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

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

Issue 101973005: SkDecodingImageGenerator now uses SkStreamRewindable (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: rebased again Created 7 years 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 | « src/images/SkDecodingImageGenerator.cpp ('k') | src/ports/SkImageDecoder_empty.cpp » ('j') | 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 264 matching lines...) Expand 10 before | Expand all | Expand 10 after
275 SkBitmap::Config pref, Mode mode, Format* format) { 275 SkBitmap::Config pref, Mode mode, Format* format) {
276 if (0 == size) { 276 if (0 == size) {
277 return false; 277 return false;
278 } 278 }
279 SkASSERT(buffer); 279 SkASSERT(buffer);
280 280
281 SkMemoryStream stream(buffer, size); 281 SkMemoryStream stream(buffer, size);
282 return SkImageDecoder::DecodeStream(&stream, bm, pref, mode, format); 282 return SkImageDecoder::DecodeStream(&stream, bm, pref, mode, format);
283 } 283 }
284 284
285 /**
286 * Special allocator used by DecodeMemoryToTarget. Uses preallocated memory
287 * provided if the bm is 8888. Otherwise, uses a heap allocator. The same
288 * allocator will be used again for a copy to 8888, when the preallocated
289 * memory will be used.
290 */
291 class TargetAllocator : public SkBitmap::HeapAllocator {
292
293 public:
294 TargetAllocator(void* target)
295 : fTarget(target) {}
296
297 virtual bool allocPixelRef(SkBitmap* bm, SkColorTable* ct) SK_OVERRIDE {
298 // If the config is not 8888, allocate a pixelref using the heap.
299 // fTarget will be used to store the final pixels when copied to
300 // 8888.
301 if (bm->config() != SkBitmap::kARGB_8888_Config) {
302 return INHERITED::allocPixelRef(bm, ct);
303 }
304 // In kARGB_8888_Config, there is no colortable.
305 SkASSERT(NULL == ct);
306 bm->setPixels(fTarget);
307 return true;
308 }
309
310 private:
311 void* fTarget;
312 typedef SkBitmap::HeapAllocator INHERITED;
313 };
314
315 /**
316 * Helper function for DecodeMemoryToTarget. DecodeMemoryToTarget wants
317 * 8888, so set the config to it. All parameters must not be null.
318 * @param decoder Decoder appropriate for this stream.
319 * @param stream Rewound stream to the encoded data.
320 * @param bitmap On success, will have its bounds set to the bounds of the
321 * encoded data, and its config set to 8888.
322 * @return True if the bounds were decoded and the bitmap is 8888 or can be
323 * copied to 8888.
324 */
325 static bool decode_bounds_to_8888(SkImageDecoder* decoder, SkStream* stream,
326 SkBitmap* bitmap) {
327 SkASSERT(decoder != NULL);
328 SkASSERT(stream != NULL);
329 SkASSERT(bitmap != NULL);
330
331 if (!decoder->decode(stream, bitmap, SkImageDecoder::kDecodeBounds_Mode)) {
332 return false;
333 }
334
335 if (bitmap->config() == SkBitmap::kARGB_8888_Config) {
336 return true;
337 }
338
339 if (!bitmap->canCopyTo(SkBitmap::kARGB_8888_Config)) {
340 return false;
341 }
342
343 bitmap->setConfig(SkBitmap::kARGB_8888_Config, bitmap->width(), bitmap->heig ht());
344 return true;
345 }
346
347 /**
348 * Helper function for DecodeMemoryToTarget. Decodes the stream into bitmap, an d if
349 * the bitmap is not 8888, then it is copied to 8888. Either way, the end resul t has
350 * its pixels stored in target. All parameters must not be null.
351 * @param decoder Decoder appropriate for this stream.
352 * @param stream Rewound stream to the encoded data.
353 * @param bitmap On success, will contain the decoded image, with its pixels st ored
354 * at target.
355 * @param target Preallocated memory for storing pixels.
356 * @return bool Whether the decode (and copy, if necessary) succeeded.
357 */
358 static bool decode_pixels_to_8888(SkImageDecoder* decoder, SkStream* stream,
359 SkBitmap* bitmap, void* target) {
360 SkASSERT(decoder != NULL);
361 SkASSERT(stream != NULL);
362 SkASSERT(bitmap != NULL);
363 SkASSERT(target != NULL);
364
365 TargetAllocator allocator(target);
366 decoder->setAllocator(&allocator);
367
368 bool success = decoder->decode(stream, bitmap, SkImageDecoder::kDecodePixels _Mode);
369 decoder->setAllocator(NULL);
370
371 if (!success) {
372 return false;
373 }
374
375 if (bitmap->config() == SkBitmap::kARGB_8888_Config) {
376 return true;
377 }
378
379 SkBitmap bm8888;
380 if (!bitmap->copyTo(&bm8888, SkBitmap::kARGB_8888_Config, &allocator)) {
381 return false;
382 }
383
384 bitmap->swap(bm8888);
385 return true;
386 }
387
388 bool SkImageDecoder::DecodeMemoryToTarget(const void* buffer, size_t size,
389 SkImageInfo* info,
390 const SkImageDecoder::Target* target) {
391 // FIXME: Just to get this working, implement in terms of existing
392 // ImageDecoder calls.
393 SkBitmap bm;
394 SkMemoryStream stream(buffer, size);
395 SkAutoTDelete<SkImageDecoder> decoder(SkImageDecoder::Factory(&stream));
396 if (NULL == decoder.get()) {
397 return false;
398 }
399
400 if (!decode_bounds_to_8888(decoder.get(), &stream, &bm)) {
401 return false;
402 }
403
404 SkASSERT(bm.config() == SkBitmap::kARGB_8888_Config);
405
406 // Now set info properly.
407 // Since Config is SkBitmap::kARGB_8888_Config, SkBitmapToImageInfo
408 // will always succeed.
409 if (info) {
410 SkAssertResult(SkBitmapToImageInfo(bm, info));
411 }
412
413 if (NULL == target) {
414 return true;
415 }
416
417 if (target->fRowBytes != SkToU32(bm.rowBytes())) {
418 size_t minRB = SkBitmap::ComputeRowBytes(bm.config(), bm.width());
419 if (target->fRowBytes < minRB) {
420 SkDEBUGFAIL("Desired row bytes is too small");
421 return false;
422 }
423 bm.setConfig(bm.config(), bm.width(), bm.height(), target->fRowBytes);
424 }
425
426 // SkMemoryStream.rewind() will always return true.
427 SkAssertResult(stream.rewind());
428 return decode_pixels_to_8888(decoder.get(), &stream, &bm, target->fAddr);
429 }
430
431
432 bool SkImageDecoder::DecodeStream(SkStreamRewindable* stream, SkBitmap* bm, 285 bool SkImageDecoder::DecodeStream(SkStreamRewindable* stream, SkBitmap* bm,
433 SkBitmap::Config pref, Mode mode, 286 SkBitmap::Config pref, Mode mode,
434 Format* format) { 287 Format* format) {
435 SkASSERT(stream); 288 SkASSERT(stream);
436 SkASSERT(bm); 289 SkASSERT(bm);
437 290
438 bool success = false; 291 bool success = false;
439 SkImageDecoder* codec = SkImageDecoder::Factory(stream); 292 SkImageDecoder* codec = SkImageDecoder::Factory(stream);
440 293
441 if (NULL != codec) { 294 if (NULL != codec) {
442 success = codec->decode(stream, bm, pref, mode); 295 success = codec->decode(stream, bm, pref, mode);
443 if (success && format) { 296 if (success && format) {
444 *format = codec->getFormat(); 297 *format = codec->getFormat();
445 if (kUnknown_Format == *format) { 298 if (kUnknown_Format == *format) {
446 if (stream->rewind()) { 299 if (stream->rewind()) {
447 *format = GetStreamFormat(stream); 300 *format = GetStreamFormat(stream);
448 } 301 }
449 } 302 }
450 } 303 }
451 delete codec; 304 delete codec;
452 } 305 }
453 return success; 306 return success;
454 } 307 }
OLDNEW
« no previous file with comments | « src/images/SkDecodingImageGenerator.cpp ('k') | src/ports/SkImageDecoder_empty.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698