| 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 | 
|---|