Home | History | Annotate | Download | only in images
      1 /*
      2  * Copyright 2007 The Android Open Source Project
      3  *
      4  * Use of this source code is governed by a BSD-style license that can be
      5  * found in the LICENSE file.
      6  */
      7 
      8 
      9 #include "SkImageDecoder.h"
     10 #include "SkImageEncoder.h"
     11 #include "SkJpegUtility.h"
     12 #include "SkColorPriv.h"
     13 #include "SkDither.h"
     14 #include "SkMSAN.h"
     15 #include "SkScaledBitmapSampler.h"
     16 #include "SkStream.h"
     17 #include "SkTemplates.h"
     18 #include "SkTime.h"
     19 #include "SkUtils.h"
     20 #include "SkRTConf.h"
     21 #include "SkRect.h"
     22 #include "SkCanvas.h"
     23 
     24 
     25 #include <stdio.h>
     26 extern "C" {
     27     #include "jpeglib.h"
     28     #include "jerror.h"
     29 }
     30 
     31 // These enable timing code that report milliseconds for an encoding/decoding
     32 //#define TIME_ENCODE
     33 //#define TIME_DECODE
     34 
     35 // If ANDROID_RGB is defined by in the jpeg headers it indicates that jpeg offers
     36 // support for two additional formats (1) JCS_RGBA_8888 and (2) JCS_RGB_565.
     37 
     38 #define DEFAULT_FOR_SUPPRESS_JPEG_IMAGE_DECODER_WARNINGS true
     39 #define DEFAULT_FOR_SUPPRESS_JPEG_IMAGE_DECODER_ERRORS true
     40 SK_CONF_DECLARE(bool, c_suppressJPEGImageDecoderWarnings,
     41                 "images.jpeg.suppressDecoderWarnings",
     42                 DEFAULT_FOR_SUPPRESS_JPEG_IMAGE_DECODER_WARNINGS,
     43                 "Suppress most JPG warnings when calling decode functions.");
     44 SK_CONF_DECLARE(bool, c_suppressJPEGImageDecoderErrors,
     45                 "images.jpeg.suppressDecoderErrors",
     46                 DEFAULT_FOR_SUPPRESS_JPEG_IMAGE_DECODER_ERRORS,
     47                 "Suppress most JPG error messages when decode "
     48                 "function fails.");
     49 
     50 //////////////////////////////////////////////////////////////////////////
     51 //////////////////////////////////////////////////////////////////////////
     52 
     53 static void do_nothing_emit_message(jpeg_common_struct*, int) {
     54     /* do nothing */
     55 }
     56 static void do_nothing_output_message(j_common_ptr) {
     57     /* do nothing */
     58 }
     59 
     60 static void initialize_info(jpeg_decompress_struct* cinfo, skjpeg_source_mgr* src_mgr) {
     61     SkASSERT(cinfo != nullptr);
     62     SkASSERT(src_mgr != nullptr);
     63     jpeg_create_decompress(cinfo);
     64     cinfo->src = src_mgr;
     65     /* To suppress warnings with a SK_DEBUG binary, set the
     66      * environment variable "skia_images_jpeg_suppressDecoderWarnings"
     67      * to "true".  Inside a program that links to skia:
     68      * SK_CONF_SET("images.jpeg.suppressDecoderWarnings", true); */
     69     if (c_suppressJPEGImageDecoderWarnings) {
     70         cinfo->err->emit_message = &do_nothing_emit_message;
     71     }
     72     /* To suppress error messages with a SK_DEBUG binary, set the
     73      * environment variable "skia_images_jpeg_suppressDecoderErrors"
     74      * to "true".  Inside a program that links to skia:
     75      * SK_CONF_SET("images.jpeg.suppressDecoderErrors", true); */
     76     if (c_suppressJPEGImageDecoderErrors) {
     77         cinfo->err->output_message = &do_nothing_output_message;
     78     }
     79 }
     80 
     81 class SkJPEGImageDecoder : public SkImageDecoder {
     82 public:
     83 
     84     Format getFormat() const override {
     85         return kJPEG_Format;
     86     }
     87 
     88 protected:
     89     Result onDecode(SkStream* stream, SkBitmap* bm, Mode) override;
     90     bool onDecodeYUV8Planes(SkStream* stream, SkISize componentSizes[3],
     91                             void* planes[3], size_t rowBytes[3],
     92                             SkYUVColorSpace* colorSpace) override;
     93 
     94 private:
     95 
     96     /**
     97      *  Determine the appropriate bitmap colortype and out_color_space based on
     98      *  both the preference of the caller and the jpeg_color_space on the
     99      *  jpeg_decompress_struct passed in.
    100      *  Must be called after jpeg_read_header.
    101      */
    102     SkColorType getBitmapColorType(jpeg_decompress_struct*);
    103 
    104     typedef SkImageDecoder INHERITED;
    105 };
    106 
    107 //////////////////////////////////////////////////////////////////////////
    108 
    109 /* Automatically clean up after throwing an exception */
    110 class JPEGAutoClean {
    111 public:
    112     JPEGAutoClean(): cinfo_ptr(nullptr) {}
    113     ~JPEGAutoClean() {
    114         if (cinfo_ptr) {
    115             jpeg_destroy_decompress(cinfo_ptr);
    116         }
    117     }
    118     void set(jpeg_decompress_struct* info) {
    119         cinfo_ptr = info;
    120     }
    121 private:
    122     jpeg_decompress_struct* cinfo_ptr;
    123 };
    124 
    125 ///////////////////////////////////////////////////////////////////////////////
    126 
    127 /*  If we need to better match the request, we might examine the image and
    128      output dimensions, and determine if the downsampling jpeg provided is
    129      not sufficient. If so, we can recompute a modified sampleSize value to
    130      make up the difference.
    131 
    132      To skip this additional scaling, just set sampleSize = 1; below.
    133  */
    134 static int recompute_sampleSize(int sampleSize,
    135                                 const jpeg_decompress_struct& cinfo) {
    136     return sampleSize * cinfo.output_width / cinfo.image_width;
    137 }
    138 
    139 static bool valid_output_dimensions(const jpeg_decompress_struct& cinfo) {
    140     /* These are initialized to 0, so if they have non-zero values, we assume
    141        they are "valid" (i.e. have been computed by libjpeg)
    142      */
    143     return 0 != cinfo.output_width && 0 != cinfo.output_height;
    144 }
    145 
    146 static bool skip_src_rows(jpeg_decompress_struct* cinfo, void* buffer, int count) {
    147     for (int i = 0; i < count; i++) {
    148         JSAMPLE* rowptr = (JSAMPLE*)buffer;
    149         int row_count = jpeg_read_scanlines(cinfo, &rowptr, 1);
    150         if (1 != row_count) {
    151             return false;
    152         }
    153     }
    154     return true;
    155 }
    156 
    157 ///////////////////////////////////////////////////////////////////////////////
    158 
    159 // This guy exists just to aid in debugging, as it allows debuggers to just
    160 // set a break-point in one place to see all error exists.
    161 static void print_jpeg_decoder_errors(const jpeg_decompress_struct& cinfo,
    162                          int width, int height, const char caller[]) {
    163     if (!(c_suppressJPEGImageDecoderErrors)) {
    164         char buffer[JMSG_LENGTH_MAX];
    165         cinfo.err->format_message((const j_common_ptr)&cinfo, buffer);
    166         SkDebugf("libjpeg error %d <%s> from %s [%d %d]\n",
    167                  cinfo.err->msg_code, buffer, caller, width, height);
    168     }
    169 }
    170 
    171 static bool return_false(const jpeg_decompress_struct& cinfo,
    172                          const char caller[]) {
    173     print_jpeg_decoder_errors(cinfo, 0, 0, caller);
    174     return false;
    175 }
    176 
    177 static SkImageDecoder::Result return_failure(const jpeg_decompress_struct& cinfo,
    178                                              const SkBitmap& bm, const char caller[]) {
    179     print_jpeg_decoder_errors(cinfo, bm.width(), bm.height(), caller);
    180     return SkImageDecoder::kFailure;
    181 }
    182 
    183 ///////////////////////////////////////////////////////////////////////////////
    184 
    185 // Convert a scanline of CMYK samples to RGBX in place. Note that this
    186 // method moves the "scanline" pointer in its processing
    187 static void convert_CMYK_to_RGB(uint8_t* scanline, unsigned int width) {
    188     // At this point we've received CMYK pixels from libjpeg. We
    189     // perform a crude conversion to RGB (based on the formulae
    190     // from easyrgb.com):
    191     //  CMYK -> CMY
    192     //    C = ( C * (1 - K) + K )      // for each CMY component
    193     //  CMY -> RGB
    194     //    R = ( 1 - C ) * 255          // for each RGB component
    195     // Unfortunately we are seeing inverted CMYK so all the original terms
    196     // are 1-. This yields:
    197     //  CMYK -> CMY
    198     //    C = ( (1-C) * (1 - (1-K) + (1-K) ) -> C = 1 - C*K
    199     // The conversion from CMY->RGB remains the same
    200     for (unsigned int x = 0; x < width; ++x, scanline += 4) {
    201         scanline[0] = SkMulDiv255Round(scanline[0], scanline[3]);
    202         scanline[1] = SkMulDiv255Round(scanline[1], scanline[3]);
    203         scanline[2] = SkMulDiv255Round(scanline[2], scanline[3]);
    204         scanline[3] = 255;
    205     }
    206 }
    207 
    208 /**
    209  *  Common code for setting the error manager.
    210  */
    211 static void set_error_mgr(jpeg_decompress_struct* cinfo, skjpeg_error_mgr* errorManager) {
    212     SkASSERT(cinfo != nullptr);
    213     SkASSERT(errorManager != nullptr);
    214     cinfo->err = jpeg_std_error(errorManager);
    215     errorManager->error_exit = skjpeg_error_exit;
    216 }
    217 
    218 /**
    219  * Common code for setting the dct method.
    220  */
    221 static void set_dct_method(const SkImageDecoder& decoder, jpeg_decompress_struct* cinfo) {
    222     SkASSERT(cinfo != nullptr);
    223     cinfo->dct_method = JDCT_ISLOW;
    224 }
    225 
    226 SkColorType SkJPEGImageDecoder::getBitmapColorType(jpeg_decompress_struct* cinfo) {
    227     SkASSERT(cinfo != nullptr);
    228 
    229     SrcDepth srcDepth = k32Bit_SrcDepth;
    230     if (JCS_GRAYSCALE == cinfo->jpeg_color_space) {
    231         srcDepth = k8BitGray_SrcDepth;
    232     }
    233 
    234     SkColorType colorType = this->getPrefColorType(srcDepth, /*hasAlpha*/ false);
    235     switch (colorType) {
    236         case kAlpha_8_SkColorType:
    237             // Only respect A8 colortype if the original is grayscale,
    238             // in which case we will treat the grayscale as alpha
    239             // values.
    240             if (cinfo->jpeg_color_space != JCS_GRAYSCALE) {
    241                 colorType = kN32_SkColorType;
    242             }
    243             break;
    244         case kN32_SkColorType:
    245             // Fall through.
    246         case kARGB_4444_SkColorType:
    247             // Fall through.
    248         case kRGB_565_SkColorType:
    249             // These are acceptable destination colortypes.
    250             break;
    251         default:
    252             // Force all other colortypes to 8888.
    253             colorType = kN32_SkColorType;
    254             break;
    255     }
    256 
    257     switch (cinfo->jpeg_color_space) {
    258         case JCS_CMYK:
    259             // Fall through.
    260         case JCS_YCCK:
    261             // libjpeg cannot convert from CMYK or YCCK to RGB - here we set up
    262             // so libjpeg will give us CMYK samples back and we will later
    263             // manually convert them to RGB
    264             cinfo->out_color_space = JCS_CMYK;
    265             break;
    266         case JCS_GRAYSCALE:
    267             if (kAlpha_8_SkColorType == colorType) {
    268                 cinfo->out_color_space = JCS_GRAYSCALE;
    269                 break;
    270             }
    271             // The data is JCS_GRAYSCALE, but the caller wants some sort of RGB
    272             // colortype. Fall through to set to the default.
    273         default:
    274             cinfo->out_color_space = JCS_RGB;
    275             break;
    276     }
    277     return colorType;
    278 }
    279 
    280 /**
    281  *  Based on the colortype and dither mode, adjust out_color_space and
    282  *  dither_mode of cinfo. Only does work in ANDROID_RGB
    283  */
    284 static void adjust_out_color_space_and_dither(jpeg_decompress_struct* cinfo,
    285                                               SkColorType colorType,
    286                                               const SkImageDecoder& decoder) {
    287     SkASSERT(cinfo != nullptr);
    288 #ifdef ANDROID_RGB
    289     cinfo->dither_mode = JDITHER_NONE;
    290     if (JCS_CMYK == cinfo->out_color_space) {
    291         return;
    292     }
    293     switch (colorType) {
    294         case kN32_SkColorType:
    295             cinfo->out_color_space = JCS_RGBA_8888;
    296             break;
    297         case kRGB_565_SkColorType:
    298             cinfo->out_color_space = JCS_RGB_565;
    299             if (decoder.getDitherImage()) {
    300                 cinfo->dither_mode = JDITHER_ORDERED;
    301             }
    302             break;
    303         default:
    304             break;
    305     }
    306 #endif
    307 }
    308 
    309 /**
    310    Sets all pixels in given bitmap to SK_ColorWHITE for all rows >= y.
    311    Used when decoding fails partway through reading scanlines to fill
    312    remaining lines. */
    313 static void fill_below_level(int y, SkBitmap* bitmap) {
    314     SkIRect rect = SkIRect::MakeLTRB(0, y, bitmap->width(), bitmap->height());
    315     SkCanvas canvas(*bitmap);
    316     canvas.clipRect(SkRect::Make(rect));
    317     canvas.drawColor(SK_ColorWHITE);
    318 }
    319 
    320 /**
    321  *  Get the config and bytes per pixel of the source data. Return
    322  *  whether the data is supported.
    323  */
    324 static bool get_src_config(const jpeg_decompress_struct& cinfo,
    325                            SkScaledBitmapSampler::SrcConfig* sc,
    326                            int* srcBytesPerPixel) {
    327     SkASSERT(sc != nullptr && srcBytesPerPixel != nullptr);
    328     if (JCS_CMYK == cinfo.out_color_space) {
    329         // In this case we will manually convert the CMYK values to RGB
    330         *sc = SkScaledBitmapSampler::kRGBX;
    331         // The CMYK work-around relies on 4 components per pixel here
    332         *srcBytesPerPixel = 4;
    333     } else if (3 == cinfo.out_color_components && JCS_RGB == cinfo.out_color_space) {
    334         *sc = SkScaledBitmapSampler::kRGB;
    335         *srcBytesPerPixel = 3;
    336 #ifdef ANDROID_RGB
    337     } else if (JCS_RGBA_8888 == cinfo.out_color_space) {
    338         *sc = SkScaledBitmapSampler::kRGBX;
    339         *srcBytesPerPixel = 4;
    340     } else if (JCS_RGB_565 == cinfo.out_color_space) {
    341         *sc = SkScaledBitmapSampler::kRGB_565;
    342         *srcBytesPerPixel = 2;
    343 #endif
    344     } else if (1 == cinfo.out_color_components &&
    345                JCS_GRAYSCALE == cinfo.out_color_space) {
    346         *sc = SkScaledBitmapSampler::kGray;
    347         *srcBytesPerPixel = 1;
    348     } else {
    349         return false;
    350     }
    351     return true;
    352 }
    353 
    354 SkImageDecoder::Result SkJPEGImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) {
    355 #ifdef TIME_DECODE
    356     SkAutoTime atm("JPEG Decode");
    357 #endif
    358 
    359     JPEGAutoClean autoClean;
    360 
    361     jpeg_decompress_struct  cinfo;
    362     skjpeg_source_mgr       srcManager(stream, this);
    363 
    364     skjpeg_error_mgr errorManager;
    365     set_error_mgr(&cinfo, &errorManager);
    366 
    367     // All objects need to be instantiated before this setjmp call so that
    368     // they will be cleaned up properly if an error occurs.
    369     if (setjmp(errorManager.fJmpBuf)) {
    370         return return_failure(cinfo, *bm, "setjmp");
    371     }
    372 
    373     initialize_info(&cinfo, &srcManager);
    374     autoClean.set(&cinfo);
    375 
    376     int status = jpeg_read_header(&cinfo, true);
    377     if (status != JPEG_HEADER_OK) {
    378         return return_failure(cinfo, *bm, "read_header");
    379     }
    380 
    381     /*  Try to fulfill the requested sampleSize. Since jpeg can do it (when it
    382         can) much faster that we, just use their num/denom api to approximate
    383         the size.
    384     */
    385     int sampleSize = this->getSampleSize();
    386 
    387     set_dct_method(*this, &cinfo);
    388 
    389     SkASSERT(1 == cinfo.scale_num);
    390     cinfo.scale_denom = sampleSize;
    391 
    392     const SkColorType colorType = this->getBitmapColorType(&cinfo);
    393     const SkAlphaType alphaType = kAlpha_8_SkColorType == colorType ?
    394                                       kPremul_SkAlphaType : kOpaque_SkAlphaType;
    395 
    396     adjust_out_color_space_and_dither(&cinfo, colorType, *this);
    397 
    398     if (1 == sampleSize && SkImageDecoder::kDecodeBounds_Mode == mode) {
    399         // Assume an A8 bitmap is not opaque to avoid the check of each
    400         // individual pixel. It is very unlikely to be opaque, since
    401         // an opaque A8 bitmap would not be very interesting.
    402         // Otherwise, a jpeg image is opaque.
    403         bool success = bm->setInfo(SkImageInfo::Make(cinfo.image_width, cinfo.image_height,
    404                                                      colorType, alphaType));
    405         return success ? kSuccess : kFailure;
    406     }
    407 
    408     /*  image_width and image_height are the original dimensions, available
    409         after jpeg_read_header(). To see the scaled dimensions, we have to call
    410         jpeg_start_decompress(), and then read output_width and output_height.
    411     */
    412     if (!jpeg_start_decompress(&cinfo)) {
    413         /*  If we failed here, we may still have enough information to return
    414             to the caller if they just wanted (subsampled bounds). If sampleSize
    415             was 1, then we would have already returned. Thus we just check if
    416             we're in kDecodeBounds_Mode, and that we have valid output sizes.
    417 
    418             One reason to fail here is that we have insufficient stream data
    419             to complete the setup. However, output dimensions seem to get
    420             computed very early, which is why this special check can pay off.
    421          */
    422         if (SkImageDecoder::kDecodeBounds_Mode == mode && valid_output_dimensions(cinfo)) {
    423             SkScaledBitmapSampler smpl(cinfo.output_width, cinfo.output_height,
    424                                        recompute_sampleSize(sampleSize, cinfo));
    425             // Assume an A8 bitmap is not opaque to avoid the check of each
    426             // individual pixel. It is very unlikely to be opaque, since
    427             // an opaque A8 bitmap would not be very interesting.
    428             // Otherwise, a jpeg image is opaque.
    429             bool success = bm->setInfo(SkImageInfo::Make(smpl.scaledWidth(), smpl.scaledHeight(),
    430                                                          colorType, alphaType));
    431             return success ? kSuccess : kFailure;
    432         } else {
    433             return return_failure(cinfo, *bm, "start_decompress");
    434         }
    435     }
    436     sampleSize = recompute_sampleSize(sampleSize, cinfo);
    437 
    438     SkScaledBitmapSampler sampler(cinfo.output_width, cinfo.output_height, sampleSize);
    439     // Assume an A8 bitmap is not opaque to avoid the check of each
    440     // individual pixel. It is very unlikely to be opaque, since
    441     // an opaque A8 bitmap would not be very interesting.
    442     // Otherwise, a jpeg image is opaque.
    443     bm->setInfo(SkImageInfo::Make(sampler.scaledWidth(), sampler.scaledHeight(),
    444                                   colorType, alphaType));
    445     if (SkImageDecoder::kDecodeBounds_Mode == mode) {
    446         return kSuccess;
    447     }
    448     if (!this->allocPixelRef(bm, nullptr)) {
    449         return return_failure(cinfo, *bm, "allocPixelRef");
    450     }
    451 
    452     SkAutoLockPixels alp(*bm);
    453 
    454 #ifdef ANDROID_RGB
    455     /* short-circuit the SkScaledBitmapSampler when possible, as this gives
    456        a significant performance boost.
    457     */
    458     if (sampleSize == 1 &&
    459         ((kN32_SkColorType == colorType && cinfo.out_color_space == JCS_RGBA_8888) ||
    460          (kRGB_565_SkColorType == colorType && cinfo.out_color_space == JCS_RGB_565)))
    461     {
    462         JSAMPLE* rowptr = (JSAMPLE*)bm->getPixels();
    463         INT32 const bpr =  bm->rowBytes();
    464 
    465         while (cinfo.output_scanline < cinfo.output_height) {
    466             int row_count = jpeg_read_scanlines(&cinfo, &rowptr, 1);
    467             if (0 == row_count) {
    468                 // if row_count == 0, then we didn't get a scanline,
    469                 // so return early.  We will return a partial image.
    470                 fill_below_level(cinfo.output_scanline, bm);
    471                 cinfo.output_scanline = cinfo.output_height;
    472                 jpeg_finish_decompress(&cinfo);
    473                 return kPartialSuccess;
    474             }
    475             if (this->shouldCancelDecode()) {
    476                 return return_failure(cinfo, *bm, "shouldCancelDecode");
    477             }
    478             rowptr += bpr;
    479         }
    480         jpeg_finish_decompress(&cinfo);
    481         return kSuccess;
    482     }
    483 #endif
    484 
    485     // check for supported formats
    486     SkScaledBitmapSampler::SrcConfig sc;
    487     int srcBytesPerPixel;
    488 
    489     if (!get_src_config(cinfo, &sc, &srcBytesPerPixel)) {
    490         return return_failure(cinfo, *bm, "jpeg colorspace");
    491     }
    492 
    493     if (!sampler.begin(bm, sc, *this)) {
    494         return return_failure(cinfo, *bm, "sampler.begin");
    495     }
    496 
    497     SkAutoTMalloc<uint8_t> srcStorage(cinfo.output_width * srcBytesPerPixel);
    498     uint8_t* srcRow = srcStorage.get();
    499 
    500     //  Possibly skip initial rows [sampler.srcY0]
    501     if (!skip_src_rows(&cinfo, srcRow, sampler.srcY0())) {
    502         return return_failure(cinfo, *bm, "skip rows");
    503     }
    504 
    505     // now loop through scanlines until y == bm->height() - 1
    506     for (int y = 0;; y++) {
    507         JSAMPLE* rowptr = (JSAMPLE*)srcRow;
    508         int row_count = jpeg_read_scanlines(&cinfo, &rowptr, 1);
    509         sk_msan_mark_initialized(srcRow, srcRow + cinfo.output_width * srcBytesPerPixel,
    510                                  "skbug.com/4550");
    511         if (0 == row_count) {
    512             // if row_count == 0, then we didn't get a scanline,
    513             // so return early.  We will return a partial image.
    514             fill_below_level(y, bm);
    515             cinfo.output_scanline = cinfo.output_height;
    516             jpeg_finish_decompress(&cinfo);
    517             return kPartialSuccess;
    518         }
    519         if (this->shouldCancelDecode()) {
    520             return return_failure(cinfo, *bm, "shouldCancelDecode");
    521         }
    522 
    523         if (JCS_CMYK == cinfo.out_color_space) {
    524             convert_CMYK_to_RGB(srcRow, cinfo.output_width);
    525         }
    526 
    527 
    528         sampler.next(srcRow);
    529         if (bm->height() - 1 == y) {
    530             // we're done
    531             break;
    532         }
    533 
    534         if (!skip_src_rows(&cinfo, srcRow, sampler.srcDY() - 1)) {
    535             return return_failure(cinfo, *bm, "skip rows");
    536         }
    537     }
    538 
    539     // we formally skip the rest, so we don't get a complaint from libjpeg
    540     if (!skip_src_rows(&cinfo, srcRow,
    541                        cinfo.output_height - cinfo.output_scanline)) {
    542         return return_failure(cinfo, *bm, "skip rows");
    543     }
    544     jpeg_finish_decompress(&cinfo);
    545 
    546     return kSuccess;
    547 }
    548 
    549 ///////////////////////////////////////////////////////////////////////////////
    550 
    551 enum SizeType {
    552     kSizeForMemoryAllocation_SizeType,
    553     kActualSize_SizeType
    554 };
    555 
    556 static SkISize compute_yuv_size(const jpeg_decompress_struct& info, int component,
    557                                 SizeType sizeType) {
    558     if (sizeType == kSizeForMemoryAllocation_SizeType) {
    559         return SkISize::Make(info.cur_comp_info[component]->width_in_blocks * DCTSIZE,
    560                              info.cur_comp_info[component]->height_in_blocks * DCTSIZE);
    561     }
    562     return SkISize::Make(info.cur_comp_info[component]->downsampled_width,
    563                          info.cur_comp_info[component]->downsampled_height);
    564 }
    565 
    566 static bool appears_to_be_yuv(const jpeg_decompress_struct& info) {
    567     return (info.jpeg_color_space == JCS_YCbCr)
    568         && (DCTSIZE == 8)
    569         && (info.num_components == 3)
    570         && (info.comps_in_scan >= info.num_components)
    571         && (info.scale_denom <= 8)
    572         && (info.cur_comp_info[0])
    573         && (info.cur_comp_info[1])
    574         && (info.cur_comp_info[2])
    575         && (info.cur_comp_info[1]->h_samp_factor == 1)
    576         && (info.cur_comp_info[1]->v_samp_factor == 1)
    577         && (info.cur_comp_info[2]->h_samp_factor == 1)
    578         && (info.cur_comp_info[2]->v_samp_factor == 1);
    579 }
    580 
    581 static void update_components_sizes(const jpeg_decompress_struct& cinfo, SkISize componentSizes[3],
    582                                     SizeType sizeType) {
    583     SkASSERT(appears_to_be_yuv(cinfo));
    584     for (int i = 0; i < 3; ++i) {
    585         componentSizes[i] = compute_yuv_size(cinfo, i, sizeType);
    586     }
    587 }
    588 
    589 static bool output_raw_data(jpeg_decompress_struct& cinfo, void* planes[3], size_t rowBytes[3]) {
    590     SkASSERT(appears_to_be_yuv(cinfo));
    591     // U size and V size have to be the same if we're calling output_raw_data()
    592     SkISize uvSize = compute_yuv_size(cinfo, 1, kSizeForMemoryAllocation_SizeType);
    593     SkASSERT(uvSize == compute_yuv_size(cinfo, 2, kSizeForMemoryAllocation_SizeType));
    594 
    595     JSAMPARRAY bufferraw[3];
    596     JSAMPROW bufferraw2[32];
    597     bufferraw[0] = &bufferraw2[0]; // Y channel rows (8 or 16)
    598     bufferraw[1] = &bufferraw2[16]; // U channel rows (8)
    599     bufferraw[2] = &bufferraw2[24]; // V channel rows (8)
    600     int yWidth = cinfo.output_width;
    601     int yHeight = cinfo.output_height;
    602     int yMaxH = yHeight - 1;
    603     int v = cinfo.cur_comp_info[0]->v_samp_factor;
    604     int uvMaxH = uvSize.height() - 1;
    605     JSAMPROW outputY = static_cast<JSAMPROW>(planes[0]);
    606     JSAMPROW outputU = static_cast<JSAMPROW>(planes[1]);
    607     JSAMPROW outputV = static_cast<JSAMPROW>(planes[2]);
    608     size_t rowBytesY = rowBytes[0];
    609     size_t rowBytesU = rowBytes[1];
    610     size_t rowBytesV = rowBytes[2];
    611 
    612     int yScanlinesToRead = DCTSIZE * v;
    613     SkAutoMalloc lastRowStorage(rowBytesY * 4);
    614     JSAMPROW yLastRow = (JSAMPROW)lastRowStorage.get();
    615     JSAMPROW uLastRow = yLastRow + rowBytesY;
    616     JSAMPROW vLastRow = uLastRow + rowBytesY;
    617     JSAMPROW dummyRow = vLastRow + rowBytesY;
    618 
    619     while (cinfo.output_scanline < cinfo.output_height) {
    620         // Request 8 or 16 scanlines: returns 0 or more scanlines.
    621         bool hasYLastRow(false), hasUVLastRow(false);
    622         // Assign 8 or 16 rows of memory to read the Y channel.
    623         for (int i = 0; i < yScanlinesToRead; ++i) {
    624             int scanline = (cinfo.output_scanline + i);
    625             if (scanline < yMaxH) {
    626                 bufferraw2[i] = &outputY[scanline * rowBytesY];
    627             } else if (scanline == yMaxH) {
    628                 bufferraw2[i] = yLastRow;
    629                 hasYLastRow = true;
    630             } else {
    631                 bufferraw2[i] = dummyRow;
    632             }
    633         }
    634         int scaledScanline = cinfo.output_scanline / v;
    635         // Assign 8 rows of memory to read the U and V channels.
    636         for (int i = 0; i < 8; ++i) {
    637             int scanline = (scaledScanline + i);
    638             if (scanline < uvMaxH) {
    639                 bufferraw2[16 + i] = &outputU[scanline * rowBytesU];
    640                 bufferraw2[24 + i] = &outputV[scanline * rowBytesV];
    641             } else if (scanline == uvMaxH) {
    642                 bufferraw2[16 + i] = uLastRow;
    643                 bufferraw2[24 + i] = vLastRow;
    644                 hasUVLastRow = true;
    645             } else {
    646                 bufferraw2[16 + i] = dummyRow;
    647                 bufferraw2[24 + i] = dummyRow;
    648             }
    649         }
    650         JDIMENSION scanlinesRead = jpeg_read_raw_data(&cinfo, bufferraw, yScanlinesToRead);
    651 
    652         if (scanlinesRead == 0) {
    653             return false;
    654         }
    655 
    656         if (hasYLastRow) {
    657             memcpy(&outputY[yMaxH * rowBytesY], yLastRow, yWidth);
    658         }
    659         if (hasUVLastRow) {
    660             memcpy(&outputU[uvMaxH * rowBytesU], uLastRow, uvSize.width());
    661             memcpy(&outputV[uvMaxH * rowBytesV], vLastRow, uvSize.width());
    662         }
    663     }
    664 
    665     cinfo.output_scanline = SkMin32(cinfo.output_scanline, cinfo.output_height);
    666 
    667     return true;
    668 }
    669 
    670 bool SkJPEGImageDecoder::onDecodeYUV8Planes(SkStream* stream, SkISize componentSizes[3],
    671                                             void* planes[3], size_t rowBytes[3],
    672                                             SkYUVColorSpace* colorSpace) {
    673 #ifdef TIME_DECODE
    674     SkAutoTime atm("JPEG YUV8 Decode");
    675 #endif
    676     if (this->getSampleSize() != 1) {
    677         return false; // Resizing not supported
    678     }
    679 
    680     JPEGAutoClean autoClean;
    681 
    682     jpeg_decompress_struct  cinfo;
    683     skjpeg_source_mgr       srcManager(stream, this);
    684 
    685     skjpeg_error_mgr errorManager;
    686     set_error_mgr(&cinfo, &errorManager);
    687 
    688     // All objects need to be instantiated before this setjmp call so that
    689     // they will be cleaned up properly if an error occurs.
    690     if (setjmp(errorManager.fJmpBuf)) {
    691         return return_false(cinfo, "setjmp YUV8");
    692     }
    693 
    694     initialize_info(&cinfo, &srcManager);
    695     autoClean.set(&cinfo);
    696 
    697     int status = jpeg_read_header(&cinfo, true);
    698     if (status != JPEG_HEADER_OK) {
    699         return return_false(cinfo, "read_header YUV8");
    700     }
    701 
    702     if (!appears_to_be_yuv(cinfo)) {
    703         // It's not an error to not be encoded in YUV, so no need to use return_false()
    704         return false;
    705     }
    706 
    707     cinfo.out_color_space = JCS_YCbCr;
    708     cinfo.raw_data_out = TRUE;
    709 
    710     if (!planes || !planes[0] || !rowBytes || !rowBytes[0]) { // Compute size only
    711         update_components_sizes(cinfo, componentSizes, kSizeForMemoryAllocation_SizeType);
    712         return true;
    713     }
    714 
    715     set_dct_method(*this, &cinfo);
    716 
    717     SkASSERT(1 == cinfo.scale_num);
    718     cinfo.scale_denom = 1;
    719 
    720 #ifdef ANDROID_RGB
    721     cinfo.dither_mode = JDITHER_NONE;
    722 #endif
    723 
    724     /*  image_width and image_height are the original dimensions, available
    725         after jpeg_read_header(). To see the scaled dimensions, we have to call
    726         jpeg_start_decompress(), and then read output_width and output_height.
    727     */
    728     if (!jpeg_start_decompress(&cinfo)) {
    729         return return_false(cinfo, "start_decompress YUV8");
    730     }
    731 
    732     // Seems like jpeg_start_decompress is updating our opinion of whether cinfo represents YUV.
    733     // Again, not really an error.
    734     if (!appears_to_be_yuv(cinfo)) {
    735         return false;
    736     }
    737 
    738     if (!output_raw_data(cinfo, planes, rowBytes)) {
    739         return return_false(cinfo, "output_raw_data");
    740     }
    741 
    742     update_components_sizes(cinfo, componentSizes, kActualSize_SizeType);
    743     jpeg_finish_decompress(&cinfo);
    744 
    745     if (nullptr != colorSpace) {
    746         *colorSpace = kJPEG_SkYUVColorSpace;
    747     }
    748 
    749     return true;
    750 }
    751 
    752 ///////////////////////////////////////////////////////////////////////////////
    753 
    754 typedef void (*WriteScanline)(uint8_t* SK_RESTRICT dst,
    755                               const void* SK_RESTRICT src, int width,
    756                               const SkPMColor* SK_RESTRICT ctable);
    757 
    758 static void Write_32_RGB(uint8_t* SK_RESTRICT dst,
    759                          const void* SK_RESTRICT srcRow, int width,
    760                          const SkPMColor*) {
    761     const uint32_t* SK_RESTRICT src = (const uint32_t*)srcRow;
    762     while (--width >= 0) {
    763         uint32_t c = *src++;
    764         dst[0] = SkGetPackedR32(c);
    765         dst[1] = SkGetPackedG32(c);
    766         dst[2] = SkGetPackedB32(c);
    767         dst += 3;
    768     }
    769 }
    770 
    771 static void Write_4444_RGB(uint8_t* SK_RESTRICT dst,
    772                            const void* SK_RESTRICT srcRow, int width,
    773                            const SkPMColor*) {
    774     const SkPMColor16* SK_RESTRICT src = (const SkPMColor16*)srcRow;
    775     while (--width >= 0) {
    776         SkPMColor16 c = *src++;
    777         dst[0] = SkPacked4444ToR32(c);
    778         dst[1] = SkPacked4444ToG32(c);
    779         dst[2] = SkPacked4444ToB32(c);
    780         dst += 3;
    781     }
    782 }
    783 
    784 static void Write_16_RGB(uint8_t* SK_RESTRICT dst,
    785                          const void* SK_RESTRICT srcRow, int width,
    786                          const SkPMColor*) {
    787     const uint16_t* SK_RESTRICT src = (const uint16_t*)srcRow;
    788     while (--width >= 0) {
    789         uint16_t c = *src++;
    790         dst[0] = SkPacked16ToR32(c);
    791         dst[1] = SkPacked16ToG32(c);
    792         dst[2] = SkPacked16ToB32(c);
    793         dst += 3;
    794     }
    795 }
    796 
    797 static void Write_Index_RGB(uint8_t* SK_RESTRICT dst,
    798                             const void* SK_RESTRICT srcRow, int width,
    799                             const SkPMColor* SK_RESTRICT ctable) {
    800     const uint8_t* SK_RESTRICT src = (const uint8_t*)srcRow;
    801     while (--width >= 0) {
    802         uint32_t c = ctable[*src++];
    803         dst[0] = SkGetPackedR32(c);
    804         dst[1] = SkGetPackedG32(c);
    805         dst[2] = SkGetPackedB32(c);
    806         dst += 3;
    807     }
    808 }
    809 
    810 static WriteScanline ChooseWriter(const SkBitmap& bm) {
    811     switch (bm.colorType()) {
    812         case kN32_SkColorType:
    813             return Write_32_RGB;
    814         case kRGB_565_SkColorType:
    815             return Write_16_RGB;
    816         case kARGB_4444_SkColorType:
    817             return Write_4444_RGB;
    818         case kIndex_8_SkColorType:
    819             return Write_Index_RGB;
    820         default:
    821             return nullptr;
    822     }
    823 }
    824 
    825 class SkJPEGImageEncoder : public SkImageEncoder {
    826 protected:
    827     virtual bool onEncode(SkWStream* stream, const SkBitmap& bm, int quality) {
    828 #ifdef TIME_ENCODE
    829         SkAutoTime atm("JPEG Encode");
    830 #endif
    831 
    832         SkAutoLockPixels alp(bm);
    833         if (nullptr == bm.getPixels()) {
    834             return false;
    835         }
    836 
    837         jpeg_compress_struct    cinfo;
    838         skjpeg_error_mgr        sk_err;
    839         skjpeg_destination_mgr  sk_wstream(stream);
    840 
    841         // allocate these before set call setjmp
    842         SkAutoTMalloc<uint8_t>  oneRow;
    843 
    844         cinfo.err = jpeg_std_error(&sk_err);
    845         sk_err.error_exit = skjpeg_error_exit;
    846         if (setjmp(sk_err.fJmpBuf)) {
    847             return false;
    848         }
    849 
    850         // Keep after setjmp or mark volatile.
    851         const WriteScanline writer = ChooseWriter(bm);
    852         if (nullptr == writer) {
    853             return false;
    854         }
    855 
    856         jpeg_create_compress(&cinfo);
    857         cinfo.dest = &sk_wstream;
    858         cinfo.image_width = bm.width();
    859         cinfo.image_height = bm.height();
    860         cinfo.input_components = 3;
    861         // FIXME: Can we take advantage of other in_color_spaces in libjpeg-turbo?
    862         cinfo.in_color_space = JCS_RGB;
    863 
    864         // The gamma value is ignored by libjpeg-turbo.
    865         cinfo.input_gamma = 1;
    866 
    867         jpeg_set_defaults(&cinfo);
    868 
    869         // Tells libjpeg-turbo to compute optimal Huffman coding tables
    870         // for the image.  This improves compression at the cost of
    871         // slower encode performance.
    872         cinfo.optimize_coding = TRUE;
    873         jpeg_set_quality(&cinfo, quality, TRUE /* limit to baseline-JPEG values */);
    874 
    875         jpeg_start_compress(&cinfo, TRUE);
    876 
    877         const int       width = bm.width();
    878         uint8_t*        oneRowP = oneRow.reset(width * 3);
    879 
    880         const SkPMColor* colors = bm.getColorTable() ? bm.getColorTable()->readColors() : nullptr;
    881         const void*      srcRow = bm.getPixels();
    882 
    883         while (cinfo.next_scanline < cinfo.image_height) {
    884             JSAMPROW row_pointer[1];    /* pointer to JSAMPLE row[s] */
    885 
    886             writer(oneRowP, srcRow, width, colors);
    887             row_pointer[0] = oneRowP;
    888             (void) jpeg_write_scanlines(&cinfo, row_pointer, 1);
    889             srcRow = (const void*)((const char*)srcRow + bm.rowBytes());
    890         }
    891 
    892         jpeg_finish_compress(&cinfo);
    893         jpeg_destroy_compress(&cinfo);
    894 
    895         return true;
    896     }
    897 };
    898 
    899 ///////////////////////////////////////////////////////////////////////////////
    900 DEFINE_DECODER_CREATOR(JPEGImageDecoder);
    901 DEFINE_ENCODER_CREATOR(JPEGImageEncoder);
    902 ///////////////////////////////////////////////////////////////////////////////
    903 
    904 static bool is_jpeg(SkStreamRewindable* stream) {
    905     static const unsigned char gHeader[] = { 0xFF, 0xD8, 0xFF };
    906     static const size_t HEADER_SIZE = sizeof(gHeader);
    907 
    908     char buffer[HEADER_SIZE];
    909     size_t len = stream->read(buffer, HEADER_SIZE);
    910 
    911     if (len != HEADER_SIZE) {
    912         return false;   // can't read enough
    913     }
    914     if (memcmp(buffer, gHeader, HEADER_SIZE)) {
    915         return false;
    916     }
    917     return true;
    918 }
    919 
    920 
    921 static SkImageDecoder* sk_libjpeg_dfactory(SkStreamRewindable* stream) {
    922     if (is_jpeg(stream)) {
    923         return new SkJPEGImageDecoder;
    924     }
    925     return nullptr;
    926 }
    927 
    928 static SkImageDecoder::Format get_format_jpeg(SkStreamRewindable* stream) {
    929     if (is_jpeg(stream)) {
    930         return SkImageDecoder::kJPEG_Format;
    931     }
    932     return SkImageDecoder::kUnknown_Format;
    933 }
    934 
    935 static SkImageEncoder* sk_libjpeg_efactory(SkImageEncoder::Type t) {
    936     return (SkImageEncoder::kJPEG_Type == t) ? new SkJPEGImageEncoder : nullptr;
    937 }
    938 
    939 static SkImageDecoder_DecodeReg gDReg(sk_libjpeg_dfactory);
    940 static SkImageDecoder_FormatReg gFormatReg(get_format_jpeg);
    941 static SkImageEncoder_EncodeReg gEReg(sk_libjpeg_efactory);
    942