| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2007 The Android Open Source Project | 2 * Copyright 2007 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 "SkImageEncoder.h" | 10 #include "SkImageEncoder.h" |
| (...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 231 | 231 |
| 232 virtual Format getFormat() const { | 232 virtual Format getFormat() const { |
| 233 return kJPEG_Format; | 233 return kJPEG_Format; |
| 234 } | 234 } |
| 235 | 235 |
| 236 protected: | 236 protected: |
| 237 #ifdef SK_BUILD_FOR_ANDROID | 237 #ifdef SK_BUILD_FOR_ANDROID |
| 238 virtual bool onBuildTileIndex(SkStreamRewindable *stream, int *width, int *h
eight) SK_OVERRIDE; | 238 virtual bool onBuildTileIndex(SkStreamRewindable *stream, int *width, int *h
eight) SK_OVERRIDE; |
| 239 virtual bool onDecodeSubset(SkBitmap* bitmap, const SkIRect& rect) SK_OVERRI
DE; | 239 virtual bool onDecodeSubset(SkBitmap* bitmap, const SkIRect& rect) SK_OVERRI
DE; |
| 240 #endif | 240 #endif |
| 241 virtual bool onDecode(SkStream* stream, SkBitmap* bm, Mode) SK_OVERRIDE; | 241 virtual Result onDecode(SkStream* stream, SkBitmap* bm, Mode) SK_OVERRIDE; |
| 242 virtual bool onDecodeYUV8Planes(SkStream* stream, SkISize componentSizes[3], | 242 virtual bool onDecodeYUV8Planes(SkStream* stream, SkISize componentSizes[3], |
| 243 void* planes[3], size_t rowBytes[3], | 243 void* planes[3], size_t rowBytes[3], |
| 244 SkYUVColorSpace* colorSpace) SK_OVERRIDE; | 244 SkYUVColorSpace* colorSpace) SK_OVERRIDE; |
| 245 | 245 |
| 246 private: | 246 private: |
| 247 #ifdef SK_BUILD_FOR_ANDROID | 247 #ifdef SK_BUILD_FOR_ANDROID |
| 248 SkJPEGImageIndex* fImageIndex; | 248 SkJPEGImageIndex* fImageIndex; |
| 249 int fImageWidth; | 249 int fImageWidth; |
| 250 int fImageHeight; | 250 int fImageHeight; |
| 251 #endif | 251 #endif |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 318 JSAMPLE* rowptr = (JSAMPLE*)buffer; | 318 JSAMPLE* rowptr = (JSAMPLE*)buffer; |
| 319 int row_count = jpeg_read_tile_scanline(cinfo, index, &rowptr); | 319 int row_count = jpeg_read_tile_scanline(cinfo, index, &rowptr); |
| 320 if (1 != row_count) { | 320 if (1 != row_count) { |
| 321 return false; | 321 return false; |
| 322 } | 322 } |
| 323 } | 323 } |
| 324 return true; | 324 return true; |
| 325 } | 325 } |
| 326 #endif | 326 #endif |
| 327 | 327 |
| 328 /////////////////////////////////////////////////////////////////////////////// |
| 329 |
| 328 // This guy exists just to aid in debugging, as it allows debuggers to just | 330 // This guy exists just to aid in debugging, as it allows debuggers to just |
| 329 // set a break-point in one place to see all error exists. | 331 // set a break-point in one place to see all error exists. |
| 330 static bool return_false(const jpeg_decompress_struct& cinfo, | 332 static void print_jpeg_decoder_errors(const jpeg_decompress_struct& cinfo, |
| 331 int width, int height, const char caller[]) { | 333 int width, int height, const char caller[]) { |
| 332 if (!(c_suppressJPEGImageDecoderErrors)) { | 334 if (!(c_suppressJPEGImageDecoderErrors)) { |
| 333 char buffer[JMSG_LENGTH_MAX]; | 335 char buffer[JMSG_LENGTH_MAX]; |
| 334 cinfo.err->format_message((const j_common_ptr)&cinfo, buffer); | 336 cinfo.err->format_message((const j_common_ptr)&cinfo, buffer); |
| 335 SkDebugf("libjpeg error %d <%s> from %s [%d %d]\n", | 337 SkDebugf("libjpeg error %d <%s> from %s [%d %d]\n", |
| 336 cinfo.err->msg_code, buffer, caller, width, height); | 338 cinfo.err->msg_code, buffer, caller, width, height); |
| 337 } | 339 } |
| 338 return false; // must always return false | 340 } |
| 341 |
| 342 static bool return_false(const jpeg_decompress_struct& cinfo, |
| 343 const char caller[]) { |
| 344 print_jpeg_decoder_errors(cinfo, 0, 0, caller); |
| 345 return false; |
| 339 } | 346 } |
| 340 | 347 |
| 341 static bool return_false(const jpeg_decompress_struct& cinfo, | 348 static bool return_false(const jpeg_decompress_struct& cinfo, |
| 342 const SkBitmap& bm, const char caller[]) { | 349 const SkBitmap& bm, const char caller[]) { |
| 343 return return_false(cinfo, bm.width(), bm.height(), caller); | 350 print_jpeg_decoder_errors(cinfo, bm.width(), bm.height(), caller); |
| 351 return false; |
| 344 } | 352 } |
| 345 | 353 |
| 354 static SkImageDecoder::Result return_failure(const jpeg_decompress_struct& cinfo
, |
| 355 const SkBitmap& bm, const char call
er[]) { |
| 356 print_jpeg_decoder_errors(cinfo, bm.width(), bm.height(), caller); |
| 357 return SkImageDecoder::kFailure; |
| 358 } |
| 359 |
| 360 /////////////////////////////////////////////////////////////////////////////// |
| 361 |
| 346 // Convert a scanline of CMYK samples to RGBX in place. Note that this | 362 // Convert a scanline of CMYK samples to RGBX in place. Note that this |
| 347 // method moves the "scanline" pointer in its processing | 363 // method moves the "scanline" pointer in its processing |
| 348 static void convert_CMYK_to_RGB(uint8_t* scanline, unsigned int width) { | 364 static void convert_CMYK_to_RGB(uint8_t* scanline, unsigned int width) { |
| 349 // At this point we've received CMYK pixels from libjpeg. We | 365 // At this point we've received CMYK pixels from libjpeg. We |
| 350 // perform a crude conversion to RGB (based on the formulae | 366 // perform a crude conversion to RGB (based on the formulae |
| 351 // from easyrgb.com): | 367 // from easyrgb.com): |
| 352 // CMYK -> CMY | 368 // CMYK -> CMY |
| 353 // C = ( C * (1 - K) + K ) // for each CMY component | 369 // C = ( C * (1 - K) + K ) // for each CMY component |
| 354 // CMY -> RGB | 370 // CMY -> RGB |
| 355 // R = ( 1 - C ) * 255 // for each RGB component | 371 // R = ( 1 - C ) * 255 // for each RGB component |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 484 if (decoder.getDitherImage()) { | 500 if (decoder.getDitherImage()) { |
| 485 cinfo->dither_mode = JDITHER_ORDERED; | 501 cinfo->dither_mode = JDITHER_ORDERED; |
| 486 } | 502 } |
| 487 break; | 503 break; |
| 488 default: | 504 default: |
| 489 break; | 505 break; |
| 490 } | 506 } |
| 491 #endif | 507 #endif |
| 492 } | 508 } |
| 493 | 509 |
| 494 | |
| 495 /** | 510 /** |
| 496 Sets all pixels in given bitmap to SK_ColorWHITE for all rows >= y. | 511 Sets all pixels in given bitmap to SK_ColorWHITE for all rows >= y. |
| 497 Used when decoding fails partway through reading scanlines to fill | 512 Used when decoding fails partway through reading scanlines to fill |
| 498 remaining lines. */ | 513 remaining lines. */ |
| 499 static void fill_below_level(int y, SkBitmap* bitmap) { | 514 static void fill_below_level(int y, SkBitmap* bitmap) { |
| 500 SkIRect rect = SkIRect::MakeLTRB(0, y, bitmap->width(), bitmap->height()); | 515 SkIRect rect = SkIRect::MakeLTRB(0, y, bitmap->width(), bitmap->height()); |
| 501 SkCanvas canvas(*bitmap); | 516 SkCanvas canvas(*bitmap); |
| 502 canvas.clipRect(SkRect::Make(rect)); | 517 canvas.clipRect(SkRect::Make(rect)); |
| 503 canvas.drawColor(SK_ColorWHITE); | 518 canvas.drawColor(SK_ColorWHITE); |
| 504 } | 519 } |
| (...skipping 25 matching lines...) Expand all Loading... |
| 530 } else if (1 == cinfo.out_color_components && | 545 } else if (1 == cinfo.out_color_components && |
| 531 JCS_GRAYSCALE == cinfo.out_color_space) { | 546 JCS_GRAYSCALE == cinfo.out_color_space) { |
| 532 *sc = SkScaledBitmapSampler::kGray; | 547 *sc = SkScaledBitmapSampler::kGray; |
| 533 *srcBytesPerPixel = 1; | 548 *srcBytesPerPixel = 1; |
| 534 } else { | 549 } else { |
| 535 return false; | 550 return false; |
| 536 } | 551 } |
| 537 return true; | 552 return true; |
| 538 } | 553 } |
| 539 | 554 |
| 540 bool SkJPEGImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) { | 555 SkImageDecoder::Result SkJPEGImageDecoder::onDecode(SkStream* stream, SkBitmap*
bm, Mode mode) { |
| 541 #ifdef TIME_DECODE | 556 #ifdef TIME_DECODE |
| 542 SkAutoTime atm("JPEG Decode"); | 557 SkAutoTime atm("JPEG Decode"); |
| 543 #endif | 558 #endif |
| 544 | 559 |
| 545 JPEGAutoClean autoClean; | 560 JPEGAutoClean autoClean; |
| 546 | 561 |
| 547 jpeg_decompress_struct cinfo; | 562 jpeg_decompress_struct cinfo; |
| 548 skjpeg_source_mgr srcManager(stream, this); | 563 skjpeg_source_mgr srcManager(stream, this); |
| 549 | 564 |
| 550 skjpeg_error_mgr errorManager; | 565 skjpeg_error_mgr errorManager; |
| 551 set_error_mgr(&cinfo, &errorManager); | 566 set_error_mgr(&cinfo, &errorManager); |
| 552 | 567 |
| 553 // All objects need to be instantiated before this setjmp call so that | 568 // All objects need to be instantiated before this setjmp call so that |
| 554 // they will be cleaned up properly if an error occurs. | 569 // they will be cleaned up properly if an error occurs. |
| 555 if (setjmp(errorManager.fJmpBuf)) { | 570 if (setjmp(errorManager.fJmpBuf)) { |
| 556 return return_false(cinfo, *bm, "setjmp"); | 571 return return_failure(cinfo, *bm, "setjmp"); |
| 557 } | 572 } |
| 558 | 573 |
| 559 initialize_info(&cinfo, &srcManager); | 574 initialize_info(&cinfo, &srcManager); |
| 560 autoClean.set(&cinfo); | 575 autoClean.set(&cinfo); |
| 561 | 576 |
| 562 int status = jpeg_read_header(&cinfo, true); | 577 int status = jpeg_read_header(&cinfo, true); |
| 563 if (status != JPEG_HEADER_OK) { | 578 if (status != JPEG_HEADER_OK) { |
| 564 return return_false(cinfo, *bm, "read_header"); | 579 return return_failure(cinfo, *bm, "read_header"); |
| 565 } | 580 } |
| 566 | 581 |
| 567 /* Try to fulfill the requested sampleSize. Since jpeg can do it (when it | 582 /* Try to fulfill the requested sampleSize. Since jpeg can do it (when it |
| 568 can) much faster that we, just use their num/denom api to approximate | 583 can) much faster that we, just use their num/denom api to approximate |
| 569 the size. | 584 the size. |
| 570 */ | 585 */ |
| 571 int sampleSize = this->getSampleSize(); | 586 int sampleSize = this->getSampleSize(); |
| 572 | 587 |
| 573 set_dct_method(*this, &cinfo); | 588 set_dct_method(*this, &cinfo); |
| 574 | 589 |
| 575 SkASSERT(1 == cinfo.scale_num); | 590 SkASSERT(1 == cinfo.scale_num); |
| 576 cinfo.scale_denom = sampleSize; | 591 cinfo.scale_denom = sampleSize; |
| 577 | 592 |
| 578 turn_off_visual_optimizations(&cinfo); | 593 turn_off_visual_optimizations(&cinfo); |
| 579 | 594 |
| 580 const SkColorType colorType = this->getBitmapColorType(&cinfo); | 595 const SkColorType colorType = this->getBitmapColorType(&cinfo); |
| 581 const SkAlphaType alphaType = kAlpha_8_SkColorType == colorType ? | 596 const SkAlphaType alphaType = kAlpha_8_SkColorType == colorType ? |
| 582 kPremul_SkAlphaType : kOpaque_SkAlphaType; | 597 kPremul_SkAlphaType : kOpaque_SkAlphaType; |
| 583 | 598 |
| 584 adjust_out_color_space_and_dither(&cinfo, colorType, *this); | 599 adjust_out_color_space_and_dither(&cinfo, colorType, *this); |
| 585 | 600 |
| 586 if (1 == sampleSize && SkImageDecoder::kDecodeBounds_Mode == mode) { | 601 if (1 == sampleSize && SkImageDecoder::kDecodeBounds_Mode == mode) { |
| 587 // Assume an A8 bitmap is not opaque to avoid the check of each | 602 // Assume an A8 bitmap is not opaque to avoid the check of each |
| 588 // individual pixel. It is very unlikely to be opaque, since | 603 // individual pixel. It is very unlikely to be opaque, since |
| 589 // an opaque A8 bitmap would not be very interesting. | 604 // an opaque A8 bitmap would not be very interesting. |
| 590 // Otherwise, a jpeg image is opaque. | 605 // Otherwise, a jpeg image is opaque. |
| 591 return bm->setInfo(SkImageInfo::Make(cinfo.image_width, cinfo.image_heig
ht, | 606 bool success = bm->setInfo(SkImageInfo::Make(cinfo.image_width, cinfo.im
age_height, |
| 592 colorType, alphaType)); | 607 colorType, alphaType)); |
| 608 return success ? kSuccess : kFailure; |
| 593 } | 609 } |
| 594 | 610 |
| 595 /* image_width and image_height are the original dimensions, available | 611 /* image_width and image_height are the original dimensions, available |
| 596 after jpeg_read_header(). To see the scaled dimensions, we have to call | 612 after jpeg_read_header(). To see the scaled dimensions, we have to call |
| 597 jpeg_start_decompress(), and then read output_width and output_height. | 613 jpeg_start_decompress(), and then read output_width and output_height. |
| 598 */ | 614 */ |
| 599 if (!jpeg_start_decompress(&cinfo)) { | 615 if (!jpeg_start_decompress(&cinfo)) { |
| 600 /* If we failed here, we may still have enough information to return | 616 /* If we failed here, we may still have enough information to return |
| 601 to the caller if they just wanted (subsampled bounds). If sampleSize | 617 to the caller if they just wanted (subsampled bounds). If sampleSize |
| 602 was 1, then we would have already returned. Thus we just check if | 618 was 1, then we would have already returned. Thus we just check if |
| 603 we're in kDecodeBounds_Mode, and that we have valid output sizes. | 619 we're in kDecodeBounds_Mode, and that we have valid output sizes. |
| 604 | 620 |
| 605 One reason to fail here is that we have insufficient stream data | 621 One reason to fail here is that we have insufficient stream data |
| 606 to complete the setup. However, output dimensions seem to get | 622 to complete the setup. However, output dimensions seem to get |
| 607 computed very early, which is why this special check can pay off. | 623 computed very early, which is why this special check can pay off. |
| 608 */ | 624 */ |
| 609 if (SkImageDecoder::kDecodeBounds_Mode == mode && valid_output_dimension
s(cinfo)) { | 625 if (SkImageDecoder::kDecodeBounds_Mode == mode && valid_output_dimension
s(cinfo)) { |
| 610 SkScaledBitmapSampler smpl(cinfo.output_width, cinfo.output_height, | 626 SkScaledBitmapSampler smpl(cinfo.output_width, cinfo.output_height, |
| 611 recompute_sampleSize(sampleSize, cinfo)); | 627 recompute_sampleSize(sampleSize, cinfo)); |
| 612 // Assume an A8 bitmap is not opaque to avoid the check of each | 628 // Assume an A8 bitmap is not opaque to avoid the check of each |
| 613 // individual pixel. It is very unlikely to be opaque, since | 629 // individual pixel. It is very unlikely to be opaque, since |
| 614 // an opaque A8 bitmap would not be very interesting. | 630 // an opaque A8 bitmap would not be very interesting. |
| 615 // Otherwise, a jpeg image is opaque. | 631 // Otherwise, a jpeg image is opaque. |
| 616 return bm->setInfo(SkImageInfo::Make(smpl.scaledWidth(), smpl.scaled
Height(), | 632 bool success = bm->setInfo(SkImageInfo::Make(smpl.scaledWidth(), smp
l.scaledHeight(), |
| 617 colorType, alphaType)); | 633 colorType, alphaType)); |
| 634 return success ? kSuccess : kFailure; |
| 618 } else { | 635 } else { |
| 619 return return_false(cinfo, *bm, "start_decompress"); | 636 return return_failure(cinfo, *bm, "start_decompress"); |
| 620 } | 637 } |
| 621 } | 638 } |
| 622 sampleSize = recompute_sampleSize(sampleSize, cinfo); | 639 sampleSize = recompute_sampleSize(sampleSize, cinfo); |
| 623 | 640 |
| 624 #ifdef SK_SUPPORT_LEGACY_IMAGEDECODER_CHOOSER | 641 #ifdef SK_SUPPORT_LEGACY_IMAGEDECODER_CHOOSER |
| 625 // should we allow the Chooser (if present) to pick a colortype for us??? | 642 // should we allow the Chooser (if present) to pick a colortype for us??? |
| 626 if (!this->chooseFromOneChoice(colorType, cinfo.output_width, cinfo.output_h
eight)) { | 643 if (!this->chooseFromOneChoice(colorType, cinfo.output_width, cinfo.output_h
eight)) { |
| 627 return return_false(cinfo, *bm, "chooseFromOneChoice"); | 644 return return_failure(cinfo, *bm, "chooseFromOneChoice"); |
| 628 } | 645 } |
| 629 #endif | 646 #endif |
| 630 | 647 |
| 631 SkScaledBitmapSampler sampler(cinfo.output_width, cinfo.output_height, sampl
eSize); | 648 SkScaledBitmapSampler sampler(cinfo.output_width, cinfo.output_height, sampl
eSize); |
| 632 // Assume an A8 bitmap is not opaque to avoid the check of each | 649 // Assume an A8 bitmap is not opaque to avoid the check of each |
| 633 // individual pixel. It is very unlikely to be opaque, since | 650 // individual pixel. It is very unlikely to be opaque, since |
| 634 // an opaque A8 bitmap would not be very interesting. | 651 // an opaque A8 bitmap would not be very interesting. |
| 635 // Otherwise, a jpeg image is opaque. | 652 // Otherwise, a jpeg image is opaque. |
| 636 bm->setInfo(SkImageInfo::Make(sampler.scaledWidth(), sampler.scaledHeight(), | 653 bm->setInfo(SkImageInfo::Make(sampler.scaledWidth(), sampler.scaledHeight(), |
| 637 colorType, alphaType)); | 654 colorType, alphaType)); |
| 638 if (SkImageDecoder::kDecodeBounds_Mode == mode) { | 655 if (SkImageDecoder::kDecodeBounds_Mode == mode) { |
| 639 return true; | 656 return kSuccess; |
| 640 } | 657 } |
| 641 if (!this->allocPixelRef(bm, NULL)) { | 658 if (!this->allocPixelRef(bm, NULL)) { |
| 642 return return_false(cinfo, *bm, "allocPixelRef"); | 659 return return_failure(cinfo, *bm, "allocPixelRef"); |
| 643 } | 660 } |
| 644 | 661 |
| 645 SkAutoLockPixels alp(*bm); | 662 SkAutoLockPixels alp(*bm); |
| 646 | 663 |
| 647 #ifdef ANDROID_RGB | 664 #ifdef ANDROID_RGB |
| 648 /* short-circuit the SkScaledBitmapSampler when possible, as this gives | 665 /* short-circuit the SkScaledBitmapSampler when possible, as this gives |
| 649 a significant performance boost. | 666 a significant performance boost. |
| 650 */ | 667 */ |
| 651 if (sampleSize == 1 && | 668 if (sampleSize == 1 && |
| 652 ((kN32_SkColorType == colorType && cinfo.out_color_space == JCS_RGBA_888
8) || | 669 ((kN32_SkColorType == colorType && cinfo.out_color_space == JCS_RGBA_888
8) || |
| 653 (kRGB_565_SkColorType == colorType && cinfo.out_color_space == JCS_RGB_
565))) | 670 (kRGB_565_SkColorType == colorType && cinfo.out_color_space == JCS_RGB_
565))) |
| 654 { | 671 { |
| 655 JSAMPLE* rowptr = (JSAMPLE*)bm->getPixels(); | 672 JSAMPLE* rowptr = (JSAMPLE*)bm->getPixels(); |
| 656 INT32 const bpr = bm->rowBytes(); | 673 INT32 const bpr = bm->rowBytes(); |
| 657 | 674 |
| 658 while (cinfo.output_scanline < cinfo.output_height) { | 675 while (cinfo.output_scanline < cinfo.output_height) { |
| 659 int row_count = jpeg_read_scanlines(&cinfo, &rowptr, 1); | 676 int row_count = jpeg_read_scanlines(&cinfo, &rowptr, 1); |
| 660 if (0 == row_count) { | 677 if (0 == row_count) { |
| 661 // if row_count == 0, then we didn't get a scanline, | 678 // if row_count == 0, then we didn't get a scanline, |
| 662 // so return early. We will return a partial image. | 679 // so return early. We will return a partial image. |
| 663 fill_below_level(cinfo.output_scanline, bm); | 680 fill_below_level(cinfo.output_scanline, bm); |
| 664 cinfo.output_scanline = cinfo.output_height; | 681 cinfo.output_scanline = cinfo.output_height; |
| 665 break; // Skip to jpeg_finish_decompress() | 682 jpeg_finish_decompress(&cinfo); |
| 683 return kPartialSuccess; |
| 666 } | 684 } |
| 667 if (this->shouldCancelDecode()) { | 685 if (this->shouldCancelDecode()) { |
| 668 return return_false(cinfo, *bm, "shouldCancelDecode"); | 686 return return_failure(cinfo, *bm, "shouldCancelDecode"); |
| 669 } | 687 } |
| 670 rowptr += bpr; | 688 rowptr += bpr; |
| 671 } | 689 } |
| 672 jpeg_finish_decompress(&cinfo); | 690 jpeg_finish_decompress(&cinfo); |
| 673 return true; | 691 return kSuccess; |
| 674 } | 692 } |
| 675 #endif | 693 #endif |
| 676 | 694 |
| 677 // check for supported formats | 695 // check for supported formats |
| 678 SkScaledBitmapSampler::SrcConfig sc; | 696 SkScaledBitmapSampler::SrcConfig sc; |
| 679 int srcBytesPerPixel; | 697 int srcBytesPerPixel; |
| 680 | 698 |
| 681 if (!get_src_config(cinfo, &sc, &srcBytesPerPixel)) { | 699 if (!get_src_config(cinfo, &sc, &srcBytesPerPixel)) { |
| 682 return return_false(cinfo, *bm, "jpeg colorspace"); | 700 return return_failure(cinfo, *bm, "jpeg colorspace"); |
| 683 } | 701 } |
| 684 | 702 |
| 685 if (!sampler.begin(bm, sc, *this)) { | 703 if (!sampler.begin(bm, sc, *this)) { |
| 686 return return_false(cinfo, *bm, "sampler.begin"); | 704 return return_failure(cinfo, *bm, "sampler.begin"); |
| 687 } | 705 } |
| 688 | 706 |
| 689 SkAutoMalloc srcStorage(cinfo.output_width * srcBytesPerPixel); | 707 SkAutoMalloc srcStorage(cinfo.output_width * srcBytesPerPixel); |
| 690 uint8_t* srcRow = (uint8_t*)srcStorage.get(); | 708 uint8_t* srcRow = (uint8_t*)srcStorage.get(); |
| 691 | 709 |
| 692 // Possibly skip initial rows [sampler.srcY0] | 710 // Possibly skip initial rows [sampler.srcY0] |
| 693 if (!skip_src_rows(&cinfo, srcRow, sampler.srcY0())) { | 711 if (!skip_src_rows(&cinfo, srcRow, sampler.srcY0())) { |
| 694 return return_false(cinfo, *bm, "skip rows"); | 712 return return_failure(cinfo, *bm, "skip rows"); |
| 695 } | 713 } |
| 696 | 714 |
| 697 // now loop through scanlines until y == bm->height() - 1 | 715 // now loop through scanlines until y == bm->height() - 1 |
| 698 for (int y = 0;; y++) { | 716 for (int y = 0;; y++) { |
| 699 JSAMPLE* rowptr = (JSAMPLE*)srcRow; | 717 JSAMPLE* rowptr = (JSAMPLE*)srcRow; |
| 700 int row_count = jpeg_read_scanlines(&cinfo, &rowptr, 1); | 718 int row_count = jpeg_read_scanlines(&cinfo, &rowptr, 1); |
| 701 if (0 == row_count) { | 719 if (0 == row_count) { |
| 702 // if row_count == 0, then we didn't get a scanline, | 720 // if row_count == 0, then we didn't get a scanline, |
| 703 // so return early. We will return a partial image. | 721 // so return early. We will return a partial image. |
| 704 fill_below_level(y, bm); | 722 fill_below_level(y, bm); |
| 705 cinfo.output_scanline = cinfo.output_height; | 723 cinfo.output_scanline = cinfo.output_height; |
| 706 break; // Skip to jpeg_finish_decompress() | 724 jpeg_finish_decompress(&cinfo); |
| 725 return kSuccess; |
| 707 } | 726 } |
| 708 if (this->shouldCancelDecode()) { | 727 if (this->shouldCancelDecode()) { |
| 709 return return_false(cinfo, *bm, "shouldCancelDecode"); | 728 return return_failure(cinfo, *bm, "shouldCancelDecode"); |
| 710 } | 729 } |
| 711 | 730 |
| 712 if (JCS_CMYK == cinfo.out_color_space) { | 731 if (JCS_CMYK == cinfo.out_color_space) { |
| 713 convert_CMYK_to_RGB(srcRow, cinfo.output_width); | 732 convert_CMYK_to_RGB(srcRow, cinfo.output_width); |
| 714 } | 733 } |
| 715 | 734 |
| 716 sampler.next(srcRow); | 735 sampler.next(srcRow); |
| 717 if (bm->height() - 1 == y) { | 736 if (bm->height() - 1 == y) { |
| 718 // we're done | 737 // we're done |
| 719 break; | 738 break; |
| 720 } | 739 } |
| 721 | 740 |
| 722 if (!skip_src_rows(&cinfo, srcRow, sampler.srcDY() - 1)) { | 741 if (!skip_src_rows(&cinfo, srcRow, sampler.srcDY() - 1)) { |
| 723 return return_false(cinfo, *bm, "skip rows"); | 742 return return_failure(cinfo, *bm, "skip rows"); |
| 724 } | 743 } |
| 725 } | 744 } |
| 726 | 745 |
| 727 // we formally skip the rest, so we don't get a complaint from libjpeg | 746 // we formally skip the rest, so we don't get a complaint from libjpeg |
| 728 if (!skip_src_rows(&cinfo, srcRow, | 747 if (!skip_src_rows(&cinfo, srcRow, |
| 729 cinfo.output_height - cinfo.output_scanline)) { | 748 cinfo.output_height - cinfo.output_scanline)) { |
| 730 return return_false(cinfo, *bm, "skip rows"); | 749 return return_failure(cinfo, *bm, "skip rows"); |
| 731 } | 750 } |
| 732 jpeg_finish_decompress(&cinfo); | 751 jpeg_finish_decompress(&cinfo); |
| 733 | 752 |
| 734 return true; | 753 return kSuccess; |
| 735 } | 754 } |
| 736 | 755 |
| 756 /////////////////////////////////////////////////////////////////////////////// |
| 757 |
| 737 enum SizeType { | 758 enum SizeType { |
| 738 kSizeForMemoryAllocation_SizeType, | 759 kSizeForMemoryAllocation_SizeType, |
| 739 kActualSize_SizeType | 760 kActualSize_SizeType |
| 740 }; | 761 }; |
| 741 | 762 |
| 742 static SkISize compute_yuv_size(const jpeg_decompress_struct& info, int componen
t, | 763 static SkISize compute_yuv_size(const jpeg_decompress_struct& info, int componen
t, |
| 743 SizeType sizeType) { | 764 SizeType sizeType) { |
| 744 if (sizeType == kSizeForMemoryAllocation_SizeType) { | 765 if (sizeType == kSizeForMemoryAllocation_SizeType) { |
| 745 return SkISize::Make(info.cur_comp_info[component]->width_in_blocks * DC
TSIZE, | 766 return SkISize::Make(info.cur_comp_info[component]->width_in_blocks * DC
TSIZE, |
| 746 info.cur_comp_info[component]->height_in_blocks * D
CTSIZE); | 767 info.cur_comp_info[component]->height_in_blocks * D
CTSIZE); |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 871 bufferraw2[16 + i] = uLastRow; | 892 bufferraw2[16 + i] = uLastRow; |
| 872 bufferraw2[24 + i] = vLastRow; | 893 bufferraw2[24 + i] = vLastRow; |
| 873 hasUVLastRow = true; | 894 hasUVLastRow = true; |
| 874 } else { | 895 } else { |
| 875 bufferraw2[16 + i] = dummyRow; | 896 bufferraw2[16 + i] = dummyRow; |
| 876 bufferraw2[24 + i] = dummyRow; | 897 bufferraw2[24 + i] = dummyRow; |
| 877 } | 898 } |
| 878 } | 899 } |
| 879 JDIMENSION scanlinesRead = jpeg_read_raw_data(&cinfo, bufferraw, yScanli
nesToRead); | 900 JDIMENSION scanlinesRead = jpeg_read_raw_data(&cinfo, bufferraw, yScanli
nesToRead); |
| 880 | 901 |
| 881 if (scanlinesRead == 0) | 902 if (scanlinesRead == 0) { |
| 882 return false; | 903 return false; |
| 904 } |
| 883 | 905 |
| 884 if (hasYLastRow) { | 906 if (hasYLastRow) { |
| 885 memcpy(&outputY[yMaxH * rowBytesY], yLastRow, yWidth); | 907 memcpy(&outputY[yMaxH * rowBytesY], yLastRow, yWidth); |
| 886 } | 908 } |
| 887 if (hasUVLastRow) { | 909 if (hasUVLastRow) { |
| 888 memcpy(&outputU[uvMaxH * rowBytesU], uLastRow, uvSize.width()); | 910 memcpy(&outputU[uvMaxH * rowBytesU], uLastRow, uvSize.width()); |
| 889 memcpy(&outputV[uvMaxH * rowBytesV], vLastRow, uvSize.width()); | 911 memcpy(&outputV[uvMaxH * rowBytesV], vLastRow, uvSize.width()); |
| 890 } | 912 } |
| 891 } | 913 } |
| 892 | 914 |
| (...skipping 17 matching lines...) Expand all Loading... |
| 910 | 932 |
| 911 jpeg_decompress_struct cinfo; | 933 jpeg_decompress_struct cinfo; |
| 912 skjpeg_source_mgr srcManager(stream, this); | 934 skjpeg_source_mgr srcManager(stream, this); |
| 913 | 935 |
| 914 skjpeg_error_mgr errorManager; | 936 skjpeg_error_mgr errorManager; |
| 915 set_error_mgr(&cinfo, &errorManager); | 937 set_error_mgr(&cinfo, &errorManager); |
| 916 | 938 |
| 917 // All objects need to be instantiated before this setjmp call so that | 939 // All objects need to be instantiated before this setjmp call so that |
| 918 // they will be cleaned up properly if an error occurs. | 940 // they will be cleaned up properly if an error occurs. |
| 919 if (setjmp(errorManager.fJmpBuf)) { | 941 if (setjmp(errorManager.fJmpBuf)) { |
| 920 return return_false(cinfo, 0, 0, "setjmp YUV8"); | 942 return return_false(cinfo, "setjmp YUV8"); |
| 921 } | 943 } |
| 922 | 944 |
| 923 initialize_info(&cinfo, &srcManager); | 945 initialize_info(&cinfo, &srcManager); |
| 924 autoClean.set(&cinfo); | 946 autoClean.set(&cinfo); |
| 925 | 947 |
| 926 int status = jpeg_read_header(&cinfo, true); | 948 int status = jpeg_read_header(&cinfo, true); |
| 927 if (status != JPEG_HEADER_OK) { | 949 if (status != JPEG_HEADER_OK) { |
| 928 return return_false(cinfo, 0, 0, "read_header YUV8"); | 950 return return_false(cinfo, "read_header YUV8"); |
| 929 } | 951 } |
| 930 | 952 |
| 931 if (cinfo.jpeg_color_space != JCS_YCbCr) { | 953 if (cinfo.jpeg_color_space != JCS_YCbCr) { |
| 932 // It's not an error to not be encoded in YUV, so no need to use return_
false() | 954 // It's not an error to not be encoded in YUV, so no need to use return_
false() |
| 933 return false; | 955 return false; |
| 934 } | 956 } |
| 935 | 957 |
| 936 cinfo.out_color_space = JCS_YCbCr; | 958 cinfo.out_color_space = JCS_YCbCr; |
| 937 cinfo.raw_data_out = TRUE; | 959 cinfo.raw_data_out = TRUE; |
| 938 | 960 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 950 | 972 |
| 951 #ifdef ANDROID_RGB | 973 #ifdef ANDROID_RGB |
| 952 cinfo.dither_mode = JDITHER_NONE; | 974 cinfo.dither_mode = JDITHER_NONE; |
| 953 #endif | 975 #endif |
| 954 | 976 |
| 955 /* image_width and image_height are the original dimensions, available | 977 /* image_width and image_height are the original dimensions, available |
| 956 after jpeg_read_header(). To see the scaled dimensions, we have to call | 978 after jpeg_read_header(). To see the scaled dimensions, we have to call |
| 957 jpeg_start_decompress(), and then read output_width and output_height. | 979 jpeg_start_decompress(), and then read output_width and output_height. |
| 958 */ | 980 */ |
| 959 if (!jpeg_start_decompress(&cinfo)) { | 981 if (!jpeg_start_decompress(&cinfo)) { |
| 960 return return_false(cinfo, 0, 0, "start_decompress YUV8"); | 982 return return_false(cinfo, "start_decompress YUV8"); |
| 961 } | 983 } |
| 962 | 984 |
| 963 if (!output_raw_data(cinfo, planes, rowBytes)) { | 985 if (!output_raw_data(cinfo, planes, rowBytes)) { |
| 964 return return_false(cinfo, 0, 0, "output_raw_data"); | 986 return return_false(cinfo, "output_raw_data"); |
| 965 } | 987 } |
| 966 | 988 |
| 967 update_components_sizes(cinfo, componentSizes, kActualSize_SizeType); | 989 update_components_sizes(cinfo, componentSizes, kActualSize_SizeType); |
| 968 jpeg_finish_decompress(&cinfo); | 990 jpeg_finish_decompress(&cinfo); |
| 969 | 991 |
| 970 if (NULL != colorSpace) { | 992 if (NULL != colorSpace) { |
| 971 *colorSpace = kJPEG_SkYUVColorSpace; | 993 *colorSpace = kJPEG_SkYUVColorSpace; |
| 972 } | 994 } |
| 973 | 995 |
| 974 return true; | 996 return true; |
| 975 } | 997 } |
| 976 | 998 |
| 999 /////////////////////////////////////////////////////////////////////////////// |
| 1000 |
| 977 #ifdef SK_BUILD_FOR_ANDROID | 1001 #ifdef SK_BUILD_FOR_ANDROID |
| 978 bool SkJPEGImageDecoder::onBuildTileIndex(SkStreamRewindable* stream, int *width
, int *height) { | 1002 bool SkJPEGImageDecoder::onBuildTileIndex(SkStreamRewindable* stream, int *width
, int *height) { |
| 979 | 1003 |
| 980 SkAutoTDelete<SkJPEGImageIndex> imageIndex(SkNEW_ARGS(SkJPEGImageIndex, (str
eam, this))); | 1004 SkAutoTDelete<SkJPEGImageIndex> imageIndex(SkNEW_ARGS(SkJPEGImageIndex, (str
eam, this))); |
| 981 jpeg_decompress_struct* cinfo = imageIndex->cinfo(); | 1005 jpeg_decompress_struct* cinfo = imageIndex->cinfo(); |
| 982 | 1006 |
| 983 skjpeg_error_mgr sk_err; | 1007 skjpeg_error_mgr sk_err; |
| 984 set_error_mgr(cinfo, &sk_err); | 1008 set_error_mgr(cinfo, &sk_err); |
| 985 | 1009 |
| 986 // All objects need to be instantiated before this setjmp call so that | 1010 // All objects need to be instantiated before this setjmp call so that |
| (...skipping 494 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1481 return SkImageDecoder::kUnknown_Format; | 1505 return SkImageDecoder::kUnknown_Format; |
| 1482 } | 1506 } |
| 1483 | 1507 |
| 1484 static SkImageEncoder* sk_libjpeg_efactory(SkImageEncoder::Type t) { | 1508 static SkImageEncoder* sk_libjpeg_efactory(SkImageEncoder::Type t) { |
| 1485 return (SkImageEncoder::kJPEG_Type == t) ? SkNEW(SkJPEGImageEncoder) : NULL; | 1509 return (SkImageEncoder::kJPEG_Type == t) ? SkNEW(SkJPEGImageEncoder) : NULL; |
| 1486 } | 1510 } |
| 1487 | 1511 |
| 1488 static SkImageDecoder_DecodeReg gDReg(sk_libjpeg_dfactory); | 1512 static SkImageDecoder_DecodeReg gDReg(sk_libjpeg_dfactory); |
| 1489 static SkImageDecoder_FormatReg gFormatReg(get_format_jpeg); | 1513 static SkImageDecoder_FormatReg gFormatReg(get_format_jpeg); |
| 1490 static SkImageEncoder_EncodeReg gEReg(sk_libjpeg_efactory); | 1514 static SkImageEncoder_EncodeReg gEReg(sk_libjpeg_efactory); |
| OLD | NEW |