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