| 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 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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 bool onDecode(SkStream* stream, SkBitmap* bm, Mode) SK_OVERRIDE; |
| 242 virtual bool onDecodeYUV8Planes(SkStream* stream, SkISize componentSizes[3], | |
| 243 void* planes[3], size_t rowBytes[3], | |
| 244 SkYUVColorSpace* colorSpace) SK_OVERRIDE; | |
| 245 | 242 |
| 246 private: | 243 private: |
| 247 #ifdef SK_BUILD_FOR_ANDROID | 244 #ifdef SK_BUILD_FOR_ANDROID |
| 248 SkJPEGImageIndex* fImageIndex; | 245 SkJPEGImageIndex* fImageIndex; |
| 249 int fImageWidth; | 246 int fImageWidth; |
| 250 int fImageHeight; | 247 int fImageHeight; |
| 251 #endif | 248 #endif |
| 252 | 249 |
| 253 /** | 250 /** |
| 254 * Determine the appropriate bitmap colortype and out_color_space based on | 251 * Determine the appropriate bitmap colortype and out_color_space based on |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 321 return false; | 318 return false; |
| 322 } | 319 } |
| 323 } | 320 } |
| 324 return true; | 321 return true; |
| 325 } | 322 } |
| 326 #endif | 323 #endif |
| 327 | 324 |
| 328 // This guy exists just to aid in debugging, as it allows debuggers to just | 325 // 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. | 326 // set a break-point in one place to see all error exists. |
| 330 static bool return_false(const jpeg_decompress_struct& cinfo, | 327 static bool return_false(const jpeg_decompress_struct& cinfo, |
| 331 int width, int height, const char caller[]) { | 328 const SkBitmap& bm, const char caller[]) { |
| 332 if (!(c_suppressJPEGImageDecoderErrors)) { | 329 if (!(c_suppressJPEGImageDecoderErrors)) { |
| 333 char buffer[JMSG_LENGTH_MAX]; | 330 char buffer[JMSG_LENGTH_MAX]; |
| 334 cinfo.err->format_message((const j_common_ptr)&cinfo, buffer); | 331 cinfo.err->format_message((const j_common_ptr)&cinfo, buffer); |
| 335 SkDebugf("libjpeg error %d <%s> from %s [%d %d]\n", | 332 SkDebugf("libjpeg error %d <%s> from %s [%d %d]\n", |
| 336 cinfo.err->msg_code, buffer, caller, width, height); | 333 cinfo.err->msg_code, buffer, caller, bm.width(), bm.height()); |
| 337 } | 334 } |
| 338 return false; // must always return false | 335 return false; // must always return false |
| 339 } | 336 } |
| 340 | 337 |
| 341 static bool return_false(const jpeg_decompress_struct& cinfo, | |
| 342 const SkBitmap& bm, const char caller[]) { | |
| 343 return return_false(cinfo, bm.width(), bm.height(), caller); | |
| 344 } | |
| 345 | |
| 346 // Convert a scanline of CMYK samples to RGBX in place. Note that this | 338 // Convert a scanline of CMYK samples to RGBX in place. Note that this |
| 347 // method moves the "scanline" pointer in its processing | 339 // method moves the "scanline" pointer in its processing |
| 348 static void convert_CMYK_to_RGB(uint8_t* scanline, unsigned int width) { | 340 static void convert_CMYK_to_RGB(uint8_t* scanline, unsigned int width) { |
| 349 // At this point we've received CMYK pixels from libjpeg. We | 341 // At this point we've received CMYK pixels from libjpeg. We |
| 350 // perform a crude conversion to RGB (based on the formulae | 342 // perform a crude conversion to RGB (based on the formulae |
| 351 // from easyrgb.com): | 343 // from easyrgb.com): |
| 352 // CMYK -> CMY | 344 // CMYK -> CMY |
| 353 // C = ( C * (1 - K) + K ) // for each CMY component | 345 // C = ( C * (1 - K) + K ) // for each CMY component |
| 354 // CMY -> RGB | 346 // CMY -> RGB |
| 355 // R = ( 1 - C ) * 255 // for each RGB component | 347 // R = ( 1 - C ) * 255 // for each RGB component |
| (...skipping 371 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 727 // we formally skip the rest, so we don't get a complaint from libjpeg | 719 // we formally skip the rest, so we don't get a complaint from libjpeg |
| 728 if (!skip_src_rows(&cinfo, srcRow, | 720 if (!skip_src_rows(&cinfo, srcRow, |
| 729 cinfo.output_height - cinfo.output_scanline)) { | 721 cinfo.output_height - cinfo.output_scanline)) { |
| 730 return return_false(cinfo, *bm, "skip rows"); | 722 return return_false(cinfo, *bm, "skip rows"); |
| 731 } | 723 } |
| 732 jpeg_finish_decompress(&cinfo); | 724 jpeg_finish_decompress(&cinfo); |
| 733 | 725 |
| 734 return true; | 726 return true; |
| 735 } | 727 } |
| 736 | 728 |
| 737 enum SizeType { | |
| 738 kSizeForMemoryAllocation_SizeType, | |
| 739 kActualSize_SizeType | |
| 740 }; | |
| 741 | |
| 742 static SkISize compute_yuv_size(const jpeg_decompress_struct& info, int componen
t, | |
| 743 SizeType sizeType) { | |
| 744 if (sizeType == kSizeForMemoryAllocation_SizeType) { | |
| 745 return SkISize::Make(info.cur_comp_info[component]->width_in_blocks * DC
TSIZE, | |
| 746 info.cur_comp_info[component]->height_in_blocks * D
CTSIZE); | |
| 747 } | |
| 748 return SkISize::Make(info.cur_comp_info[component]->downsampled_width, | |
| 749 info.cur_comp_info[component]->downsampled_height); | |
| 750 } | |
| 751 | |
| 752 // Enum for YUV decoding | |
| 753 enum YUVSubsampling { | |
| 754 kUNKNOWN_YUVSubsampling, | |
| 755 k410_YUVSubsampling, | |
| 756 k411_YUVSubsampling, | |
| 757 k420_YUVSubsampling, | |
| 758 k422_YUVSubsampling, | |
| 759 k440_YUVSubsampling, | |
| 760 k444_YUVSubsampling | |
| 761 }; | |
| 762 | |
| 763 static YUVSubsampling yuv_subsampling(const jpeg_decompress_struct& info) { | |
| 764 if ((DCTSIZE == 8) | |
| 765 && (info.num_components == 3) | |
| 766 && (info.comps_in_scan >= info.num_components) | |
| 767 && (info.scale_denom <= 8) | |
| 768 && (info.cur_comp_info[0]) | |
| 769 && (info.cur_comp_info[1]) | |
| 770 && (info.cur_comp_info[2]) | |
| 771 && (info.cur_comp_info[1]->h_samp_factor == 1) | |
| 772 && (info.cur_comp_info[1]->v_samp_factor == 1) | |
| 773 && (info.cur_comp_info[2]->h_samp_factor == 1) | |
| 774 && (info.cur_comp_info[2]->v_samp_factor == 1)) | |
| 775 { | |
| 776 int h = info.cur_comp_info[0]->h_samp_factor; | |
| 777 int v = info.cur_comp_info[0]->v_samp_factor; | |
| 778 // 4:4:4 : (h == 1) && (v == 1) | |
| 779 // 4:4:0 : (h == 1) && (v == 2) | |
| 780 // 4:2:2 : (h == 2) && (v == 1) | |
| 781 // 4:2:0 : (h == 2) && (v == 2) | |
| 782 // 4:1:1 : (h == 4) && (v == 1) | |
| 783 // 4:1:0 : (h == 4) && (v == 2) | |
| 784 if (v == 1) { | |
| 785 switch (h) { | |
| 786 case 1: | |
| 787 return k444_YUVSubsampling; | |
| 788 case 2: | |
| 789 return k422_YUVSubsampling; | |
| 790 case 4: | |
| 791 return k411_YUVSubsampling; | |
| 792 default: | |
| 793 break; | |
| 794 } | |
| 795 } else if (v == 2) { | |
| 796 switch (h) { | |
| 797 case 1: | |
| 798 return k440_YUVSubsampling; | |
| 799 case 2: | |
| 800 return k420_YUVSubsampling; | |
| 801 case 4: | |
| 802 return k410_YUVSubsampling; | |
| 803 default: | |
| 804 break; | |
| 805 } | |
| 806 } | |
| 807 } | |
| 808 | |
| 809 return kUNKNOWN_YUVSubsampling; | |
| 810 } | |
| 811 | |
| 812 static void update_components_sizes(const jpeg_decompress_struct& cinfo, SkISize
componentSizes[3], | |
| 813 SizeType sizeType) { | |
| 814 for (int i = 0; i < 3; ++i) { | |
| 815 componentSizes[i] = compute_yuv_size(cinfo, i, sizeType); | |
| 816 } | |
| 817 } | |
| 818 | |
| 819 static bool output_raw_data(jpeg_decompress_struct& cinfo, void* planes[3], size
_t rowBytes[3]) { | |
| 820 // U size and V size have to be the same if we're calling output_raw_data() | |
| 821 SkISize uvSize = compute_yuv_size(cinfo, 1, kSizeForMemoryAllocation_SizeTyp
e); | |
| 822 SkASSERT(uvSize == compute_yuv_size(cinfo, 2, kSizeForMemoryAllocation_SizeT
ype)); | |
| 823 | |
| 824 JSAMPARRAY bufferraw[3]; | |
| 825 JSAMPROW bufferraw2[32]; | |
| 826 bufferraw[0] = &bufferraw2[0]; // Y channel rows (8 or 16) | |
| 827 bufferraw[1] = &bufferraw2[16]; // U channel rows (8) | |
| 828 bufferraw[2] = &bufferraw2[24]; // V channel rows (8) | |
| 829 int yWidth = cinfo.output_width; | |
| 830 int yHeight = cinfo.output_height; | |
| 831 int yMaxH = yHeight - 1; | |
| 832 int v = cinfo.cur_comp_info[0]->v_samp_factor; | |
| 833 int uvMaxH = uvSize.height() - 1; | |
| 834 JSAMPROW outputY = static_cast<JSAMPROW>(planes[0]); | |
| 835 JSAMPROW outputU = static_cast<JSAMPROW>(planes[1]); | |
| 836 JSAMPROW outputV = static_cast<JSAMPROW>(planes[2]); | |
| 837 size_t rowBytesY = rowBytes[0]; | |
| 838 size_t rowBytesU = rowBytes[1]; | |
| 839 size_t rowBytesV = rowBytes[2]; | |
| 840 | |
| 841 int yScanlinesToRead = DCTSIZE * v; | |
| 842 SkAutoMalloc lastRowStorage(yWidth * 8); | |
| 843 JSAMPROW yLastRow = (JSAMPROW)lastRowStorage.get(); | |
| 844 JSAMPROW uLastRow = yLastRow + 2 * yWidth; | |
| 845 JSAMPROW vLastRow = uLastRow + 2 * yWidth; | |
| 846 JSAMPROW dummyRow = vLastRow + 2 * yWidth; | |
| 847 | |
| 848 while (cinfo.output_scanline < cinfo.output_height) { | |
| 849 // Request 8 or 16 scanlines: returns 0 or more scanlines. | |
| 850 bool hasYLastRow(false), hasUVLastRow(false); | |
| 851 // Assign 8 or 16 rows of memory to read the Y channel. | |
| 852 for (int i = 0; i < yScanlinesToRead; ++i) { | |
| 853 int scanline = (cinfo.output_scanline + i); | |
| 854 if (scanline < yMaxH) { | |
| 855 bufferraw2[i] = &outputY[scanline * rowBytesY]; | |
| 856 } else if (scanline == yMaxH) { | |
| 857 bufferraw2[i] = yLastRow; | |
| 858 hasYLastRow = true; | |
| 859 } else { | |
| 860 bufferraw2[i] = dummyRow; | |
| 861 } | |
| 862 } | |
| 863 int scaledScanline = cinfo.output_scanline / v; | |
| 864 // Assign 8 rows of memory to read the U and V channels. | |
| 865 for (int i = 0; i < 8; ++i) { | |
| 866 int scanline = (scaledScanline + i); | |
| 867 if (scanline < uvMaxH) { | |
| 868 bufferraw2[16 + i] = &outputU[scanline * rowBytesU]; | |
| 869 bufferraw2[24 + i] = &outputV[scanline * rowBytesV]; | |
| 870 } else if (scanline == uvMaxH) { | |
| 871 bufferraw2[16 + i] = uLastRow; | |
| 872 bufferraw2[24 + i] = vLastRow; | |
| 873 hasUVLastRow = true; | |
| 874 } else { | |
| 875 bufferraw2[16 + i] = dummyRow; | |
| 876 bufferraw2[24 + i] = dummyRow; | |
| 877 } | |
| 878 } | |
| 879 JDIMENSION scanlinesRead = jpeg_read_raw_data(&cinfo, bufferraw, yScanli
nesToRead); | |
| 880 | |
| 881 if (scanlinesRead == 0) | |
| 882 return false; | |
| 883 | |
| 884 if (hasYLastRow) { | |
| 885 memcpy(&outputY[yMaxH * rowBytesY], yLastRow, yWidth); | |
| 886 } | |
| 887 if (hasUVLastRow) { | |
| 888 memcpy(&outputU[uvMaxH * rowBytesU], uLastRow, uvSize.width()); | |
| 889 memcpy(&outputV[uvMaxH * rowBytesV], vLastRow, uvSize.width()); | |
| 890 } | |
| 891 } | |
| 892 | |
| 893 cinfo.output_scanline = SkMin32(cinfo.output_scanline, cinfo.output_height); | |
| 894 | |
| 895 return true; | |
| 896 } | |
| 897 | |
| 898 bool SkJPEGImageDecoder::onDecodeYUV8Planes(SkStream* stream, SkISize componentS
izes[3], | |
| 899 void* planes[3], size_t rowBytes[3], | |
| 900 SkYUVColorSpace* colorSpace) { | |
| 901 #ifdef TIME_DECODE | |
| 902 SkAutoTime atm("JPEG YUV8 Decode"); | |
| 903 #endif | |
| 904 | |
| 905 if (this->getSampleSize() != 1) { | |
| 906 return false; // Resizing not supported | |
| 907 } | |
| 908 | |
| 909 JPEGAutoClean autoClean; | |
| 910 | |
| 911 jpeg_decompress_struct cinfo; | |
| 912 skjpeg_source_mgr srcManager(stream, this); | |
| 913 | |
| 914 skjpeg_error_mgr errorManager; | |
| 915 set_error_mgr(&cinfo, &errorManager); | |
| 916 | |
| 917 // All objects need to be instantiated before this setjmp call so that | |
| 918 // they will be cleaned up properly if an error occurs. | |
| 919 if (setjmp(errorManager.fJmpBuf)) { | |
| 920 return return_false(cinfo, 0, 0, "setjmp"); | |
| 921 } | |
| 922 | |
| 923 initialize_info(&cinfo, &srcManager); | |
| 924 autoClean.set(&cinfo); | |
| 925 | |
| 926 int status = jpeg_read_header(&cinfo, true); | |
| 927 if (status != JPEG_HEADER_OK) { | |
| 928 return return_false(cinfo, 0, 0, "read_header"); | |
| 929 } | |
| 930 | |
| 931 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() | |
| 933 return false; | |
| 934 } | |
| 935 | |
| 936 cinfo.out_color_space = JCS_YCbCr; | |
| 937 cinfo.raw_data_out = TRUE; | |
| 938 | |
| 939 if (!planes || !planes[0] || !rowBytes || !rowBytes[0]) { // Compute size on
ly | |
| 940 update_components_sizes(cinfo, componentSizes, kSizeForMemoryAllocation_
SizeType); | |
| 941 return true; | |
| 942 } | |
| 943 | |
| 944 set_dct_method(*this, &cinfo); | |
| 945 | |
| 946 SkASSERT(1 == cinfo.scale_num); | |
| 947 cinfo.scale_denom = 1; | |
| 948 | |
| 949 turn_off_visual_optimizations(&cinfo); | |
| 950 | |
| 951 #ifdef ANDROID_RGB | |
| 952 cinfo.dither_mode = JDITHER_NONE; | |
| 953 #endif | |
| 954 | |
| 955 /* image_width and image_height are the original dimensions, available | |
| 956 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. | |
| 958 */ | |
| 959 if (!jpeg_start_decompress(&cinfo)) { | |
| 960 return return_false(cinfo, 0, 0, "start_decompress"); | |
| 961 } | |
| 962 | |
| 963 if (!output_raw_data(cinfo, planes, rowBytes)) { | |
| 964 return return_false(cinfo, 0, 0, "output_raw_data"); | |
| 965 } | |
| 966 | |
| 967 update_components_sizes(cinfo, componentSizes, kActualSize_SizeType); | |
| 968 jpeg_finish_decompress(&cinfo); | |
| 969 | |
| 970 if (NULL != colorSpace) { | |
| 971 *colorSpace = kJPEG_SkYUVColorSpace; | |
| 972 } | |
| 973 | |
| 974 return true; | |
| 975 } | |
| 976 | |
| 977 #ifdef SK_BUILD_FOR_ANDROID | 729 #ifdef SK_BUILD_FOR_ANDROID |
| 978 bool SkJPEGImageDecoder::onBuildTileIndex(SkStreamRewindable* stream, int *width
, int *height) { | 730 bool SkJPEGImageDecoder::onBuildTileIndex(SkStreamRewindable* stream, int *width
, int *height) { |
| 979 | 731 |
| 980 SkAutoTDelete<SkJPEGImageIndex> imageIndex(SkNEW_ARGS(SkJPEGImageIndex, (str
eam, this))); | 732 SkAutoTDelete<SkJPEGImageIndex> imageIndex(SkNEW_ARGS(SkJPEGImageIndex, (str
eam, this))); |
| 981 jpeg_decompress_struct* cinfo = imageIndex->cinfo(); | 733 jpeg_decompress_struct* cinfo = imageIndex->cinfo(); |
| 982 | 734 |
| 983 skjpeg_error_mgr sk_err; | 735 skjpeg_error_mgr sk_err; |
| 984 set_error_mgr(cinfo, &sk_err); | 736 set_error_mgr(cinfo, &sk_err); |
| 985 | 737 |
| 986 // All objects need to be instantiated before this setjmp call so that | 738 // 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; | 1233 return SkImageDecoder::kUnknown_Format; |
| 1482 } | 1234 } |
| 1483 | 1235 |
| 1484 static SkImageEncoder* sk_libjpeg_efactory(SkImageEncoder::Type t) { | 1236 static SkImageEncoder* sk_libjpeg_efactory(SkImageEncoder::Type t) { |
| 1485 return (SkImageEncoder::kJPEG_Type == t) ? SkNEW(SkJPEGImageEncoder) : NULL; | 1237 return (SkImageEncoder::kJPEG_Type == t) ? SkNEW(SkJPEGImageEncoder) : NULL; |
| 1486 } | 1238 } |
| 1487 | 1239 |
| 1488 static SkImageDecoder_DecodeReg gDReg(sk_libjpeg_dfactory); | 1240 static SkImageDecoder_DecodeReg gDReg(sk_libjpeg_dfactory); |
| 1489 static SkImageDecoder_FormatReg gFormatReg(get_format_jpeg); | 1241 static SkImageDecoder_FormatReg gFormatReg(get_format_jpeg); |
| 1490 static SkImageEncoder_EncodeReg gEReg(sk_libjpeg_efactory); | 1242 static SkImageEncoder_EncodeReg gEReg(sk_libjpeg_efactory); |
| OLD | NEW |