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