OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2014 Google Inc. | 2 * Copyright 2014 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "SkImageGenerator.h" | 8 #include "SkImageGenerator.h" |
9 #include "SkNextID.h" | 9 #include "SkNextID.h" |
10 | 10 |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
121 bool SkImageGenerator::onGetPixels(const SkImageInfo& info, void* dst, size_t rb
, | 121 bool SkImageGenerator::onGetPixels(const SkImageInfo& info, void* dst, size_t rb
, |
122 SkPMColor* colors, int* colorCount) { | 122 SkPMColor* colors, int* colorCount) { |
123 return false; | 123 return false; |
124 } | 124 } |
125 | 125 |
126 ////////////////////////////////////////////////////////////////////////////////
/////////////////// | 126 ////////////////////////////////////////////////////////////////////////////////
/////////////////// |
127 | 127 |
128 #include "SkBitmap.h" | 128 #include "SkBitmap.h" |
129 #include "SkColorTable.h" | 129 #include "SkColorTable.h" |
130 | 130 |
131 static void release_malloc_proc(void* pixels, void* ctx) { | 131 static bool reset_and_return_false(SkBitmap* bitmap) { |
132 sk_free(pixels); | 132 bitmap->reset(); |
| 133 return false; |
133 } | 134 } |
134 | 135 |
135 bool SkImageGenerator::tryGenerateBitmap(SkBitmap* bitmap, const SkImageInfo* in
foPtr) { | 136 bool SkImageGenerator::tryGenerateBitmap(SkBitmap* bitmap, const SkImageInfo* in
foPtr, |
136 const SkImageInfo info = infoPtr ? *infoPtr : this->getInfo(); | 137 SkBitmap::Allocator* allocator) { |
137 const size_t rowBytes = info.minRowBytes(); | 138 SkImageInfo info = infoPtr ? *infoPtr : this->getInfo(); |
138 const size_t pixelSize = info.getSafeSize(rowBytes); | 139 if (0 == info.getSafeSize(info.minRowBytes())) { |
139 if (0 == pixelSize) { | |
140 return false; | 140 return false; |
141 } | 141 } |
| 142 if (!bitmap->setInfo(info)) { |
| 143 return reset_and_return_false(bitmap); |
| 144 } |
142 | 145 |
143 SkAutoFree pixelStorage(sk_malloc_flags(pixelSize, 0)); | 146 SkPMColor ctStorage[256]; |
144 void* pixels = pixelStorage.get(); | 147 memset(ctStorage, 0xFF, sizeof(ctStorage)); // init with opaque-white for th
e moment |
145 if (!pixels) { | 148 SkAutoTUnref<SkColorTable> ctable(new SkColorTable(ctStorage, 256)); |
146 return false; | 149 if (!bitmap->tryAllocPixels(allocator, ctable)) { |
| 150 // SkResourceCache's custom allcator can'thandle ctables, so it may fail
on |
| 151 // kIndex_8_SkColorTable. |
| 152 // skbug.com/4355 |
| 153 #if 1 |
| 154 // ignroe the allocator, and see if we can succeed without it |
| 155 if (!bitmap->tryAllocPixels(nullptr, ctable)) { |
| 156 return reset_and_return_false(bitmap); |
| 157 } |
| 158 #else |
| 159 // this is the up-scale technique, not fully debugged, but we keep it he
re at the moment |
| 160 // to remind ourselves that this might be better than ignoring the alloc
ator. |
| 161 |
| 162 info = SkImageInfo::MakeN32(info.width(), info.height(), info.alphaType(
)); |
| 163 if (!bitmap->setInfo(info)) { |
| 164 return reset_and_return_false(bitmap); |
| 165 } |
| 166 // we pass nullptr for the ctable arg, since we are now explicitly N32 |
| 167 if (!bitmap->tryAllocPixels(allocator, nullptr)) { |
| 168 return reset_and_return_false(bitmap); |
| 169 } |
| 170 #endif |
147 } | 171 } |
148 | 172 |
149 SkPMColor ctStorage[256]; | 173 bitmap->lockPixels(); |
| 174 if (!bitmap->getPixels()) { |
| 175 return reset_and_return_false(bitmap); |
| 176 } |
| 177 |
150 int ctCount = 0; | 178 int ctCount = 0; |
151 | 179 if (!this->getPixels(bitmap->info(), bitmap->getPixels(), bitmap->rowBytes()
, |
152 if (!this->getPixels(info, pixels, rowBytes, ctStorage, &ctCount)) { | 180 ctStorage, &ctCount)) { |
153 return false; | 181 return reset_and_return_false(bitmap); |
154 } | 182 } |
155 | 183 |
156 SkAutoTUnref<SkColorTable> ctable; | |
157 if (ctCount > 0) { | 184 if (ctCount > 0) { |
158 SkASSERT(kIndex_8_SkColorType == info.colorType()); | 185 SkASSERT(kIndex_8_SkColorType == bitmap->colorType()); |
159 ctable.reset(new SkColorTable(ctStorage, ctCount)); | 186 // we and bitmap should be owners |
| 187 SkASSERT(!ctable->unique()); |
| 188 |
| 189 // Now we need to overwrite the ctable we built earlier, with the correc
t colors. |
| 190 // This does mean that we may have made the table too big, but that cann
ot be avoided |
| 191 // until we can change SkImageGenerator's API to return us the ctable *b
efore* we have to |
| 192 // allocate space for all the pixels. |
| 193 ctable->dangerous_overwriteColors(ctStorage, ctCount); |
160 } else { | 194 } else { |
161 SkASSERT(kIndex_8_SkColorType != info.colorType()); | 195 SkASSERT(kIndex_8_SkColorType != bitmap->colorType()); |
| 196 // we should be the only owner |
| 197 SkASSERT(ctable->unique()); |
162 } | 198 } |
163 | 199 return true; |
164 return bitmap->installPixels(info, pixelStorage.detach(), rowBytes, ctable, | |
165 release_malloc_proc, nullptr); | |
166 } | 200 } |
167 | 201 |
168 #include "SkGraphics.h" | 202 #include "SkGraphics.h" |
169 | 203 |
170 static SkGraphics::ImageGeneratorFromEncodedFactory gFactory; | 204 static SkGraphics::ImageGeneratorFromEncodedFactory gFactory; |
171 | 205 |
172 SkGraphics::ImageGeneratorFromEncodedFactory | 206 SkGraphics::ImageGeneratorFromEncodedFactory |
173 SkGraphics::SetImageGeneratorFromEncodedFactory(ImageGeneratorFromEncodedFactory
factory) | 207 SkGraphics::SetImageGeneratorFromEncodedFactory(ImageGeneratorFromEncodedFactory
factory) |
174 { | 208 { |
175 ImageGeneratorFromEncodedFactory prev = gFactory; | 209 ImageGeneratorFromEncodedFactory prev = gFactory; |
176 gFactory = factory; | 210 gFactory = factory; |
177 return prev; | 211 return prev; |
178 } | 212 } |
179 | 213 |
180 SkImageGenerator* SkImageGenerator::NewFromEncoded(SkData* data) { | 214 SkImageGenerator* SkImageGenerator::NewFromEncoded(SkData* data) { |
181 if (nullptr == data) { | 215 if (nullptr == data) { |
182 return nullptr; | 216 return nullptr; |
183 } | 217 } |
184 if (gFactory) { | 218 if (gFactory) { |
185 if (SkImageGenerator* generator = gFactory(data)) { | 219 if (SkImageGenerator* generator = gFactory(data)) { |
186 return generator; | 220 return generator; |
187 } | 221 } |
188 } | 222 } |
189 return SkImageGenerator::NewFromEncodedImpl(data); | 223 return SkImageGenerator::NewFromEncodedImpl(data); |
190 } | 224 } |
OLD | NEW |