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 "SkScaledBitmapSampler.h"
     15 #include "SkStream.h"
     16 #include "SkTemplates.h"
     17 #include "SkTime.h"
     18 #include "SkUtils.h"
     19 #include "SkRect.h"
     20 #include "SkCanvas.h"
     21 
     22 #include <stdio.h>
     23 extern "C" {
     24     #include "jpeglib.h"
     25     #include "jerror.h"
     26 }
     27 
     28 // These enable timing code that report milliseconds for an encoding/decoding
     29 //#define TIME_ENCODE
     30 //#define TIME_DECODE
     31 
     32 // this enables our rgb->yuv code, which is faster than libjpeg on ARM
     33 #define WE_CONVERT_TO_YUV
     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 //////////////////////////////////////////////////////////////////////////
     39 //////////////////////////////////////////////////////////////////////////
     40 
     41 static void overwrite_mem_buffer_size(jpeg_decompress_struct* cinfo) {
     42 #ifdef SK_BUILD_FOR_ANDROID
     43     /* Check if the device indicates that it has a large amount of system memory
     44      * if so, increase the memory allocation to 30MB instead of the default 5MB.
     45      */
     46 #ifdef ANDROID_LARGE_MEMORY_DEVICE
     47     cinfo->mem->max_memory_to_use = 30 * 1024 * 1024;
     48 #else
     49     cinfo->mem->max_memory_to_use = 5 * 1024 * 1024;
     50 #endif
     51 #endif // SK_BUILD_FOR_ANDROID
     52 }
     53 
     54 //////////////////////////////////////////////////////////////////////////
     55 //////////////////////////////////////////////////////////////////////////
     56 
     57 static void initialize_info(jpeg_decompress_struct* cinfo, skjpeg_source_mgr* src_mgr) {
     58     SkASSERT(cinfo != NULL);
     59     SkASSERT(src_mgr != NULL);
     60     jpeg_create_decompress(cinfo);
     61     overwrite_mem_buffer_size(cinfo);
     62     cinfo->src = src_mgr;
     63 }
     64 
     65 #ifdef SK_BUILD_FOR_ANDROID
     66 class SkJPEGImageIndex {
     67 public:
     68     SkJPEGImageIndex(SkStream* stream, SkImageDecoder* decoder)
     69         : fSrcMgr(stream, decoder)
     70         , fInfoInitialized(false)
     71         , fHuffmanCreated(false)
     72         , fDecompressStarted(false)
     73         {
     74             SkDEBUGCODE(fReadHeaderSucceeded = false;)
     75         }
     76 
     77     ~SkJPEGImageIndex() {
     78         if (fHuffmanCreated) {
     79             // Set to false before calling the libjpeg function, in case
     80             // the libjpeg function calls longjmp. Our setjmp handler may
     81             // attempt to delete this SkJPEGImageIndex, thus entering this
     82             // destructor again. Setting fHuffmanCreated to false first
     83             // prevents an infinite loop.
     84             fHuffmanCreated = false;
     85             jpeg_destroy_huffman_index(&fHuffmanIndex);
     86         }
     87         if (fDecompressStarted) {
     88             // Like fHuffmanCreated, set to false before calling libjpeg
     89             // function to prevent potential infinite loop.
     90             fDecompressStarted = false;
     91             jpeg_finish_decompress(&fCInfo);
     92         }
     93         if (fInfoInitialized) {
     94             this->destroyInfo();
     95         }
     96     }
     97 
     98     /**
     99      *  Destroy the cinfo struct.
    100      *  After this call, if a huffman index was already built, it
    101      *  can be used after calling initializeInfoAndReadHeader
    102      *  again. Must not be called after startTileDecompress except
    103      *  in the destructor.
    104      */
    105     void destroyInfo() {
    106         SkASSERT(fInfoInitialized);
    107         SkASSERT(!fDecompressStarted);
    108         // Like fHuffmanCreated, set to false before calling libjpeg
    109         // function to prevent potential infinite loop.
    110         fInfoInitialized = false;
    111         jpeg_destroy_decompress(&fCInfo);
    112         SkDEBUGCODE(fReadHeaderSucceeded = false;)
    113     }
    114 
    115     /**
    116      *  Initialize the cinfo struct.
    117      *  Calls jpeg_create_decompress, makes customizations, and
    118      *  finally calls jpeg_read_header. Returns true if jpeg_read_header
    119      *  returns JPEG_HEADER_OK.
    120      *  If cinfo was already initialized, destroyInfo must be called to
    121      *  destroy the old one. Must not be called after startTileDecompress.
    122      */
    123     bool initializeInfoAndReadHeader() {
    124         SkASSERT(!fInfoInitialized && !fDecompressStarted);
    125         initialize_info(&fCInfo, &fSrcMgr);
    126         fInfoInitialized = true;
    127         const bool success = (JPEG_HEADER_OK == jpeg_read_header(&fCInfo, true));
    128         SkDEBUGCODE(fReadHeaderSucceeded = success;)
    129         return success;
    130     }
    131 
    132     jpeg_decompress_struct* cinfo() { return &fCInfo; }
    133 
    134     huffman_index* huffmanIndex() { return &fHuffmanIndex; }
    135 
    136     /**
    137      *  Build the index to be used for tile based decoding.
    138      *  Must only be called after a successful call to
    139      *  initializeInfoAndReadHeader and must not be called more
    140      *  than once.
    141      */
    142     bool buildHuffmanIndex() {
    143         SkASSERT(fReadHeaderSucceeded);
    144         SkASSERT(!fHuffmanCreated);
    145         jpeg_create_huffman_index(&fCInfo, &fHuffmanIndex);
    146         fHuffmanCreated = true;
    147         SkASSERT(1 == fCInfo.scale_num && 1 == fCInfo.scale_denom);
    148         return jpeg_build_huffman_index(&fCInfo, &fHuffmanIndex);
    149     }
    150 
    151     /**
    152      *  Start tile based decoding. Must only be called after a
    153      *  successful call to buildHuffmanIndex, and must only be
    154      *  called once.
    155      */
    156     bool startTileDecompress() {
    157         SkASSERT(fHuffmanCreated);
    158         SkASSERT(fReadHeaderSucceeded);
    159         SkASSERT(!fDecompressStarted);
    160         if (jpeg_start_tile_decompress(&fCInfo)) {
    161             fDecompressStarted = true;
    162             return true;
    163         }
    164         return false;
    165     }
    166 
    167 private:
    168     skjpeg_source_mgr  fSrcMgr;
    169     jpeg_decompress_struct fCInfo;
    170     huffman_index fHuffmanIndex;
    171     bool fInfoInitialized;
    172     bool fHuffmanCreated;
    173     bool fDecompressStarted;
    174     SkDEBUGCODE(bool fReadHeaderSucceeded;)
    175 };
    176 #endif
    177 
    178 class SkJPEGImageDecoder : public SkImageDecoder {
    179 public:
    180 #ifdef SK_BUILD_FOR_ANDROID
    181     SkJPEGImageDecoder() {
    182         fImageIndex = NULL;
    183         fImageWidth = 0;
    184         fImageHeight = 0;
    185     }
    186 
    187     virtual ~SkJPEGImageDecoder() {
    188         SkDELETE(fImageIndex);
    189     }
    190 #endif
    191 
    192     virtual Format getFormat() const {
    193         return kJPEG_Format;
    194     }
    195 
    196 protected:
    197 #ifdef SK_BUILD_FOR_ANDROID
    198     virtual bool onBuildTileIndex(SkStream *stream, int *width, int *height) SK_OVERRIDE;
    199     virtual bool onDecodeSubset(SkBitmap* bitmap, const SkIRect& rect) SK_OVERRIDE;
    200 #endif
    201     virtual bool onDecode(SkStream* stream, SkBitmap* bm, Mode) SK_OVERRIDE;
    202 
    203 private:
    204 #ifdef SK_BUILD_FOR_ANDROID
    205     SkJPEGImageIndex* fImageIndex;
    206     int fImageWidth;
    207     int fImageHeight;
    208 #endif
    209 
    210     /**
    211      *  Determine the appropriate bitmap config and out_color_space based on
    212      *  both the preference of the caller and the jpeg_color_space on the
    213      *  jpeg_decompress_struct passed in.
    214      *  Must be called after jpeg_read_header.
    215      */
    216     SkBitmap::Config getBitmapConfig(jpeg_decompress_struct*);
    217 
    218     typedef SkImageDecoder INHERITED;
    219 };
    220 
    221 //////////////////////////////////////////////////////////////////////////
    222 
    223 /* Automatically clean up after throwing an exception */
    224 class JPEGAutoClean {
    225 public:
    226     JPEGAutoClean(): cinfo_ptr(NULL) {}
    227     ~JPEGAutoClean() {
    228         if (cinfo_ptr) {
    229             jpeg_destroy_decompress(cinfo_ptr);
    230         }
    231     }
    232     void set(jpeg_decompress_struct* info) {
    233         cinfo_ptr = info;
    234     }
    235 private:
    236     jpeg_decompress_struct* cinfo_ptr;
    237 };
    238 
    239 ///////////////////////////////////////////////////////////////////////////////
    240 
    241 /*  If we need to better match the request, we might examine the image and
    242      output dimensions, and determine if the downsampling jpeg provided is
    243      not sufficient. If so, we can recompute a modified sampleSize value to
    244      make up the difference.
    245 
    246      To skip this additional scaling, just set sampleSize = 1; below.
    247  */
    248 static int recompute_sampleSize(int sampleSize,
    249                                 const jpeg_decompress_struct& cinfo) {
    250     return sampleSize * cinfo.output_width / cinfo.image_width;
    251 }
    252 
    253 static bool valid_output_dimensions(const jpeg_decompress_struct& cinfo) {
    254     /* These are initialized to 0, so if they have non-zero values, we assume
    255        they are "valid" (i.e. have been computed by libjpeg)
    256      */
    257     return 0 != cinfo.output_width && 0 != cinfo.output_height;
    258 }
    259 
    260 static bool skip_src_rows(jpeg_decompress_struct* cinfo, void* buffer, int count) {
    261     for (int i = 0; i < count; i++) {
    262         JSAMPLE* rowptr = (JSAMPLE*)buffer;
    263         int row_count = jpeg_read_scanlines(cinfo, &rowptr, 1);
    264         if (1 != row_count) {
    265             return false;
    266         }
    267     }
    268     return true;
    269 }
    270 
    271 #ifdef SK_BUILD_FOR_ANDROID
    272 static bool skip_src_rows_tile(jpeg_decompress_struct* cinfo,
    273                                huffman_index *index, void* buffer, int count) {
    274     for (int i = 0; i < count; i++) {
    275         JSAMPLE* rowptr = (JSAMPLE*)buffer;
    276         int row_count = jpeg_read_tile_scanline(cinfo, index, &rowptr);
    277         if (1 != row_count) {
    278             return false;
    279         }
    280     }
    281     return true;
    282 }
    283 #endif
    284 
    285 // This guy exists just to aid in debugging, as it allows debuggers to just
    286 // set a break-point in one place to see all error exists.
    287 static bool return_false(const jpeg_decompress_struct& cinfo,
    288                          const SkBitmap& bm, const char msg[]) {
    289 #ifdef SK_DEBUG
    290     SkDebugf("libjpeg error %d <%s> from %s [%d %d]\n", cinfo.err->msg_code,
    291              cinfo.err->jpeg_message_table[cinfo.err->msg_code], msg,
    292              bm.width(), bm.height());
    293 #endif
    294     return false;   // must always return false
    295 }
    296 
    297 // Convert a scanline of CMYK samples to RGBX in place. Note that this
    298 // method moves the "scanline" pointer in its processing
    299 static void convert_CMYK_to_RGB(uint8_t* scanline, unsigned int width) {
    300     // At this point we've received CMYK pixels from libjpeg. We
    301     // perform a crude conversion to RGB (based on the formulae
    302     // from easyrgb.com):
    303     //  CMYK -> CMY
    304     //    C = ( C * (1 - K) + K )      // for each CMY component
    305     //  CMY -> RGB
    306     //    R = ( 1 - C ) * 255          // for each RGB component
    307     // Unfortunately we are seeing inverted CMYK so all the original terms
    308     // are 1-. This yields:
    309     //  CMYK -> CMY
    310     //    C = ( (1-C) * (1 - (1-K) + (1-K) ) -> C = 1 - C*K
    311     // The conversion from CMY->RGB remains the same
    312     for (unsigned int x = 0; x < width; ++x, scanline += 4) {
    313         scanline[0] = SkMulDiv255Round(scanline[0], scanline[3]);
    314         scanline[1] = SkMulDiv255Round(scanline[1], scanline[3]);
    315         scanline[2] = SkMulDiv255Round(scanline[2], scanline[3]);
    316         scanline[3] = 255;
    317     }
    318 }
    319 
    320 /**
    321  *  Common code for setting the error manager.
    322  */
    323 static void set_error_mgr(jpeg_decompress_struct* cinfo, skjpeg_error_mgr* errorManager) {
    324     SkASSERT(cinfo != NULL);
    325     SkASSERT(errorManager != NULL);
    326     cinfo->err = jpeg_std_error(errorManager);
    327     errorManager->error_exit = skjpeg_error_exit;
    328 }
    329 
    330 /**
    331  *  Common code for turning off upsampling and smoothing. Turning these
    332  *  off helps performance without showing noticable differences in the
    333  *  resulting bitmap.
    334  */
    335 static void turn_off_visual_optimizations(jpeg_decompress_struct* cinfo) {
    336     SkASSERT(cinfo != NULL);
    337     /* this gives about 30% performance improvement. In theory it may
    338        reduce the visual quality, in practice I'm not seeing a difference
    339      */
    340     cinfo->do_fancy_upsampling = 0;
    341 
    342     /* this gives another few percents */
    343     cinfo->do_block_smoothing = 0;
    344 }
    345 
    346 /**
    347  * Common code for setting the dct method.
    348  */
    349 static void set_dct_method(const SkImageDecoder& decoder, jpeg_decompress_struct* cinfo) {
    350     SkASSERT(cinfo != NULL);
    351 #ifdef DCT_IFAST_SUPPORTED
    352     if (decoder.getPreferQualityOverSpeed()) {
    353         cinfo->dct_method = JDCT_ISLOW;
    354     } else {
    355         cinfo->dct_method = JDCT_IFAST;
    356     }
    357 #else
    358     cinfo->dct_method = JDCT_ISLOW;
    359 #endif
    360 }
    361 
    362 SkBitmap::Config SkJPEGImageDecoder::getBitmapConfig(jpeg_decompress_struct* cinfo) {
    363     SkASSERT(cinfo != NULL);
    364 
    365     SrcDepth srcDepth = k32Bit_SrcDepth;
    366     if (JCS_GRAYSCALE == cinfo->jpeg_color_space) {
    367         srcDepth = k8BitGray_SrcDepth;
    368     }
    369 
    370     SkBitmap::Config config = this->getPrefConfig(srcDepth, /*hasAlpha*/ false);
    371     switch (config) {
    372         case SkBitmap::kA8_Config:
    373             // Only respect A8 config if the original is grayscale,
    374             // in which case we will treat the grayscale as alpha
    375             // values.
    376             if (cinfo->jpeg_color_space != JCS_GRAYSCALE) {
    377                 config = SkBitmap::kARGB_8888_Config;
    378             }
    379             break;
    380         case SkBitmap::kARGB_8888_Config:
    381             // Fall through.
    382         case SkBitmap::kARGB_4444_Config:
    383             // Fall through.
    384         case SkBitmap::kRGB_565_Config:
    385             // These are acceptable destination configs.
    386             break;
    387         default:
    388             // Force all other configs to 8888.
    389             config = SkBitmap::kARGB_8888_Config;
    390             break;
    391     }
    392 
    393     switch (cinfo->jpeg_color_space) {
    394         case JCS_CMYK:
    395             // Fall through.
    396         case JCS_YCCK:
    397             // libjpeg cannot convert from CMYK or YCCK to RGB - here we set up
    398             // so libjpeg will give us CMYK samples back and we will later
    399             // manually convert them to RGB
    400             cinfo->out_color_space = JCS_CMYK;
    401             break;
    402         case JCS_GRAYSCALE:
    403             if (SkBitmap::kA8_Config == config) {
    404                 cinfo->out_color_space = JCS_GRAYSCALE;
    405                 break;
    406             }
    407             // The data is JCS_GRAYSCALE, but the caller wants some sort of RGB
    408             // config. Fall through to set to the default.
    409         default:
    410             cinfo->out_color_space = JCS_RGB;
    411             break;
    412     }
    413     return config;
    414 }
    415 
    416 #ifdef ANDROID_RGB
    417 /**
    418  *  Based on the config and dither mode, adjust out_color_space and
    419  *  dither_mode of cinfo.
    420  */
    421 static void adjust_out_color_space_and_dither(jpeg_decompress_struct* cinfo,
    422                                               SkBitmap::Config config,
    423                                               const SkImageDecoder& decoder) {
    424     SkASSERT(cinfo != NULL);
    425     cinfo->dither_mode = JDITHER_NONE;
    426     if (JCS_CMYK == cinfo->out_color_space) {
    427         return;
    428     }
    429     switch(config) {
    430         case SkBitmap::kARGB_8888_Config:
    431             cinfo->out_color_space = JCS_RGBA_8888;
    432             break;
    433         case SkBitmap::kRGB_565_Config:
    434             cinfo->out_color_space = JCS_RGB_565;
    435             if (decoder.getDitherImage()) {
    436                 cinfo->dither_mode = JDITHER_ORDERED;
    437             }
    438             break;
    439         default:
    440             break;
    441     }
    442 }
    443 #endif
    444 
    445 bool SkJPEGImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) {
    446 #ifdef TIME_DECODE
    447     SkAutoTime atm("JPEG Decode");
    448 #endif
    449 
    450     JPEGAutoClean autoClean;
    451 
    452     jpeg_decompress_struct  cinfo;
    453     skjpeg_source_mgr       srcManager(stream, this);
    454 
    455     skjpeg_error_mgr errorManager;
    456     set_error_mgr(&cinfo, &errorManager);
    457 
    458     // All objects need to be instantiated before this setjmp call so that
    459     // they will be cleaned up properly if an error occurs.
    460     if (setjmp(errorManager.fJmpBuf)) {
    461         return return_false(cinfo, *bm, "setjmp");
    462     }
    463 
    464     initialize_info(&cinfo, &srcManager);
    465     autoClean.set(&cinfo);
    466 
    467     int status = jpeg_read_header(&cinfo, true);
    468     if (status != JPEG_HEADER_OK) {
    469         return return_false(cinfo, *bm, "read_header");
    470     }
    471 
    472     /*  Try to fulfill the requested sampleSize. Since jpeg can do it (when it
    473         can) much faster that we, just use their num/denom api to approximate
    474         the size.
    475     */
    476     int sampleSize = this->getSampleSize();
    477 
    478     set_dct_method(*this, &cinfo);
    479 
    480     SkASSERT(1 == cinfo.scale_num);
    481     cinfo.scale_denom = sampleSize;
    482 
    483     turn_off_visual_optimizations(&cinfo);
    484 
    485     const SkBitmap::Config config = this->getBitmapConfig(&cinfo);
    486 
    487 #ifdef ANDROID_RGB
    488     adjust_out_color_space_and_dither(&cinfo, config, *this);
    489 #endif
    490 
    491     if (1 == sampleSize && SkImageDecoder::kDecodeBounds_Mode == mode) {
    492         bm->setConfig(config, cinfo.image_width, cinfo.image_height);
    493         bm->setIsOpaque(config != SkBitmap::kA8_Config);
    494         return true;
    495     }
    496 
    497     /*  image_width and image_height are the original dimensions, available
    498         after jpeg_read_header(). To see the scaled dimensions, we have to call
    499         jpeg_start_decompress(), and then read output_width and output_height.
    500     */
    501     if (!jpeg_start_decompress(&cinfo)) {
    502         /*  If we failed here, we may still have enough information to return
    503             to the caller if they just wanted (subsampled bounds). If sampleSize
    504             was 1, then we would have already returned. Thus we just check if
    505             we're in kDecodeBounds_Mode, and that we have valid output sizes.
    506 
    507             One reason to fail here is that we have insufficient stream data
    508             to complete the setup. However, output dimensions seem to get
    509             computed very early, which is why this special check can pay off.
    510          */
    511         if (SkImageDecoder::kDecodeBounds_Mode == mode && valid_output_dimensions(cinfo)) {
    512             SkScaledBitmapSampler smpl(cinfo.output_width, cinfo.output_height,
    513                                        recompute_sampleSize(sampleSize, cinfo));
    514             bm->setConfig(config, smpl.scaledWidth(), smpl.scaledHeight());
    515             bm->setIsOpaque(config != SkBitmap::kA8_Config);
    516             return true;
    517         } else {
    518             return return_false(cinfo, *bm, "start_decompress");
    519         }
    520     }
    521     sampleSize = recompute_sampleSize(sampleSize, cinfo);
    522 
    523     // should we allow the Chooser (if present) to pick a config for us???
    524     if (!this->chooseFromOneChoice(config, cinfo.output_width, cinfo.output_height)) {
    525         return return_false(cinfo, *bm, "chooseFromOneChoice");
    526     }
    527 
    528     SkScaledBitmapSampler sampler(cinfo.output_width, cinfo.output_height, sampleSize);
    529     bm->setConfig(config, sampler.scaledWidth(), sampler.scaledHeight());
    530     bm->setIsOpaque(config != SkBitmap::kA8_Config);
    531     if (SkImageDecoder::kDecodeBounds_Mode == mode) {
    532         return true;
    533     }
    534     if (!this->allocPixelRef(bm, NULL)) {
    535         return return_false(cinfo, *bm, "allocPixelRef");
    536     }
    537 
    538     SkAutoLockPixels alp(*bm);
    539 
    540 #ifdef ANDROID_RGB
    541     /* short-circuit the SkScaledBitmapSampler when possible, as this gives
    542        a significant performance boost.
    543     */
    544     if (sampleSize == 1 &&
    545         ((config == SkBitmap::kARGB_8888_Config &&
    546                 cinfo.out_color_space == JCS_RGBA_8888) ||
    547         (config == SkBitmap::kRGB_565_Config &&
    548                 cinfo.out_color_space == JCS_RGB_565)))
    549     {
    550         JSAMPLE* rowptr = (JSAMPLE*)bm->getPixels();
    551         INT32 const bpr =  bm->rowBytes();
    552 
    553         while (cinfo.output_scanline < cinfo.output_height) {
    554             int row_count = jpeg_read_scanlines(&cinfo, &rowptr, 1);
    555             // if row_count == 0, then we didn't get a scanline, so abort.
    556             // if we supported partial images, we might return true in this case
    557             if (0 == row_count) {
    558                 return return_false(cinfo, *bm, "read_scanlines");
    559             }
    560             if (this->shouldCancelDecode()) {
    561                 return return_false(cinfo, *bm, "shouldCancelDecode");
    562             }
    563             rowptr += bpr;
    564         }
    565         jpeg_finish_decompress(&cinfo);
    566         return true;
    567     }
    568 #endif
    569 
    570     // check for supported formats
    571     SkScaledBitmapSampler::SrcConfig sc;
    572     if (JCS_CMYK == cinfo.out_color_space) {
    573         // In this case we will manually convert the CMYK values to RGB
    574         sc = SkScaledBitmapSampler::kRGBX;
    575     } else if (3 == cinfo.out_color_components && JCS_RGB == cinfo.out_color_space) {
    576         sc = SkScaledBitmapSampler::kRGB;
    577 #ifdef ANDROID_RGB
    578     } else if (JCS_RGBA_8888 == cinfo.out_color_space) {
    579         sc = SkScaledBitmapSampler::kRGBX;
    580     } else if (JCS_RGB_565 == cinfo.out_color_space) {
    581         sc = SkScaledBitmapSampler::kRGB_565;
    582 #endif
    583     } else if (1 == cinfo.out_color_components &&
    584                JCS_GRAYSCALE == cinfo.out_color_space) {
    585         sc = SkScaledBitmapSampler::kGray;
    586     } else {
    587         return return_false(cinfo, *bm, "jpeg colorspace");
    588     }
    589 
    590     if (!sampler.begin(bm, sc, this->getDitherImage())) {
    591         return return_false(cinfo, *bm, "sampler.begin");
    592     }
    593 
    594     // The CMYK work-around relies on 4 components per pixel here
    595     SkAutoMalloc srcStorage(cinfo.output_width * 4);
    596     uint8_t* srcRow = (uint8_t*)srcStorage.get();
    597 
    598     //  Possibly skip initial rows [sampler.srcY0]
    599     if (!skip_src_rows(&cinfo, srcRow, sampler.srcY0())) {
    600         return return_false(cinfo, *bm, "skip rows");
    601     }
    602 
    603     // now loop through scanlines until y == bm->height() - 1
    604     for (int y = 0;; y++) {
    605         JSAMPLE* rowptr = (JSAMPLE*)srcRow;
    606         int row_count = jpeg_read_scanlines(&cinfo, &rowptr, 1);
    607         if (0 == row_count) {
    608             return return_false(cinfo, *bm, "read_scanlines");
    609         }
    610         if (this->shouldCancelDecode()) {
    611             return return_false(cinfo, *bm, "shouldCancelDecode");
    612         }
    613 
    614         if (JCS_CMYK == cinfo.out_color_space) {
    615             convert_CMYK_to_RGB(srcRow, cinfo.output_width);
    616         }
    617 
    618         sampler.next(srcRow);
    619         if (bm->height() - 1 == y) {
    620             // we're done
    621             break;
    622         }
    623 
    624         if (!skip_src_rows(&cinfo, srcRow, sampler.srcDY() - 1)) {
    625             return return_false(cinfo, *bm, "skip rows");
    626         }
    627     }
    628 
    629     // we formally skip the rest, so we don't get a complaint from libjpeg
    630     if (!skip_src_rows(&cinfo, srcRow,
    631                        cinfo.output_height - cinfo.output_scanline)) {
    632         return return_false(cinfo, *bm, "skip rows");
    633     }
    634     jpeg_finish_decompress(&cinfo);
    635 
    636     return true;
    637 }
    638 
    639 #ifdef SK_BUILD_FOR_ANDROID
    640 bool SkJPEGImageDecoder::onBuildTileIndex(SkStream* stream, int *width, int *height) {
    641 
    642     SkAutoTDelete<SkJPEGImageIndex> imageIndex(SkNEW_ARGS(SkJPEGImageIndex, (stream, this)));
    643     jpeg_decompress_struct* cinfo = imageIndex->cinfo();
    644 
    645     skjpeg_error_mgr sk_err;
    646     set_error_mgr(cinfo, &sk_err);
    647 
    648     // All objects need to be instantiated before this setjmp call so that
    649     // they will be cleaned up properly if an error occurs.
    650     if (setjmp(sk_err.fJmpBuf)) {
    651         return false;
    652     }
    653 
    654     // create the cinfo used to create/build the huffmanIndex
    655     if (!imageIndex->initializeInfoAndReadHeader()) {
    656         return false;
    657     }
    658 
    659     if (!imageIndex->buildHuffmanIndex()) {
    660         return false;
    661     }
    662 
    663     // destroy the cinfo used to create/build the huffman index
    664     imageIndex->destroyInfo();
    665 
    666     // Init decoder to image decode mode
    667     if (!imageIndex->initializeInfoAndReadHeader()) {
    668         return false;
    669     }
    670 
    671     // FIXME: This sets cinfo->out_color_space, which we may change later
    672     // based on the config in onDecodeSubset. This should be fine, since
    673     // jpeg_init_read_tile_scanline will check out_color_space again after
    674     // that change (when it calls jinit_color_deconverter).
    675     (void) this->getBitmapConfig(cinfo);
    676 
    677     turn_off_visual_optimizations(cinfo);
    678 
    679     // instead of jpeg_start_decompress() we start a tiled decompress
    680     if (!imageIndex->startTileDecompress()) {
    681         return false;
    682     }
    683 
    684     SkASSERT(1 == cinfo->scale_num);
    685     fImageWidth = cinfo->output_width;
    686     fImageHeight = cinfo->output_height;
    687 
    688     if (width) {
    689         *width = fImageWidth;
    690     }
    691     if (height) {
    692         *height = fImageHeight;
    693     }
    694 
    695     SkDELETE(fImageIndex);
    696     fImageIndex = imageIndex.detach();
    697 
    698     return true;
    699 }
    700 
    701 bool SkJPEGImageDecoder::onDecodeSubset(SkBitmap* bm, const SkIRect& region) {
    702     if (NULL == fImageIndex) {
    703         return false;
    704     }
    705     jpeg_decompress_struct* cinfo = fImageIndex->cinfo();
    706 
    707     SkIRect rect = SkIRect::MakeWH(fImageWidth, fImageHeight);
    708     if (!rect.intersect(region)) {
    709         // If the requested region is entirely outside the image return false
    710         return false;
    711     }
    712 
    713 
    714     skjpeg_error_mgr errorManager;
    715     set_error_mgr(cinfo, &errorManager);
    716 
    717     if (setjmp(errorManager.fJmpBuf)) {
    718         return false;
    719     }
    720 
    721     int requestedSampleSize = this->getSampleSize();
    722     cinfo->scale_denom = requestedSampleSize;
    723 
    724     set_dct_method(*this, cinfo);
    725 
    726     const SkBitmap::Config config = this->getBitmapConfig(cinfo);
    727 #ifdef ANDROID_RGB
    728     adjust_out_color_space_and_dither(cinfo, config, *this);
    729 #endif
    730 
    731     int startX = rect.fLeft;
    732     int startY = rect.fTop;
    733     int width = rect.width();
    734     int height = rect.height();
    735 
    736     jpeg_init_read_tile_scanline(cinfo, fImageIndex->huffmanIndex(),
    737                                  &startX, &startY, &width, &height);
    738     int skiaSampleSize = recompute_sampleSize(requestedSampleSize, *cinfo);
    739     int actualSampleSize = skiaSampleSize * (DCTSIZE / cinfo->min_DCT_scaled_size);
    740 
    741     SkScaledBitmapSampler sampler(width, height, skiaSampleSize);
    742 
    743     SkBitmap bitmap;
    744     bitmap.setConfig(config, sampler.scaledWidth(), sampler.scaledHeight());
    745     bitmap.setIsOpaque(true);
    746 
    747     // Check ahead of time if the swap(dest, src) is possible or not.
    748     // If yes, then we will stick to AllocPixelRef since it's cheaper with the
    749     // swap happening. If no, then we will use alloc to allocate pixels to
    750     // prevent garbage collection.
    751     int w = rect.width() / actualSampleSize;
    752     int h = rect.height() / actualSampleSize;
    753     bool swapOnly = (rect == region) && bm->isNull() &&
    754                     (w == bitmap.width()) && (h == bitmap.height()) &&
    755                     ((startX - rect.x()) / actualSampleSize == 0) &&
    756                     ((startY - rect.y()) / actualSampleSize == 0);
    757     if (swapOnly) {
    758         if (!this->allocPixelRef(&bitmap, NULL)) {
    759             return return_false(*cinfo, bitmap, "allocPixelRef");
    760         }
    761     } else {
    762         if (!bitmap.allocPixels()) {
    763             return return_false(*cinfo, bitmap, "allocPixels");
    764         }
    765     }
    766 
    767     SkAutoLockPixels alp(bitmap);
    768 
    769 #ifdef ANDROID_RGB
    770     /* short-circuit the SkScaledBitmapSampler when possible, as this gives
    771        a significant performance boost.
    772     */
    773     if (skiaSampleSize == 1 &&
    774         ((config == SkBitmap::kARGB_8888_Config &&
    775                 cinfo->out_color_space == JCS_RGBA_8888) ||
    776         (config == SkBitmap::kRGB_565_Config &&
    777                 cinfo->out_color_space == JCS_RGB_565)))
    778     {
    779         JSAMPLE* rowptr = (JSAMPLE*)bitmap.getPixels();
    780         INT32 const bpr = bitmap.rowBytes();
    781         int rowTotalCount = 0;
    782 
    783         while (rowTotalCount < height) {
    784             int rowCount = jpeg_read_tile_scanline(cinfo,
    785                                                    fImageIndex->huffmanIndex(),
    786                                                    &rowptr);
    787             // if row_count == 0, then we didn't get a scanline, so abort.
    788             // if we supported partial images, we might return true in this case
    789             if (0 == rowCount) {
    790                 return return_false(*cinfo, bitmap, "read_scanlines");
    791             }
    792             if (this->shouldCancelDecode()) {
    793                 return return_false(*cinfo, bitmap, "shouldCancelDecode");
    794             }
    795             rowTotalCount += rowCount;
    796             rowptr += bpr;
    797         }
    798 
    799         if (swapOnly) {
    800             bm->swap(bitmap);
    801         } else {
    802             cropBitmap(bm, &bitmap, actualSampleSize, region.x(), region.y(),
    803                        region.width(), region.height(), startX, startY);
    804         }
    805         return true;
    806     }
    807 #endif
    808 
    809     // check for supported formats
    810     SkScaledBitmapSampler::SrcConfig sc;
    811     if (JCS_CMYK == cinfo->out_color_space) {
    812         // In this case we will manually convert the CMYK values to RGB
    813         sc = SkScaledBitmapSampler::kRGBX;
    814     } else if (3 == cinfo->out_color_components && JCS_RGB == cinfo->out_color_space) {
    815         sc = SkScaledBitmapSampler::kRGB;
    816 #ifdef ANDROID_RGB
    817     } else if (JCS_RGBA_8888 == cinfo->out_color_space) {
    818         sc = SkScaledBitmapSampler::kRGBX;
    819     } else if (JCS_RGB_565 == cinfo->out_color_space) {
    820         sc = SkScaledBitmapSampler::kRGB_565;
    821 #endif
    822     } else if (1 == cinfo->out_color_components &&
    823                JCS_GRAYSCALE == cinfo->out_color_space) {
    824         sc = SkScaledBitmapSampler::kGray;
    825     } else {
    826         return return_false(*cinfo, *bm, "jpeg colorspace");
    827     }
    828 
    829     if (!sampler.begin(&bitmap, sc, this->getDitherImage())) {
    830         return return_false(*cinfo, bitmap, "sampler.begin");
    831     }
    832 
    833     // The CMYK work-around relies on 4 components per pixel here
    834     SkAutoMalloc  srcStorage(width * 4);
    835     uint8_t* srcRow = (uint8_t*)srcStorage.get();
    836 
    837     //  Possibly skip initial rows [sampler.srcY0]
    838     if (!skip_src_rows_tile(cinfo, fImageIndex->huffmanIndex(), srcRow, sampler.srcY0())) {
    839         return return_false(*cinfo, bitmap, "skip rows");
    840     }
    841 
    842     // now loop through scanlines until y == bitmap->height() - 1
    843     for (int y = 0;; y++) {
    844         JSAMPLE* rowptr = (JSAMPLE*)srcRow;
    845         int row_count = jpeg_read_tile_scanline(cinfo, fImageIndex->huffmanIndex(), &rowptr);
    846         if (0 == row_count) {
    847             return return_false(*cinfo, bitmap, "read_scanlines");
    848         }
    849         if (this->shouldCancelDecode()) {
    850             return return_false(*cinfo, bitmap, "shouldCancelDecode");
    851         }
    852 
    853         if (JCS_CMYK == cinfo->out_color_space) {
    854             convert_CMYK_to_RGB(srcRow, width);
    855         }
    856 
    857         sampler.next(srcRow);
    858         if (bitmap.height() - 1 == y) {
    859             // we're done
    860             break;
    861         }
    862 
    863         if (!skip_src_rows_tile(cinfo, fImageIndex->huffmanIndex(), srcRow,
    864                                 sampler.srcDY() - 1)) {
    865             return return_false(*cinfo, bitmap, "skip rows");
    866         }
    867     }
    868     if (swapOnly) {
    869         bm->swap(bitmap);
    870     } else {
    871         cropBitmap(bm, &bitmap, actualSampleSize, region.x(), region.y(),
    872                    region.width(), region.height(), startX, startY);
    873     }
    874     return true;
    875 }
    876 #endif
    877 
    878 ///////////////////////////////////////////////////////////////////////////////
    879 
    880 #include "SkColorPriv.h"
    881 
    882 // taken from jcolor.c in libjpeg
    883 #if 0   // 16bit - precise but slow
    884     #define CYR     19595   // 0.299
    885     #define CYG     38470   // 0.587
    886     #define CYB      7471   // 0.114
    887 
    888     #define CUR    -11059   // -0.16874
    889     #define CUG    -21709   // -0.33126
    890     #define CUB     32768   // 0.5
    891 
    892     #define CVR     32768   // 0.5
    893     #define CVG    -27439   // -0.41869
    894     #define CVB     -5329   // -0.08131
    895 
    896     #define CSHIFT  16
    897 #else      // 8bit - fast, slightly less precise
    898     #define CYR     77    // 0.299
    899     #define CYG     150    // 0.587
    900     #define CYB      29    // 0.114
    901 
    902     #define CUR     -43    // -0.16874
    903     #define CUG    -85    // -0.33126
    904     #define CUB     128    // 0.5
    905 
    906     #define CVR      128   // 0.5
    907     #define CVG     -107   // -0.41869
    908     #define CVB      -21   // -0.08131
    909 
    910     #define CSHIFT  8
    911 #endif
    912 
    913 static void rgb2yuv_32(uint8_t dst[], SkPMColor c) {
    914     int r = SkGetPackedR32(c);
    915     int g = SkGetPackedG32(c);
    916     int b = SkGetPackedB32(c);
    917 
    918     int  y = ( CYR*r + CYG*g + CYB*b ) >> CSHIFT;
    919     int  u = ( CUR*r + CUG*g + CUB*b ) >> CSHIFT;
    920     int  v = ( CVR*r + CVG*g + CVB*b ) >> CSHIFT;
    921 
    922     dst[0] = SkToU8(y);
    923     dst[1] = SkToU8(u + 128);
    924     dst[2] = SkToU8(v + 128);
    925 }
    926 
    927 static void rgb2yuv_4444(uint8_t dst[], U16CPU c) {
    928     int r = SkGetPackedR4444(c);
    929     int g = SkGetPackedG4444(c);
    930     int b = SkGetPackedB4444(c);
    931 
    932     int  y = ( CYR*r + CYG*g + CYB*b ) >> (CSHIFT - 4);
    933     int  u = ( CUR*r + CUG*g + CUB*b ) >> (CSHIFT - 4);
    934     int  v = ( CVR*r + CVG*g + CVB*b ) >> (CSHIFT - 4);
    935 
    936     dst[0] = SkToU8(y);
    937     dst[1] = SkToU8(u + 128);
    938     dst[2] = SkToU8(v + 128);
    939 }
    940 
    941 static void rgb2yuv_16(uint8_t dst[], U16CPU c) {
    942     int r = SkGetPackedR16(c);
    943     int g = SkGetPackedG16(c);
    944     int b = SkGetPackedB16(c);
    945 
    946     int  y = ( 2*CYR*r + CYG*g + 2*CYB*b ) >> (CSHIFT - 2);
    947     int  u = ( 2*CUR*r + CUG*g + 2*CUB*b ) >> (CSHIFT - 2);
    948     int  v = ( 2*CVR*r + CVG*g + 2*CVB*b ) >> (CSHIFT - 2);
    949 
    950     dst[0] = SkToU8(y);
    951     dst[1] = SkToU8(u + 128);
    952     dst[2] = SkToU8(v + 128);
    953 }
    954 
    955 ///////////////////////////////////////////////////////////////////////////////
    956 
    957 typedef void (*WriteScanline)(uint8_t* SK_RESTRICT dst,
    958                               const void* SK_RESTRICT src, int width,
    959                               const SkPMColor* SK_RESTRICT ctable);
    960 
    961 static void Write_32_YUV(uint8_t* SK_RESTRICT dst,
    962                          const void* SK_RESTRICT srcRow, int width,
    963                          const SkPMColor*) {
    964     const uint32_t* SK_RESTRICT src = (const uint32_t*)srcRow;
    965     while (--width >= 0) {
    966 #ifdef WE_CONVERT_TO_YUV
    967         rgb2yuv_32(dst, *src++);
    968 #else
    969         uint32_t c = *src++;
    970         dst[0] = SkGetPackedR32(c);
    971         dst[1] = SkGetPackedG32(c);
    972         dst[2] = SkGetPackedB32(c);
    973 #endif
    974         dst += 3;
    975     }
    976 }
    977 
    978 static void Write_4444_YUV(uint8_t* SK_RESTRICT dst,
    979                            const void* SK_RESTRICT srcRow, int width,
    980                            const SkPMColor*) {
    981     const SkPMColor16* SK_RESTRICT src = (const SkPMColor16*)srcRow;
    982     while (--width >= 0) {
    983 #ifdef WE_CONVERT_TO_YUV
    984         rgb2yuv_4444(dst, *src++);
    985 #else
    986         SkPMColor16 c = *src++;
    987         dst[0] = SkPacked4444ToR32(c);
    988         dst[1] = SkPacked4444ToG32(c);
    989         dst[2] = SkPacked4444ToB32(c);
    990 #endif
    991         dst += 3;
    992     }
    993 }
    994 
    995 static void Write_16_YUV(uint8_t* SK_RESTRICT dst,
    996                          const void* SK_RESTRICT srcRow, int width,
    997                          const SkPMColor*) {
    998     const uint16_t* SK_RESTRICT src = (const uint16_t*)srcRow;
    999     while (--width >= 0) {
   1000 #ifdef WE_CONVERT_TO_YUV
   1001         rgb2yuv_16(dst, *src++);
   1002 #else
   1003         uint16_t c = *src++;
   1004         dst[0] = SkPacked16ToR32(c);
   1005         dst[1] = SkPacked16ToG32(c);
   1006         dst[2] = SkPacked16ToB32(c);
   1007 #endif
   1008         dst += 3;
   1009     }
   1010 }
   1011 
   1012 static void Write_Index_YUV(uint8_t* SK_RESTRICT dst,
   1013                             const void* SK_RESTRICT srcRow, int width,
   1014                             const SkPMColor* SK_RESTRICT ctable) {
   1015     const uint8_t* SK_RESTRICT src = (const uint8_t*)srcRow;
   1016     while (--width >= 0) {
   1017 #ifdef WE_CONVERT_TO_YUV
   1018         rgb2yuv_32(dst, ctable[*src++]);
   1019 #else
   1020         uint32_t c = ctable[*src++];
   1021         dst[0] = SkGetPackedR32(c);
   1022         dst[1] = SkGetPackedG32(c);
   1023         dst[2] = SkGetPackedB32(c);
   1024 #endif
   1025         dst += 3;
   1026     }
   1027 }
   1028 
   1029 static WriteScanline ChooseWriter(const SkBitmap& bm) {
   1030     switch (bm.config()) {
   1031         case SkBitmap::kARGB_8888_Config:
   1032             return Write_32_YUV;
   1033         case SkBitmap::kRGB_565_Config:
   1034             return Write_16_YUV;
   1035         case SkBitmap::kARGB_4444_Config:
   1036             return Write_4444_YUV;
   1037         case SkBitmap::kIndex8_Config:
   1038             return Write_Index_YUV;
   1039         default:
   1040             return NULL;
   1041     }
   1042 }
   1043 
   1044 class SkJPEGImageEncoder : public SkImageEncoder {
   1045 protected:
   1046     virtual bool onEncode(SkWStream* stream, const SkBitmap& bm, int quality) {
   1047 #ifdef TIME_ENCODE
   1048         SkAutoTime atm("JPEG Encode");
   1049 #endif
   1050 
   1051         SkAutoLockPixels alp(bm);
   1052         if (NULL == bm.getPixels()) {
   1053             return false;
   1054         }
   1055 
   1056         jpeg_compress_struct    cinfo;
   1057         skjpeg_error_mgr        sk_err;
   1058         skjpeg_destination_mgr  sk_wstream(stream);
   1059 
   1060         // allocate these before set call setjmp
   1061         SkAutoMalloc    oneRow;
   1062         SkAutoLockColors ctLocker;
   1063 
   1064         cinfo.err = jpeg_std_error(&sk_err);
   1065         sk_err.error_exit = skjpeg_error_exit;
   1066         if (setjmp(sk_err.fJmpBuf)) {
   1067             return false;
   1068         }
   1069 
   1070         // Keep after setjmp or mark volatile.
   1071         const WriteScanline writer = ChooseWriter(bm);
   1072         if (NULL == writer) {
   1073             return false;
   1074         }
   1075 
   1076         jpeg_create_compress(&cinfo);
   1077         cinfo.dest = &sk_wstream;
   1078         cinfo.image_width = bm.width();
   1079         cinfo.image_height = bm.height();
   1080         cinfo.input_components = 3;
   1081 #ifdef WE_CONVERT_TO_YUV
   1082         cinfo.in_color_space = JCS_YCbCr;
   1083 #else
   1084         cinfo.in_color_space = JCS_RGB;
   1085 #endif
   1086         cinfo.input_gamma = 1;
   1087 
   1088         jpeg_set_defaults(&cinfo);
   1089         jpeg_set_quality(&cinfo, quality, TRUE /* limit to baseline-JPEG values */);
   1090 #ifdef DCT_IFAST_SUPPORTED
   1091         cinfo.dct_method = JDCT_IFAST;
   1092 #endif
   1093 
   1094         jpeg_start_compress(&cinfo, TRUE);
   1095 
   1096         const int       width = bm.width();
   1097         uint8_t*        oneRowP = (uint8_t*)oneRow.reset(width * 3);
   1098 
   1099         const SkPMColor* colors = ctLocker.lockColors(bm);
   1100         const void*      srcRow = bm.getPixels();
   1101 
   1102         while (cinfo.next_scanline < cinfo.image_height) {
   1103             JSAMPROW row_pointer[1];    /* pointer to JSAMPLE row[s] */
   1104 
   1105             writer(oneRowP, srcRow, width, colors);
   1106             row_pointer[0] = oneRowP;
   1107             (void) jpeg_write_scanlines(&cinfo, row_pointer, 1);
   1108             srcRow = (const void*)((const char*)srcRow + bm.rowBytes());
   1109         }
   1110 
   1111         jpeg_finish_compress(&cinfo);
   1112         jpeg_destroy_compress(&cinfo);
   1113 
   1114         return true;
   1115     }
   1116 };
   1117 
   1118 ///////////////////////////////////////////////////////////////////////////////
   1119 DEFINE_DECODER_CREATOR(JPEGImageDecoder);
   1120 DEFINE_ENCODER_CREATOR(JPEGImageEncoder);
   1121 ///////////////////////////////////////////////////////////////////////////////
   1122 
   1123 static bool is_jpeg(SkStream* stream) {
   1124     static const unsigned char gHeader[] = { 0xFF, 0xD8, 0xFF };
   1125     static const size_t HEADER_SIZE = sizeof(gHeader);
   1126 
   1127     char buffer[HEADER_SIZE];
   1128     size_t len = stream->read(buffer, HEADER_SIZE);
   1129 
   1130     if (len != HEADER_SIZE) {
   1131         return false;   // can't read enough
   1132     }
   1133     if (memcmp(buffer, gHeader, HEADER_SIZE)) {
   1134         return false;
   1135     }
   1136     return true;
   1137 }
   1138 
   1139 #include "SkTRegistry.h"
   1140 
   1141 static SkImageDecoder* sk_libjpeg_dfactory(SkStream* stream) {
   1142     if (is_jpeg(stream)) {
   1143         return SkNEW(SkJPEGImageDecoder);
   1144     }
   1145     return NULL;
   1146 }
   1147 
   1148 static SkImageDecoder::Format get_format_jpeg(SkStream* stream) {
   1149     if (is_jpeg(stream)) {
   1150         return SkImageDecoder::kJPEG_Format;
   1151     }
   1152     return SkImageDecoder::kUnknown_Format;
   1153 }
   1154 
   1155 static SkImageEncoder* sk_libjpeg_efactory(SkImageEncoder::Type t) {
   1156     return (SkImageEncoder::kJPEG_Type == t) ? SkNEW(SkJPEGImageEncoder) : NULL;
   1157 }
   1158 
   1159 
   1160 static SkTRegistry<SkImageDecoder*, SkStream*> gDReg(sk_libjpeg_dfactory);
   1161 static SkTRegistry<SkImageDecoder::Format, SkStream*> gFormatReg(get_format_jpeg);
   1162 static SkTRegistry<SkImageEncoder*, SkImageEncoder::Type> gEReg(sk_libjpeg_efactory);
   1163