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

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

Issue 322963002: hide SkBitmap::setConfig (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 6 years, 6 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
« no previous file with comments | « src/images/SkImageDecoder_libico.cpp ('k') | src/images/SkImageDecoder_libpng.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 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 230 matching lines...) Expand 10 before | Expand all | Expand 10 after
241 virtual bool onDecode(SkStream* stream, SkBitmap* bm, Mode) SK_OVERRIDE; 241 virtual bool onDecode(SkStream* stream, SkBitmap* bm, Mode) SK_OVERRIDE;
242 242
243 private: 243 private:
244 #ifdef SK_BUILD_FOR_ANDROID 244 #ifdef SK_BUILD_FOR_ANDROID
245 SkJPEGImageIndex* fImageIndex; 245 SkJPEGImageIndex* fImageIndex;
246 int fImageWidth; 246 int fImageWidth;
247 int fImageHeight; 247 int fImageHeight;
248 #endif 248 #endif
249 249
250 /** 250 /**
251 * Determine the appropriate bitmap config and out_color_space based on 251 * Determine the appropriate bitmap colortype and out_color_space based on
252 * both the preference of the caller and the jpeg_color_space on the 252 * both the preference of the caller and the jpeg_color_space on the
253 * jpeg_decompress_struct passed in. 253 * jpeg_decompress_struct passed in.
254 * Must be called after jpeg_read_header. 254 * Must be called after jpeg_read_header.
255 */ 255 */
256 SkBitmap::Config getBitmapConfig(jpeg_decompress_struct*); 256 SkColorType getBitmapColorType(jpeg_decompress_struct*);
257 257
258 typedef SkImageDecoder INHERITED; 258 typedef SkImageDecoder INHERITED;
259 }; 259 };
260 260
261 ////////////////////////////////////////////////////////////////////////// 261 //////////////////////////////////////////////////////////////////////////
262 262
263 /* Automatically clean up after throwing an exception */ 263 /* Automatically clean up after throwing an exception */
264 class JPEGAutoClean { 264 class JPEGAutoClean {
265 public: 265 public:
266 JPEGAutoClean(): cinfo_ptr(NULL) {} 266 JPEGAutoClean(): cinfo_ptr(NULL) {}
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
393 if (decoder.getPreferQualityOverSpeed()) { 393 if (decoder.getPreferQualityOverSpeed()) {
394 cinfo->dct_method = JDCT_ISLOW; 394 cinfo->dct_method = JDCT_ISLOW;
395 } else { 395 } else {
396 cinfo->dct_method = JDCT_IFAST; 396 cinfo->dct_method = JDCT_IFAST;
397 } 397 }
398 #else 398 #else
399 cinfo->dct_method = JDCT_ISLOW; 399 cinfo->dct_method = JDCT_ISLOW;
400 #endif 400 #endif
401 } 401 }
402 402
403 SkBitmap::Config SkJPEGImageDecoder::getBitmapConfig(jpeg_decompress_struct* cin fo) { 403 SkColorType SkJPEGImageDecoder::getBitmapColorType(jpeg_decompress_struct* cinfo ) {
404 SkASSERT(cinfo != NULL); 404 SkASSERT(cinfo != NULL);
405 405
406 SrcDepth srcDepth = k32Bit_SrcDepth; 406 SrcDepth srcDepth = k32Bit_SrcDepth;
407 if (JCS_GRAYSCALE == cinfo->jpeg_color_space) { 407 if (JCS_GRAYSCALE == cinfo->jpeg_color_space) {
408 srcDepth = k8BitGray_SrcDepth; 408 srcDepth = k8BitGray_SrcDepth;
409 } 409 }
410 410
411 SkBitmap::Config config = this->getPrefConfig(srcDepth, /*hasAlpha*/ false); 411 SkColorType colorType = this->getPrefColorType(srcDepth, /*hasAlpha*/ false) ;
412 switch (config) { 412 switch (colorType) {
413 case SkBitmap::kA8_Config: 413 case kAlpha_8_SkColorType:
414 // Only respect A8 config if the original is grayscale, 414 // Only respect A8 colortype if the original is grayscale,
415 // in which case we will treat the grayscale as alpha 415 // in which case we will treat the grayscale as alpha
416 // values. 416 // values.
417 if (cinfo->jpeg_color_space != JCS_GRAYSCALE) { 417 if (cinfo->jpeg_color_space != JCS_GRAYSCALE) {
418 config = SkBitmap::kARGB_8888_Config; 418 colorType = kN32_SkColorType;
419 } 419 }
420 break; 420 break;
421 case SkBitmap::kARGB_8888_Config: 421 case kN32_SkColorType:
422 // Fall through. 422 // Fall through.
423 case SkBitmap::kARGB_4444_Config: 423 case kARGB_4444_SkColorType:
424 // Fall through. 424 // Fall through.
425 case SkBitmap::kRGB_565_Config: 425 case kRGB_565_SkColorType:
426 // These are acceptable destination configs. 426 // These are acceptable destination colortypes.
427 break; 427 break;
428 default: 428 default:
429 // Force all other configs to 8888. 429 // Force all other colortypes to 8888.
430 config = SkBitmap::kARGB_8888_Config; 430 colorType = kN32_SkColorType;
431 break; 431 break;
432 } 432 }
433 433
434 switch (cinfo->jpeg_color_space) { 434 switch (cinfo->jpeg_color_space) {
435 case JCS_CMYK: 435 case JCS_CMYK:
436 // Fall through. 436 // Fall through.
437 case JCS_YCCK: 437 case JCS_YCCK:
438 // libjpeg cannot convert from CMYK or YCCK to RGB - here we set up 438 // libjpeg cannot convert from CMYK or YCCK to RGB - here we set up
439 // so libjpeg will give us CMYK samples back and we will later 439 // so libjpeg will give us CMYK samples back and we will later
440 // manually convert them to RGB 440 // manually convert them to RGB
441 cinfo->out_color_space = JCS_CMYK; 441 cinfo->out_color_space = JCS_CMYK;
442 break; 442 break;
443 case JCS_GRAYSCALE: 443 case JCS_GRAYSCALE:
444 if (SkBitmap::kA8_Config == config) { 444 if (kAlpha_8_SkColorType == colorType) {
445 cinfo->out_color_space = JCS_GRAYSCALE; 445 cinfo->out_color_space = JCS_GRAYSCALE;
446 break; 446 break;
447 } 447 }
448 // The data is JCS_GRAYSCALE, but the caller wants some sort of RGB 448 // The data is JCS_GRAYSCALE, but the caller wants some sort of RGB
449 // config. Fall through to set to the default. 449 // colortype. Fall through to set to the default.
450 default: 450 default:
451 cinfo->out_color_space = JCS_RGB; 451 cinfo->out_color_space = JCS_RGB;
452 break; 452 break;
453 } 453 }
454 return config; 454 return colorType;
455 } 455 }
456 456
457 #ifdef ANDROID_RGB
458 /** 457 /**
459 * Based on the config and dither mode, adjust out_color_space and 458 * Based on the colortype and dither mode, adjust out_color_space and
460 * dither_mode of cinfo. 459 * dither_mode of cinfo. Only does work in ANDROID_RGB
461 */ 460 */
462 static void adjust_out_color_space_and_dither(jpeg_decompress_struct* cinfo, 461 static void adjust_out_color_space_and_dither(jpeg_decompress_struct* cinfo,
463 SkBitmap::Config config, 462 SkColorType colorType,
464 const SkImageDecoder& decoder) { 463 const SkImageDecoder& decoder) {
465 SkASSERT(cinfo != NULL); 464 SkASSERT(cinfo != NULL);
465 #ifdef ANDROID_RGB
466 cinfo->dither_mode = JDITHER_NONE; 466 cinfo->dither_mode = JDITHER_NONE;
467 if (JCS_CMYK == cinfo->out_color_space) { 467 if (JCS_CMYK == cinfo->out_color_space) {
468 return; 468 return;
469 } 469 }
470 switch(config) { 470 switch (colorType) {
471 case SkBitmap::kARGB_8888_Config: 471 case kN32_SkColorType:
472 cinfo->out_color_space = JCS_RGBA_8888; 472 cinfo->out_color_space = JCS_RGBA_8888;
473 break; 473 break;
474 case SkBitmap::kRGB_565_Config: 474 case kRGB_565_SkColorType:
475 cinfo->out_color_space = JCS_RGB_565; 475 cinfo->out_color_space = JCS_RGB_565;
476 if (decoder.getDitherImage()) { 476 if (decoder.getDitherImage()) {
477 cinfo->dither_mode = JDITHER_ORDERED; 477 cinfo->dither_mode = JDITHER_ORDERED;
478 } 478 }
479 break; 479 break;
480 default: 480 default:
481 break; 481 break;
482 } 482 }
483 #endif
483 } 484 }
484 #endif
485 485
486 486
487 /** 487 /**
488 Sets all pixels in given bitmap to SK_ColorWHITE for all rows >= y. 488 Sets all pixels in given bitmap to SK_ColorWHITE for all rows >= y.
489 Used when decoding fails partway through reading scanlines to fill 489 Used when decoding fails partway through reading scanlines to fill
490 remaining lines. */ 490 remaining lines. */
491 static void fill_below_level(int y, SkBitmap* bitmap) { 491 static void fill_below_level(int y, SkBitmap* bitmap) {
492 SkIRect rect = SkIRect::MakeLTRB(0, y, bitmap->width(), bitmap->height()); 492 SkIRect rect = SkIRect::MakeLTRB(0, y, bitmap->width(), bitmap->height());
493 SkCanvas canvas(*bitmap); 493 SkCanvas canvas(*bitmap);
494 canvas.clipRect(SkRect::Make(rect)); 494 canvas.clipRect(SkRect::Make(rect));
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
562 */ 562 */
563 int sampleSize = this->getSampleSize(); 563 int sampleSize = this->getSampleSize();
564 564
565 set_dct_method(*this, &cinfo); 565 set_dct_method(*this, &cinfo);
566 566
567 SkASSERT(1 == cinfo.scale_num); 567 SkASSERT(1 == cinfo.scale_num);
568 cinfo.scale_denom = sampleSize; 568 cinfo.scale_denom = sampleSize;
569 569
570 turn_off_visual_optimizations(&cinfo); 570 turn_off_visual_optimizations(&cinfo);
571 571
572 const SkBitmap::Config config = this->getBitmapConfig(&cinfo); 572 const SkColorType colorType = this->getBitmapColorType(&cinfo);
573 const SkAlphaType alphaType = kAlpha_8_SkColorType == colorType ?
574 kPremul_SkAlphaType : kOpaque_SkAlphaType;
573 575
574 #ifdef ANDROID_RGB 576 adjust_out_color_space_and_dither(&cinfo, colorType, *this);
575 adjust_out_color_space_and_dither(&cinfo, config, *this);
576 #endif
577 577
578 if (1 == sampleSize && SkImageDecoder::kDecodeBounds_Mode == mode) { 578 if (1 == sampleSize && SkImageDecoder::kDecodeBounds_Mode == mode) {
579 // Assume an A8 bitmap is not opaque to avoid the check of each 579 // Assume an A8 bitmap is not opaque to avoid the check of each
580 // individual pixel. It is very unlikely to be opaque, since 580 // individual pixel. It is very unlikely to be opaque, since
581 // an opaque A8 bitmap would not be very interesting. 581 // an opaque A8 bitmap would not be very interesting.
582 // Otherwise, a jpeg image is opaque. 582 // Otherwise, a jpeg image is opaque.
583 return bm->setConfig(config, cinfo.image_width, cinfo.image_height, 0, 583 return bm->setInfo(SkImageInfo::Make(cinfo.image_width, cinfo.image_heig ht,
584 SkBitmap::kA8_Config == config ? 584 colorType, alphaType));
585 kPremul_SkAlphaType : kOpaque_SkAlphaType);
586 } 585 }
587 586
588 /* image_width and image_height are the original dimensions, available 587 /* image_width and image_height are the original dimensions, available
589 after jpeg_read_header(). To see the scaled dimensions, we have to call 588 after jpeg_read_header(). To see the scaled dimensions, we have to call
590 jpeg_start_decompress(), and then read output_width and output_height. 589 jpeg_start_decompress(), and then read output_width and output_height.
591 */ 590 */
592 if (!jpeg_start_decompress(&cinfo)) { 591 if (!jpeg_start_decompress(&cinfo)) {
593 /* If we failed here, we may still have enough information to return 592 /* If we failed here, we may still have enough information to return
594 to the caller if they just wanted (subsampled bounds). If sampleSize 593 to the caller if they just wanted (subsampled bounds). If sampleSize
595 was 1, then we would have already returned. Thus we just check if 594 was 1, then we would have already returned. Thus we just check if
596 we're in kDecodeBounds_Mode, and that we have valid output sizes. 595 we're in kDecodeBounds_Mode, and that we have valid output sizes.
597 596
598 One reason to fail here is that we have insufficient stream data 597 One reason to fail here is that we have insufficient stream data
599 to complete the setup. However, output dimensions seem to get 598 to complete the setup. However, output dimensions seem to get
600 computed very early, which is why this special check can pay off. 599 computed very early, which is why this special check can pay off.
601 */ 600 */
602 if (SkImageDecoder::kDecodeBounds_Mode == mode && valid_output_dimension s(cinfo)) { 601 if (SkImageDecoder::kDecodeBounds_Mode == mode && valid_output_dimension s(cinfo)) {
603 SkScaledBitmapSampler smpl(cinfo.output_width, cinfo.output_height, 602 SkScaledBitmapSampler smpl(cinfo.output_width, cinfo.output_height,
604 recompute_sampleSize(sampleSize, cinfo)); 603 recompute_sampleSize(sampleSize, cinfo));
605 // Assume an A8 bitmap is not opaque to avoid the check of each 604 // Assume an A8 bitmap is not opaque to avoid the check of each
606 // individual pixel. It is very unlikely to be opaque, since 605 // individual pixel. It is very unlikely to be opaque, since
607 // an opaque A8 bitmap would not be very interesting. 606 // an opaque A8 bitmap would not be very interesting.
608 // Otherwise, a jpeg image is opaque. 607 // Otherwise, a jpeg image is opaque.
609 return bm->setConfig(config, smpl.scaledWidth(), smpl.scaledHeight() , 608 return bm->setInfo(SkImageInfo::Make(smpl.scaledWidth(), smpl.scaled Height(),
610 0, SkBitmap::kA8_Config == config ? 609 colorType, alphaType));
611 kPremul_SkAlphaType : kOpaque_SkAlphaType);
612 } else { 610 } else {
613 return return_false(cinfo, *bm, "start_decompress"); 611 return return_false(cinfo, *bm, "start_decompress");
614 } 612 }
615 } 613 }
616 sampleSize = recompute_sampleSize(sampleSize, cinfo); 614 sampleSize = recompute_sampleSize(sampleSize, cinfo);
617 615
618 // should we allow the Chooser (if present) to pick a config for us??? 616 // should we allow the Chooser (if present) to pick a colortype for us???
619 if (!this->chooseFromOneChoice(config, cinfo.output_width, cinfo.output_heig ht)) { 617 if (!this->chooseFromOneChoice(colorType, cinfo.output_width, cinfo.output_h eight)) {
620 return return_false(cinfo, *bm, "chooseFromOneChoice"); 618 return return_false(cinfo, *bm, "chooseFromOneChoice");
621 } 619 }
622 620
623 SkScaledBitmapSampler sampler(cinfo.output_width, cinfo.output_height, sampl eSize); 621 SkScaledBitmapSampler sampler(cinfo.output_width, cinfo.output_height, sampl eSize);
624 // Assume an A8 bitmap is not opaque to avoid the check of each 622 // Assume an A8 bitmap is not opaque to avoid the check of each
625 // individual pixel. It is very unlikely to be opaque, since 623 // individual pixel. It is very unlikely to be opaque, since
626 // an opaque A8 bitmap would not be very interesting. 624 // an opaque A8 bitmap would not be very interesting.
627 // Otherwise, a jpeg image is opaque. 625 // Otherwise, a jpeg image is opaque.
628 bm->setConfig(config, sampler.scaledWidth(), sampler.scaledHeight(), 0, 626 bm->setInfo(SkImageInfo::Make(sampler.scaledWidth(), sampler.scaledHeight(),
629 SkBitmap::kA8_Config != config ? kOpaque_SkAlphaType : kPremul _SkAlphaType); 627 colorType, alphaType));
630 if (SkImageDecoder::kDecodeBounds_Mode == mode) { 628 if (SkImageDecoder::kDecodeBounds_Mode == mode) {
631 return true; 629 return true;
632 } 630 }
633 if (!this->allocPixelRef(bm, NULL)) { 631 if (!this->allocPixelRef(bm, NULL)) {
634 return return_false(cinfo, *bm, "allocPixelRef"); 632 return return_false(cinfo, *bm, "allocPixelRef");
635 } 633 }
636 634
637 SkAutoLockPixels alp(*bm); 635 SkAutoLockPixels alp(*bm);
638 636
639 #ifdef ANDROID_RGB 637 #ifdef ANDROID_RGB
640 /* short-circuit the SkScaledBitmapSampler when possible, as this gives 638 /* short-circuit the SkScaledBitmapSampler when possible, as this gives
641 a significant performance boost. 639 a significant performance boost.
642 */ 640 */
643 if (sampleSize == 1 && 641 if (sampleSize == 1 &&
644 ((config == SkBitmap::kARGB_8888_Config && 642 ((kN32_SkColorType == colorType && cinfo.out_color_space == JCS_RGBA_888 8) ||
645 cinfo.out_color_space == JCS_RGBA_8888) || 643 (kRGB_565_SkColorType == colorType && cinfo.out_color_space == JCS_RGB_ 565)))
646 (config == SkBitmap::kRGB_565_Config &&
647 cinfo.out_color_space == JCS_RGB_565)))
648 { 644 {
649 JSAMPLE* rowptr = (JSAMPLE*)bm->getPixels(); 645 JSAMPLE* rowptr = (JSAMPLE*)bm->getPixels();
650 INT32 const bpr = bm->rowBytes(); 646 INT32 const bpr = bm->rowBytes();
651 647
652 while (cinfo.output_scanline < cinfo.output_height) { 648 while (cinfo.output_scanline < cinfo.output_height) {
653 int row_count = jpeg_read_scanlines(&cinfo, &rowptr, 1); 649 int row_count = jpeg_read_scanlines(&cinfo, &rowptr, 1);
654 if (0 == row_count) { 650 if (0 == row_count) {
655 // if row_count == 0, then we didn't get a scanline, 651 // if row_count == 0, then we didn't get a scanline,
656 // so return early. We will return a partial image. 652 // so return early. We will return a partial image.
657 fill_below_level(cinfo.output_scanline, bm); 653 fill_below_level(cinfo.output_scanline, bm);
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
757 753
758 // Init decoder to image decode mode 754 // Init decoder to image decode mode
759 if (!imageIndex->initializeInfoAndReadHeader()) { 755 if (!imageIndex->initializeInfoAndReadHeader()) {
760 return false; 756 return false;
761 } 757 }
762 758
763 // FIXME: This sets cinfo->out_color_space, which we may change later 759 // FIXME: This sets cinfo->out_color_space, which we may change later
764 // based on the config in onDecodeSubset. This should be fine, since 760 // based on the config in onDecodeSubset. This should be fine, since
765 // jpeg_init_read_tile_scanline will check out_color_space again after 761 // jpeg_init_read_tile_scanline will check out_color_space again after
766 // that change (when it calls jinit_color_deconverter). 762 // that change (when it calls jinit_color_deconverter).
767 (void) this->getBitmapConfig(cinfo); 763 (void) this->getBitmapColorType(cinfo);
768 764
769 turn_off_visual_optimizations(cinfo); 765 turn_off_visual_optimizations(cinfo);
770 766
771 // instead of jpeg_start_decompress() we start a tiled decompress 767 // instead of jpeg_start_decompress() we start a tiled decompress
772 if (!imageIndex->startTileDecompress()) { 768 if (!imageIndex->startTileDecompress()) {
773 return false; 769 return false;
774 } 770 }
775 771
776 SkASSERT(1 == cinfo->scale_num); 772 SkASSERT(1 == cinfo->scale_num);
777 fImageWidth = cinfo->output_width; 773 fImageWidth = cinfo->output_width;
(...skipping 30 matching lines...) Expand all
808 804
809 if (setjmp(errorManager.fJmpBuf)) { 805 if (setjmp(errorManager.fJmpBuf)) {
810 return false; 806 return false;
811 } 807 }
812 808
813 int requestedSampleSize = this->getSampleSize(); 809 int requestedSampleSize = this->getSampleSize();
814 cinfo->scale_denom = requestedSampleSize; 810 cinfo->scale_denom = requestedSampleSize;
815 811
816 set_dct_method(*this, cinfo); 812 set_dct_method(*this, cinfo);
817 813
818 const SkBitmap::Config config = this->getBitmapConfig(cinfo); 814 const SkColorType colorType = this->getBitmapColorType(cinfo);
819 #ifdef ANDROID_RGB 815 adjust_out_color_space_and_dither(cinfo, colorType, *this);
820 adjust_out_color_space_and_dither(cinfo, config, *this);
821 #endif
822 816
823 int startX = rect.fLeft; 817 int startX = rect.fLeft;
824 int startY = rect.fTop; 818 int startY = rect.fTop;
825 int width = rect.width(); 819 int width = rect.width();
826 int height = rect.height(); 820 int height = rect.height();
827 821
828 jpeg_init_read_tile_scanline(cinfo, fImageIndex->huffmanIndex(), 822 jpeg_init_read_tile_scanline(cinfo, fImageIndex->huffmanIndex(),
829 &startX, &startY, &width, &height); 823 &startX, &startY, &width, &height);
830 int skiaSampleSize = recompute_sampleSize(requestedSampleSize, *cinfo); 824 int skiaSampleSize = recompute_sampleSize(requestedSampleSize, *cinfo);
831 int actualSampleSize = skiaSampleSize * (DCTSIZE / cinfo->min_DCT_scaled_siz e); 825 int actualSampleSize = skiaSampleSize * (DCTSIZE / cinfo->min_DCT_scaled_siz e);
832 826
833 SkScaledBitmapSampler sampler(width, height, skiaSampleSize); 827 SkScaledBitmapSampler sampler(width, height, skiaSampleSize);
834 828
835 SkBitmap bitmap; 829 SkBitmap bitmap;
836 bitmap.setConfig(config, sampler.scaledWidth(), sampler.scaledHeight());
837 // Assume an A8 bitmap is not opaque to avoid the check of each 830 // Assume an A8 bitmap is not opaque to avoid the check of each
838 // individual pixel. It is very unlikely to be opaque, since 831 // individual pixel. It is very unlikely to be opaque, since
839 // an opaque A8 bitmap would not be very interesting. 832 // an opaque A8 bitmap would not be very interesting.
840 // Otherwise, a jpeg image is opaque. 833 // Otherwise, a jpeg image is opaque.
841 bitmap.setConfig(config, sampler.scaledWidth(), sampler.scaledHeight(), 0, 834 bitmap.setInfo(SkImageInfo::Make(sampler.scaledWidth(), sampler.scaledHeight (), colorType,
842 config == SkBitmap::kA8_Config ? kPremul_SkAlphaType : 835 kAlpha_8_SkColorType == colorType ?
843 kOpaque_SkAlphaType); 836 kPremul_SkAlphaType : kOpaque_SkAlphaTy pe));
844 837
845 // Check ahead of time if the swap(dest, src) is possible or not. 838 // Check ahead of time if the swap(dest, src) is possible or not.
846 // If yes, then we will stick to AllocPixelRef since it's cheaper with the 839 // If yes, then we will stick to AllocPixelRef since it's cheaper with the
847 // swap happening. If no, then we will use alloc to allocate pixels to 840 // swap happening. If no, then we will use alloc to allocate pixels to
848 // prevent garbage collection. 841 // prevent garbage collection.
849 int w = rect.width() / actualSampleSize; 842 int w = rect.width() / actualSampleSize;
850 int h = rect.height() / actualSampleSize; 843 int h = rect.height() / actualSampleSize;
851 bool swapOnly = (rect == region) && bm->isNull() && 844 bool swapOnly = (rect == region) && bm->isNull() &&
852 (w == bitmap.width()) && (h == bitmap.height()) && 845 (w == bitmap.width()) && (h == bitmap.height()) &&
853 ((startX - rect.x()) / actualSampleSize == 0) && 846 ((startX - rect.x()) / actualSampleSize == 0) &&
854 ((startY - rect.y()) / actualSampleSize == 0); 847 ((startY - rect.y()) / actualSampleSize == 0);
855 if (swapOnly) { 848 if (swapOnly) {
856 if (!this->allocPixelRef(&bitmap, NULL)) { 849 if (!this->allocPixelRef(&bitmap, NULL)) {
857 return return_false(*cinfo, bitmap, "allocPixelRef"); 850 return return_false(*cinfo, bitmap, "allocPixelRef");
858 } 851 }
859 } else { 852 } else {
860 if (!bitmap.allocPixels()) { 853 if (!bitmap.allocPixels()) {
861 return return_false(*cinfo, bitmap, "allocPixels"); 854 return return_false(*cinfo, bitmap, "allocPixels");
862 } 855 }
863 } 856 }
864 857
865 SkAutoLockPixels alp(bitmap); 858 SkAutoLockPixels alp(bitmap);
866 859
867 #ifdef ANDROID_RGB 860 #ifdef ANDROID_RGB
868 /* short-circuit the SkScaledBitmapSampler when possible, as this gives 861 /* short-circuit the SkScaledBitmapSampler when possible, as this gives
869 a significant performance boost. 862 a significant performance boost.
870 */ 863 */
871 if (skiaSampleSize == 1 && 864 if (skiaSampleSize == 1 &&
872 ((config == SkBitmap::kARGB_8888_Config && 865 ((kN32_SkColorType == colorType && cinfo->out_color_space == JCS_RGBA_88 88) ||
873 cinfo->out_color_space == JCS_RGBA_8888) || 866 (kRGB_565_SkColorType == colorType && cinfo->out_color_space == JCS_RGB _565)))
874 (config == SkBitmap::kRGB_565_Config &&
875 cinfo->out_color_space == JCS_RGB_565)))
876 { 867 {
877 JSAMPLE* rowptr = (JSAMPLE*)bitmap.getPixels(); 868 JSAMPLE* rowptr = (JSAMPLE*)bitmap.getPixels();
878 INT32 const bpr = bitmap.rowBytes(); 869 INT32 const bpr = bitmap.rowBytes();
879 int rowTotalCount = 0; 870 int rowTotalCount = 0;
880 871
881 while (rowTotalCount < height) { 872 while (rowTotalCount < height) {
882 int rowCount = jpeg_read_tile_scanline(cinfo, 873 int rowCount = jpeg_read_tile_scanline(cinfo,
883 fImageIndex->huffmanIndex(), 874 fImageIndex->huffmanIndex(),
884 &rowptr); 875 &rowptr);
885 // if rowCount == 0, then we didn't get a scanline, so abort. 876 // if rowCount == 0, then we didn't get a scanline, so abort.
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after
1109 uint32_t c = ctable[*src++]; 1100 uint32_t c = ctable[*src++];
1110 dst[0] = SkGetPackedR32(c); 1101 dst[0] = SkGetPackedR32(c);
1111 dst[1] = SkGetPackedG32(c); 1102 dst[1] = SkGetPackedG32(c);
1112 dst[2] = SkGetPackedB32(c); 1103 dst[2] = SkGetPackedB32(c);
1113 #endif 1104 #endif
1114 dst += 3; 1105 dst += 3;
1115 } 1106 }
1116 } 1107 }
1117 1108
1118 static WriteScanline ChooseWriter(const SkBitmap& bm) { 1109 static WriteScanline ChooseWriter(const SkBitmap& bm) {
1119 switch (bm.config()) { 1110 switch (bm.colorType()) {
1120 case SkBitmap::kARGB_8888_Config: 1111 case kN32_SkColorType:
1121 return Write_32_YUV; 1112 return Write_32_YUV;
1122 case SkBitmap::kRGB_565_Config: 1113 case kRGB_565_SkColorType:
1123 return Write_16_YUV; 1114 return Write_16_YUV;
1124 case SkBitmap::kARGB_4444_Config: 1115 case kARGB_4444_SkColorType:
1125 return Write_4444_YUV; 1116 return Write_4444_YUV;
1126 case SkBitmap::kIndex8_Config: 1117 case kIndex_8_SkColorType:
1127 return Write_Index_YUV; 1118 return Write_Index_YUV;
1128 default: 1119 default:
1129 return NULL; 1120 return NULL;
1130 } 1121 }
1131 } 1122 }
1132 1123
1133 class SkJPEGImageEncoder : public SkImageEncoder { 1124 class SkJPEGImageEncoder : public SkImageEncoder {
1134 protected: 1125 protected:
1135 virtual bool onEncode(SkWStream* stream, const SkBitmap& bm, int quality) { 1126 virtual bool onEncode(SkWStream* stream, const SkBitmap& bm, int quality) {
1136 #ifdef TIME_ENCODE 1127 #ifdef TIME_ENCODE
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
1240 return SkImageDecoder::kUnknown_Format; 1231 return SkImageDecoder::kUnknown_Format;
1241 } 1232 }
1242 1233
1243 static SkImageEncoder* sk_libjpeg_efactory(SkImageEncoder::Type t) { 1234 static SkImageEncoder* sk_libjpeg_efactory(SkImageEncoder::Type t) {
1244 return (SkImageEncoder::kJPEG_Type == t) ? SkNEW(SkJPEGImageEncoder) : NULL; 1235 return (SkImageEncoder::kJPEG_Type == t) ? SkNEW(SkJPEGImageEncoder) : NULL;
1245 } 1236 }
1246 1237
1247 static SkImageDecoder_DecodeReg gDReg(sk_libjpeg_dfactory); 1238 static SkImageDecoder_DecodeReg gDReg(sk_libjpeg_dfactory);
1248 static SkImageDecoder_FormatReg gFormatReg(get_format_jpeg); 1239 static SkImageDecoder_FormatReg gFormatReg(get_format_jpeg);
1249 static SkImageEncoder_EncodeReg gEReg(sk_libjpeg_efactory); 1240 static SkImageEncoder_EncodeReg gEReg(sk_libjpeg_efactory);
OLDNEW
« no previous file with comments | « src/images/SkImageDecoder_libico.cpp ('k') | src/images/SkImageDecoder_libpng.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698