Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Side by Side Diff: src/images/SkImageDecoder.cpp

Issue 14772035: Make DecodeMemoryToTarget handle more configs. (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: rebase Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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)
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
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 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698