OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright 2006 The Android Open Source Project | 2 * Copyright 2006 The Android Open Source Project |
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 | 8 |
9 #include "SkImageDecoder.h" | 9 #include "SkImageDecoder.h" |
10 #include "SkBitmap.h" | 10 #include "SkBitmap.h" |
(...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
273 SkBitmap::Config pref, Mode mode, Format* format) { | 273 SkBitmap::Config pref, Mode mode, Format* format) { |
274 if (0 == size) { | 274 if (0 == size) { |
275 return false; | 275 return false; |
276 } | 276 } |
277 SkASSERT(buffer); | 277 SkASSERT(buffer); |
278 | 278 |
279 SkMemoryStream stream(buffer, size); | 279 SkMemoryStream stream(buffer, size); |
280 return SkImageDecoder::DecodeStream(&stream, bm, pref, mode, format); | 280 return SkImageDecoder::DecodeStream(&stream, bm, pref, mode, format); |
281 } | 281 } |
282 | 282 |
283 class TargetAllocator : public SkBitmap::Allocator { | 283 /** |
284 * Special allocator used by DecodeMemoryToTarget. Uses preallocated memory | |
285 * provided if the bm is 8888. Otherwise, uses a heap allocator. The same | |
286 * allocator will be used again for a copy to 8888, when the preallocated | |
287 * memory will be used. | |
288 */ | |
289 class TargetAllocator : public SkBitmap::HeapAllocator { | |
284 | 290 |
285 public: | 291 public: |
286 TargetAllocator(void* target) | 292 TargetAllocator(void* target) |
reed1
2013/05/20 14:03:24
For more generality (not trying to derail the CL..
| |
287 : fTarget(target) {} | 293 : fTarget(target) {} |
288 | 294 |
289 virtual bool allocPixelRef(SkBitmap* bm, SkColorTable* ct) SK_OVERRIDE { | 295 virtual bool allocPixelRef(SkBitmap* bm, SkColorTable* ct) SK_OVERRIDE { |
290 // SkColorTable is not supported by Info/Target model. | 296 // If the config is not 8888, allocate a pixelref using the heap. |
297 // fTarget will be used to store the final pixels when copied to | |
298 // 8888. | |
299 if (bm->config() != SkBitmap::kARGB_8888_Config) { | |
300 return INHERITED::allocPixelRef(bm, ct); | |
301 } | |
302 // In kARGB_8888_Config, there is no colortable. | |
291 SkASSERT(NULL == ct); | 303 SkASSERT(NULL == ct); |
292 bm->setPixels(fTarget); | 304 bm->setPixels(fTarget); |
293 return true; | 305 return true; |
294 } | 306 } |
295 | 307 |
296 private: | 308 private: |
297 void* fTarget; | 309 void* fTarget; |
310 typedef SkBitmap::HeapAllocator INHERITED; | |
298 }; | 311 }; |
299 | 312 |
313 /** | |
314 * Helper function for DecodeMemoryToTarget. DecodeMemoryToTarget wants | |
315 * 8888, so set the config to it. All parameters must not be null. | |
316 * @param decoder Decoder appropriate for this stream. | |
317 * @param stream Rewound stream to the encoded data. | |
318 * @param bitmap On success, will have its bounds set to the bounds of the | |
319 * encoded data, and its config set to 8888. | |
320 * @return True if the bounds were decoded and the bitmap is 8888 or can be | |
321 * copied to 8888. | |
322 */ | |
323 static bool decode_bounds_to_8888(SkImageDecoder* decoder, SkStream* stream, | |
324 SkBitmap* bitmap) { | |
325 SkASSERT(decoder != NULL); | |
326 SkASSERT(stream != NULL); | |
327 SkASSERT(bitmap != NULL); | |
328 | |
329 if (!decoder->decode(stream, bitmap, SkImageDecoder::kDecodeBounds_Mode)) { | |
330 return false; | |
331 } | |
332 | |
333 if (bitmap->config() == SkBitmap::kARGB_8888_Config) { | |
334 return true; | |
335 } | |
336 | |
337 if (!bitmap->canCopyTo(SkBitmap::kARGB_8888_Config)) { | |
338 return false; | |
339 } | |
340 | |
341 bitmap->setConfig(SkBitmap::kARGB_8888_Config, bitmap->width(), bitmap->heig ht()); | |
342 return true; | |
343 } | |
344 | |
345 /** | |
346 * Helper function for DecodeMemoryToTarget. Decodes the stream into bitmap, an d if | |
347 * the bitmap is not 8888, then it is copied to 8888. Either way, the end resul t has | |
348 * its pixels stored in target. All parameters must not be null. | |
349 * @param decoder Decoder appropriate for this stream. | |
350 * @param stream Rewound stream to the encoded data. | |
351 * @param bitmap On success, will contain the decoded image, with its pixels st ored | |
352 * at target. | |
353 * @param target Preallocated memory for storing pixels. | |
354 * @return bool Whether the decode (and copy, if necessary) succeeded. | |
355 */ | |
356 static bool decode_pixels_to_8888(SkImageDecoder* decoder, SkStream* stream, | |
357 SkBitmap* bitmap, void* target) { | |
358 SkASSERT(decoder != NULL); | |
359 SkASSERT(stream != NULL); | |
360 SkASSERT(bitmap != NULL); | |
361 SkASSERT(target != NULL); | |
362 | |
363 TargetAllocator allocator(target); | |
364 decoder->setAllocator(&allocator); | |
365 | |
366 bool success = decoder->decode(stream, bitmap, SkImageDecoder::kDecodePixels _Mode); | |
367 decoder->setAllocator(NULL); | |
368 | |
369 if (!success) { | |
370 return false; | |
371 } | |
372 | |
373 if (bitmap->config() == SkBitmap::kARGB_8888_Config) { | |
374 return true; | |
375 } | |
376 | |
377 SkBitmap bm8888; | |
378 if (!bitmap->copyTo(&bm8888, SkBitmap::kARGB_8888_Config, &allocator)) { | |
379 return false; | |
380 } | |
381 | |
382 bitmap->swap(bm8888); | |
383 return true; | |
384 } | |
385 | |
300 bool SkImageDecoder::DecodeMemoryToTarget(const void* buffer, size_t size, | 386 bool SkImageDecoder::DecodeMemoryToTarget(const void* buffer, size_t size, |
301 SkImage::Info* info, | 387 SkImage::Info* info, |
302 const SkBitmapFactory::Target* target) { | 388 const SkBitmapFactory::Target* target) { |
303 if (NULL == info) { | 389 if (NULL == info) { |
304 return false; | 390 return false; |
305 } | 391 } |
392 | |
306 // FIXME: Just to get this working, implement in terms of existing | 393 // FIXME: Just to get this working, implement in terms of existing |
307 // ImageDecoder calls. | 394 // ImageDecoder calls. |
308 SkBitmap bm; | 395 SkBitmap bm; |
309 SkMemoryStream stream(buffer, size); | 396 SkMemoryStream stream(buffer, size); |
310 SkAutoTDelete<SkImageDecoder> decoder(SkImageDecoder::Factory(&stream)); | 397 SkAutoTDelete<SkImageDecoder> decoder(SkImageDecoder::Factory(&stream)); |
311 if (decoder.get() != NULL && decoder->decode(&stream, &bm, kDecodeBounds_Mod e)) { | 398 if (NULL == decoder.get()) { |
312 // Now set info properly | 399 return false; |
313 if (!SkBitmapToImageInfo(bm, info)) { | 400 } |
401 | |
402 if (!decode_bounds_to_8888(decoder.get(), &stream, &bm)) { | |
403 return false; | |
404 } | |
405 | |
406 SkASSERT(bm.config() == SkBitmap::kARGB_8888_Config); | |
407 | |
408 // Now set info properly. | |
409 // Since Config is SkBitmap::kARGB_8888_Config, SkBitmapToImageInfo | |
410 // will always succeed. | |
411 SkAssertResult(SkBitmapToImageInfo(bm, info)); | |
412 | |
413 if (NULL == target) { | |
414 return true; | |
415 } | |
416 | |
417 if (target->fRowBytes != SkToU32(bm.rowBytes())) { | |
418 if (target->fRowBytes < SkImageMinRowBytes(*info)) { | |
419 SkASSERT(!"Desired row bytes is too small"); | |
314 return false; | 420 return false; |
315 } | 421 } |
422 bm.setConfig(bm.config(), bm.width(), bm.height(), target->fRowBytes); | |
423 } | |
316 | 424 |
317 // SkBitmapToImageInfo will return false if Index8 is used. kIndex8 | 425 // SkMemoryStream.rewind() will always return true. |
318 // is not supported by the Info/Target model, since kIndex8 requires | 426 SkAssertResult(stream.rewind()); |
319 // an SkColorTable, which this model does not keep track of. | 427 return decode_pixels_to_8888(decoder.get(), &stream, &bm, target->fAddr); |
320 SkASSERT(bm.config() != SkBitmap::kIndex8_Config); | |
321 | |
322 if (NULL == target) { | |
323 return true; | |
324 } | |
325 | |
326 if (target->fRowBytes != SkToU32(bm.rowBytes())) { | |
327 if (target->fRowBytes < SkImageMinRowBytes(*info)) { | |
328 SkASSERT(!"Desired row bytes is too small"); | |
329 return false; | |
330 } | |
331 bm.setConfig(bm.config(), bm.width(), bm.height(), target->fRowBytes ); | |
332 } | |
333 | |
334 TargetAllocator allocator(target->fAddr); | |
335 decoder->setAllocator(&allocator); | |
336 stream.rewind(); | |
337 bool success = decoder->decode(&stream, &bm, kDecodePixels_Mode); | |
338 // Remove the allocator, since it's on the stack. | |
339 decoder->setAllocator(NULL); | |
340 return success; | |
341 } | |
342 return false; | |
343 } | 428 } |
344 | 429 |
345 | 430 |
346 bool SkImageDecoder::DecodeStream(SkStream* stream, SkBitmap* bm, | 431 bool SkImageDecoder::DecodeStream(SkStream* stream, SkBitmap* bm, |
347 SkBitmap::Config pref, Mode mode, Format* format) { | 432 SkBitmap::Config pref, Mode mode, Format* format) { |
348 SkASSERT(stream); | 433 SkASSERT(stream); |
349 SkASSERT(bm); | 434 SkASSERT(bm); |
350 | 435 |
351 bool success = false; | 436 bool success = false; |
352 SkImageDecoder* codec = SkImageDecoder::Factory(stream); | 437 SkImageDecoder* codec = SkImageDecoder::Factory(stream); |
(...skipping 29 matching lines...) Expand all Loading... | |
382 CreateICOImageDecoder(); | 467 CreateICOImageDecoder(); |
383 CreateWBMPImageDecoder(); | 468 CreateWBMPImageDecoder(); |
384 // Only link GIF and PNG on platforms that build them. See images.gyp | 469 // Only link GIF and PNG on platforms that build them. See images.gyp |
385 #if !defined(SK_BUILD_FOR_MAC) && !defined(SK_BUILD_FOR_WIN) && !defined(SK_BUIL D_FOR_NACL) | 470 #if !defined(SK_BUILD_FOR_MAC) && !defined(SK_BUILD_FOR_WIN) && !defined(SK_BUIL D_FOR_NACL) |
386 CreateGIFImageDecoder(); | 471 CreateGIFImageDecoder(); |
387 #endif | 472 #endif |
388 #if !defined(SK_BUILD_FOR_MAC) && !defined(SK_BUILD_FOR_WIN) | 473 #if !defined(SK_BUILD_FOR_MAC) && !defined(SK_BUILD_FOR_WIN) |
389 CreatePNGImageDecoder(); | 474 CreatePNGImageDecoder(); |
390 #endif | 475 #endif |
391 } | 476 } |
OLD | NEW |