OLD | NEW |
1 | 1 |
2 /* | 2 /* |
3 * Copyright 2007 The Android Open Source Project | 3 * Copyright 2007 The Android Open Source Project |
4 * | 4 * |
5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
7 */ | 7 */ |
8 | 8 |
9 | 9 |
10 #include "SkImageDecoder.h" | 10 #include "SkImageDecoder.h" |
(...skipping 339 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
350 } | 350 } |
351 } | 351 } |
352 sampleSize = recompute_sampleSize(sampleSize, cinfo); | 352 sampleSize = recompute_sampleSize(sampleSize, cinfo); |
353 | 353 |
354 // should we allow the Chooser (if present) to pick a config for us??? | 354 // should we allow the Chooser (if present) to pick a config for us??? |
355 if (!this->chooseFromOneChoice(config, cinfo.output_width, cinfo.output_heig
ht)) { | 355 if (!this->chooseFromOneChoice(config, cinfo.output_width, cinfo.output_heig
ht)) { |
356 return return_false(cinfo, *bm, "chooseFromOneChoice"); | 356 return return_false(cinfo, *bm, "chooseFromOneChoice"); |
357 } | 357 } |
358 | 358 |
359 SkScaledBitmapSampler sampler(cinfo.output_width, cinfo.output_height, sampl
eSize); | 359 SkScaledBitmapSampler sampler(cinfo.output_width, cinfo.output_height, sampl
eSize); |
360 | 360 bm->setConfig(config, sampler.scaledWidth(), sampler.scaledHeight()); |
361 bm->lockPixels(); | 361 bm->setIsOpaque(true); |
362 JSAMPLE* rowptr = (JSAMPLE*)bm->getPixels(); | 362 if (SkImageDecoder::kDecodeBounds_Mode == mode) { |
363 bm->unlockPixels(); | 363 return true; |
364 bool reuseBitmap = (rowptr != NULL); | 364 } |
365 | 365 if (!this->allocPixelRef(bm, NULL)) { |
366 if (reuseBitmap) { | 366 return return_false(cinfo, *bm, "allocPixelRef"); |
367 if (sampler.scaledWidth() != bm->width() || | |
368 sampler.scaledHeight() != bm->height()) { | |
369 // Dimensions must match | |
370 return false; | |
371 } else if (SkImageDecoder::kDecodeBounds_Mode == mode) { | |
372 return true; | |
373 } | |
374 } else { | |
375 bm->setConfig(config, sampler.scaledWidth(), sampler.scaledHeight()); | |
376 bm->setIsOpaque(true); | |
377 if (SkImageDecoder::kDecodeBounds_Mode == mode) { | |
378 return true; | |
379 } | |
380 if (!this->allocPixelRef(bm, NULL)) { | |
381 return return_false(cinfo, *bm, "allocPixelRef"); | |
382 } | |
383 } | 367 } |
384 | 368 |
385 SkAutoLockPixels alp(*bm); | 369 SkAutoLockPixels alp(*bm); |
386 | 370 |
387 #ifdef ANDROID_RGB | 371 #ifdef ANDROID_RGB |
388 /* short-circuit the SkScaledBitmapSampler when possible, as this gives | 372 /* short-circuit the SkScaledBitmapSampler when possible, as this gives |
389 a significant performance boost. | 373 a significant performance boost. |
390 */ | 374 */ |
391 if (sampleSize == 1 && | 375 if (sampleSize == 1 && |
392 ((config == SkBitmap::kARGB_8888_Config && | 376 ((config == SkBitmap::kARGB_8888_Config && |
393 cinfo.out_color_space == JCS_RGBA_8888) || | 377 cinfo.out_color_space == JCS_RGBA_8888) || |
394 (config == SkBitmap::kRGB_565_Config && | 378 (config == SkBitmap::kRGB_565_Config && |
395 cinfo.out_color_space == JCS_RGB_565))) | 379 cinfo.out_color_space == JCS_RGB_565))) |
396 { | 380 { |
397 rowptr = (JSAMPLE*)bm->getPixels(); | 381 JSAMPLE* rowptr = (JSAMPLE*)bm->getPixels(); |
398 INT32 const bpr = bm->rowBytes(); | 382 INT32 const bpr = bm->rowBytes(); |
399 | 383 |
400 while (cinfo.output_scanline < cinfo.output_height) { | 384 while (cinfo.output_scanline < cinfo.output_height) { |
401 int row_count = jpeg_read_scanlines(&cinfo, &rowptr, 1); | 385 int row_count = jpeg_read_scanlines(&cinfo, &rowptr, 1); |
402 // if row_count == 0, then we didn't get a scanline, so abort. | 386 // if row_count == 0, then we didn't get a scanline, so abort. |
403 // if we supported partial images, we might return true in this case | 387 // if we supported partial images, we might return true in this case |
404 if (0 == row_count) { | 388 if (0 == row_count) { |
405 return return_false(cinfo, *bm, "read_scanlines"); | 389 return return_false(cinfo, *bm, "read_scanlines"); |
406 } | 390 } |
407 if (this->shouldCancelDecode()) { | 391 if (this->shouldCancelDecode()) { |
408 return return_false(cinfo, *bm, "shouldCancelDecode"); | 392 return return_false(cinfo, *bm, "shouldCancelDecode"); |
409 } | 393 } |
410 rowptr += bpr; | 394 rowptr += bpr; |
411 } | 395 } |
412 if (reuseBitmap) { | |
413 bm->notifyPixelsChanged(); | |
414 } | |
415 jpeg_finish_decompress(&cinfo); | 396 jpeg_finish_decompress(&cinfo); |
416 return true; | 397 return true; |
417 } | 398 } |
418 #endif | 399 #endif |
419 | 400 |
420 // check for supported formats | 401 // check for supported formats |
421 SkScaledBitmapSampler::SrcConfig sc; | 402 SkScaledBitmapSampler::SrcConfig sc; |
422 if (JCS_CMYK == cinfo.out_color_space) { | 403 if (JCS_CMYK == cinfo.out_color_space) { |
423 // In this case we will manually convert the CMYK values to RGB | 404 // In this case we will manually convert the CMYK values to RGB |
424 sc = SkScaledBitmapSampler::kRGBX; | 405 sc = SkScaledBitmapSampler::kRGBX; |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
474 if (!skip_src_rows(&cinfo, srcRow, sampler.srcDY() - 1)) { | 455 if (!skip_src_rows(&cinfo, srcRow, sampler.srcDY() - 1)) { |
475 return return_false(cinfo, *bm, "skip rows"); | 456 return return_false(cinfo, *bm, "skip rows"); |
476 } | 457 } |
477 } | 458 } |
478 | 459 |
479 // we formally skip the rest, so we don't get a complaint from libjpeg | 460 // we formally skip the rest, so we don't get a complaint from libjpeg |
480 if (!skip_src_rows(&cinfo, srcRow, | 461 if (!skip_src_rows(&cinfo, srcRow, |
481 cinfo.output_height - cinfo.output_scanline)) { | 462 cinfo.output_height - cinfo.output_scanline)) { |
482 return return_false(cinfo, *bm, "skip rows"); | 463 return return_false(cinfo, *bm, "skip rows"); |
483 } | 464 } |
484 if (reuseBitmap) { | |
485 bm->notifyPixelsChanged(); | |
486 } | |
487 jpeg_finish_decompress(&cinfo); | 465 jpeg_finish_decompress(&cinfo); |
488 | 466 |
489 return true; | 467 return true; |
490 } | 468 } |
491 | 469 |
492 #ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK | 470 #ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK |
493 bool SkJPEGImageDecoder::onBuildTileIndex(SkStream* stream, int *width, int *hei
ght) { | 471 bool SkJPEGImageDecoder::onBuildTileIndex(SkStream* stream, int *width, int *hei
ght) { |
494 | 472 |
495 SkJPEGImageIndex* imageIndex = SkNEW_ARGS(SkJPEGImageIndex, (stream, this)); | 473 SkJPEGImageIndex* imageIndex = SkNEW_ARGS(SkJPEGImageIndex, (stream, this)); |
496 jpeg_decompress_struct* cinfo = imageIndex->cinfo(); | 474 jpeg_decompress_struct* cinfo = imageIndex->cinfo(); |
(...skipping 534 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1031 } | 1009 } |
1032 | 1010 |
1033 static SkImageEncoder* sk_libjpeg_efactory(SkImageEncoder::Type t) { | 1011 static SkImageEncoder* sk_libjpeg_efactory(SkImageEncoder::Type t) { |
1034 return (SkImageEncoder::kJPEG_Type == t) ? SkNEW(SkJPEGImageEncoder) : NULL; | 1012 return (SkImageEncoder::kJPEG_Type == t) ? SkNEW(SkJPEGImageEncoder) : NULL; |
1035 } | 1013 } |
1036 | 1014 |
1037 | 1015 |
1038 static SkTRegistry<SkImageDecoder*, SkStream*> gDReg(sk_libjpeg_dfactory); | 1016 static SkTRegistry<SkImageDecoder*, SkStream*> gDReg(sk_libjpeg_dfactory); |
1039 static SkTRegistry<SkImageDecoder::Format, SkStream*> gFormatReg(get_format_jpeg
); | 1017 static SkTRegistry<SkImageDecoder::Format, SkStream*> gFormatReg(get_format_jpeg
); |
1040 static SkTRegistry<SkImageEncoder*, SkImageEncoder::Type> gEReg(sk_libjpeg_efact
ory); | 1018 static SkTRegistry<SkImageEncoder*, SkImageEncoder::Type> gEReg(sk_libjpeg_efact
ory); |
OLD | NEW |