5eb827122f29e322cb7d20be8b35dcc841dd90d9
[platform/upstream/libSkiaSharp.git] / src / images / SkImageDecoder_libjpeg.cpp
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     // 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
209 private:
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
221 class SkJPEGImageDecoder : public SkImageDecoder {
222 public:
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 SK_OVERRIDE {
236         return kJPEG_Format;
237     }
238
239 protected:
240 #ifdef SK_BUILD_FOR_ANDROID
241     bool onBuildTileIndex(SkStreamRewindable *stream, int *width, int *height) SK_OVERRIDE;
242     bool onDecodeSubset(SkBitmap* bitmap, const SkIRect& rect) SK_OVERRIDE;
243 #endif
244     Result onDecode(SkStream* stream, SkBitmap* bm, Mode) SK_OVERRIDE;
245     virtual bool onDecodeYUV8Planes(SkStream* stream, SkISize componentSizes[3],
246                                     void* planes[3], size_t rowBytes[3],
247                                     SkYUVColorSpace* colorSpace) SK_OVERRIDE;
248
249 private:
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 */
270 class JPEGAutoClean {
271 public:
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     }
281 private:
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  */
294 static int recompute_sampleSize(int sampleSize,
295                                 const jpeg_decompress_struct& cinfo) {
296     return sampleSize * cinfo.output_width / cinfo.image_width;
297 }
298
299 static 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
306 static 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
318 static 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.
335 static 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
345 static 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
352 static 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
359 static 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
369 static 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  */
393 static 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  */
405 static 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  */
419 static 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
432 SkColorType 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  */
490 static 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. */
519 static 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  */
530 static 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
560 SkImageDecoder::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
756 enum SizeType {
757     kSizeForMemoryAllocation_SizeType,
758     kActualSize_SizeType
759 };
760
761 static 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
771 static 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
786 static 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
794 static 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
875 bool 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
962 bool 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
1026 bool 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         } else {
1129             cropBitmap(bm, &bitmap, actualSampleSize, region.x(), region.y(),
1130                        region.width(), region.height(), startX, startY);
1131         }
1132         return true;
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     } else {
1188         cropBitmap(bm, &bitmap, actualSampleSize, region.x(), region.y(),
1189                    region.width(), region.height(), startX, startY);
1190     }
1191     return true;
1192 }
1193 #endif
1194
1195 ///////////////////////////////////////////////////////////////////////////////
1196
1197 #include "SkColorPriv.h"
1198
1199 // taken from jcolor.c in libjpeg
1200 #if 0   // 16bit - precise but slow
1201     #define CYR     19595   // 0.299
1202     #define CYG     38470   // 0.587
1203     #define CYB      7471   // 0.114
1204
1205     #define CUR    -11059   // -0.16874
1206     #define CUG    -21709   // -0.33126
1207     #define CUB     32768   // 0.5
1208
1209     #define CVR     32768   // 0.5
1210     #define CVG    -27439   // -0.41869
1211     #define CVB     -5329   // -0.08131
1212
1213     #define CSHIFT  16
1214 #else      // 8bit - fast, slightly less precise
1215     #define CYR     77    // 0.299
1216     #define CYG     150    // 0.587
1217     #define CYB      29    // 0.114
1218
1219     #define CUR     -43    // -0.16874
1220     #define CUG    -85    // -0.33126
1221     #define CUB     128    // 0.5
1222
1223     #define CVR      128   // 0.5
1224     #define CVG     -107   // -0.41869
1225     #define CVB      -21   // -0.08131
1226
1227     #define CSHIFT  8
1228 #endif
1229
1230 static void rgb2yuv_32(uint8_t dst[], SkPMColor c) {
1231     int r = SkGetPackedR32(c);
1232     int g = SkGetPackedG32(c);
1233     int b = SkGetPackedB32(c);
1234
1235     int  y = ( CYR*r + CYG*g + CYB*b ) >> CSHIFT;
1236     int  u = ( CUR*r + CUG*g + CUB*b ) >> CSHIFT;
1237     int  v = ( CVR*r + CVG*g + CVB*b ) >> CSHIFT;
1238
1239     dst[0] = SkToU8(y);
1240     dst[1] = SkToU8(u + 128);
1241     dst[2] = SkToU8(v + 128);
1242 }
1243
1244 static void rgb2yuv_4444(uint8_t dst[], U16CPU c) {
1245     int r = SkGetPackedR4444(c);
1246     int g = SkGetPackedG4444(c);
1247     int b = SkGetPackedB4444(c);
1248
1249     int  y = ( CYR*r + CYG*g + CYB*b ) >> (CSHIFT - 4);
1250     int  u = ( CUR*r + CUG*g + CUB*b ) >> (CSHIFT - 4);
1251     int  v = ( CVR*r + CVG*g + CVB*b ) >> (CSHIFT - 4);
1252
1253     dst[0] = SkToU8(y);
1254     dst[1] = SkToU8(u + 128);
1255     dst[2] = SkToU8(v + 128);
1256 }
1257
1258 static void rgb2yuv_16(uint8_t dst[], U16CPU c) {
1259     int r = SkGetPackedR16(c);
1260     int g = SkGetPackedG16(c);
1261     int b = SkGetPackedB16(c);
1262
1263     int  y = ( 2*CYR*r + CYG*g + 2*CYB*b ) >> (CSHIFT - 2);
1264     int  u = ( 2*CUR*r + CUG*g + 2*CUB*b ) >> (CSHIFT - 2);
1265     int  v = ( 2*CVR*r + CVG*g + 2*CVB*b ) >> (CSHIFT - 2);
1266
1267     dst[0] = SkToU8(y);
1268     dst[1] = SkToU8(u + 128);
1269     dst[2] = SkToU8(v + 128);
1270 }
1271
1272 ///////////////////////////////////////////////////////////////////////////////
1273
1274 typedef void (*WriteScanline)(uint8_t* SK_RESTRICT dst,
1275                               const void* SK_RESTRICT src, int width,
1276                               const SkPMColor* SK_RESTRICT ctable);
1277
1278 static void Write_32_YUV(uint8_t* SK_RESTRICT dst,
1279                          const void* SK_RESTRICT srcRow, int width,
1280                          const SkPMColor*) {
1281     const uint32_t* SK_RESTRICT src = (const uint32_t*)srcRow;
1282     while (--width >= 0) {
1283 #ifdef WE_CONVERT_TO_YUV
1284         rgb2yuv_32(dst, *src++);
1285 #else
1286         uint32_t c = *src++;
1287         dst[0] = SkGetPackedR32(c);
1288         dst[1] = SkGetPackedG32(c);
1289         dst[2] = SkGetPackedB32(c);
1290 #endif
1291         dst += 3;
1292     }
1293 }
1294
1295 static void Write_4444_YUV(uint8_t* SK_RESTRICT dst,
1296                            const void* SK_RESTRICT srcRow, int width,
1297                            const SkPMColor*) {
1298     const SkPMColor16* SK_RESTRICT src = (const SkPMColor16*)srcRow;
1299     while (--width >= 0) {
1300 #ifdef WE_CONVERT_TO_YUV
1301         rgb2yuv_4444(dst, *src++);
1302 #else
1303         SkPMColor16 c = *src++;
1304         dst[0] = SkPacked4444ToR32(c);
1305         dst[1] = SkPacked4444ToG32(c);
1306         dst[2] = SkPacked4444ToB32(c);
1307 #endif
1308         dst += 3;
1309     }
1310 }
1311
1312 static void Write_16_YUV(uint8_t* SK_RESTRICT dst,
1313                          const void* SK_RESTRICT srcRow, int width,
1314                          const SkPMColor*) {
1315     const uint16_t* SK_RESTRICT src = (const uint16_t*)srcRow;
1316     while (--width >= 0) {
1317 #ifdef WE_CONVERT_TO_YUV
1318         rgb2yuv_16(dst, *src++);
1319 #else
1320         uint16_t c = *src++;
1321         dst[0] = SkPacked16ToR32(c);
1322         dst[1] = SkPacked16ToG32(c);
1323         dst[2] = SkPacked16ToB32(c);
1324 #endif
1325         dst += 3;
1326     }
1327 }
1328
1329 static void Write_Index_YUV(uint8_t* SK_RESTRICT dst,
1330                             const void* SK_RESTRICT srcRow, int width,
1331                             const SkPMColor* SK_RESTRICT ctable) {
1332     const uint8_t* SK_RESTRICT src = (const uint8_t*)srcRow;
1333     while (--width >= 0) {
1334 #ifdef WE_CONVERT_TO_YUV
1335         rgb2yuv_32(dst, ctable[*src++]);
1336 #else
1337         uint32_t c = ctable[*src++];
1338         dst[0] = SkGetPackedR32(c);
1339         dst[1] = SkGetPackedG32(c);
1340         dst[2] = SkGetPackedB32(c);
1341 #endif
1342         dst += 3;
1343     }
1344 }
1345
1346 static WriteScanline ChooseWriter(const SkBitmap& bm) {
1347     switch (bm.colorType()) {
1348         case kN32_SkColorType:
1349             return Write_32_YUV;
1350         case kRGB_565_SkColorType:
1351             return Write_16_YUV;
1352         case kARGB_4444_SkColorType:
1353             return Write_4444_YUV;
1354         case kIndex_8_SkColorType:
1355             return Write_Index_YUV;
1356         default:
1357             return NULL;
1358     }
1359 }
1360
1361 class SkJPEGImageEncoder : public SkImageEncoder {
1362 protected:
1363     virtual bool onEncode(SkWStream* stream, const SkBitmap& bm, int quality) {
1364 #ifdef TIME_ENCODE
1365         SkAutoTime atm("JPEG Encode");
1366 #endif
1367
1368         SkAutoLockPixels alp(bm);
1369         if (NULL == bm.getPixels()) {
1370             return false;
1371         }
1372
1373         jpeg_compress_struct    cinfo;
1374         skjpeg_error_mgr        sk_err;
1375         skjpeg_destination_mgr  sk_wstream(stream);
1376
1377         // allocate these before set call setjmp
1378         SkAutoMalloc    oneRow;
1379
1380         cinfo.err = jpeg_std_error(&sk_err);
1381         sk_err.error_exit = skjpeg_error_exit;
1382         if (setjmp(sk_err.fJmpBuf)) {
1383             return false;
1384         }
1385
1386         // Keep after setjmp or mark volatile.
1387         const WriteScanline writer = ChooseWriter(bm);
1388         if (NULL == writer) {
1389             return false;
1390         }
1391
1392         jpeg_create_compress(&cinfo);
1393         cinfo.dest = &sk_wstream;
1394         cinfo.image_width = bm.width();
1395         cinfo.image_height = bm.height();
1396         cinfo.input_components = 3;
1397 #ifdef WE_CONVERT_TO_YUV
1398         cinfo.in_color_space = JCS_YCbCr;
1399 #else
1400         cinfo.in_color_space = JCS_RGB;
1401 #endif
1402         cinfo.input_gamma = 1;
1403
1404         jpeg_set_defaults(&cinfo);
1405         jpeg_set_quality(&cinfo, quality, TRUE /* limit to baseline-JPEG values */);
1406 #ifdef DCT_IFAST_SUPPORTED
1407         cinfo.dct_method = JDCT_IFAST;
1408 #endif
1409
1410         jpeg_start_compress(&cinfo, TRUE);
1411
1412         const int       width = bm.width();
1413         uint8_t*        oneRowP = (uint8_t*)oneRow.reset(width * 3);
1414
1415         const SkPMColor* colors = bm.getColorTable() ? bm.getColorTable()->readColors() : NULL;
1416         const void*      srcRow = bm.getPixels();
1417
1418         while (cinfo.next_scanline < cinfo.image_height) {
1419             JSAMPROW row_pointer[1];    /* pointer to JSAMPLE row[s] */
1420
1421             writer(oneRowP, srcRow, width, colors);
1422             row_pointer[0] = oneRowP;
1423             (void) jpeg_write_scanlines(&cinfo, row_pointer, 1);
1424             srcRow = (const void*)((const char*)srcRow + bm.rowBytes());
1425         }
1426
1427         jpeg_finish_compress(&cinfo);
1428         jpeg_destroy_compress(&cinfo);
1429
1430         return true;
1431     }
1432 };
1433
1434 ///////////////////////////////////////////////////////////////////////////////
1435 DEFINE_DECODER_CREATOR(JPEGImageDecoder);
1436 DEFINE_ENCODER_CREATOR(JPEGImageEncoder);
1437 ///////////////////////////////////////////////////////////////////////////////
1438
1439 static bool is_jpeg(SkStreamRewindable* stream) {
1440     static const unsigned char gHeader[] = { 0xFF, 0xD8, 0xFF };
1441     static const size_t HEADER_SIZE = sizeof(gHeader);
1442
1443     char buffer[HEADER_SIZE];
1444     size_t len = stream->read(buffer, HEADER_SIZE);
1445
1446     if (len != HEADER_SIZE) {
1447         return false;   // can't read enough
1448     }
1449     if (memcmp(buffer, gHeader, HEADER_SIZE)) {
1450         return false;
1451     }
1452     return true;
1453 }
1454
1455
1456 static SkImageDecoder* sk_libjpeg_dfactory(SkStreamRewindable* stream) {
1457     if (is_jpeg(stream)) {
1458         return SkNEW(SkJPEGImageDecoder);
1459     }
1460     return NULL;
1461 }
1462
1463 static SkImageDecoder::Format get_format_jpeg(SkStreamRewindable* stream) {
1464     if (is_jpeg(stream)) {
1465         return SkImageDecoder::kJPEG_Format;
1466     }
1467     return SkImageDecoder::kUnknown_Format;
1468 }
1469
1470 static SkImageEncoder* sk_libjpeg_efactory(SkImageEncoder::Type t) {
1471     return (SkImageEncoder::kJPEG_Type == t) ? SkNEW(SkJPEGImageEncoder) : NULL;
1472 }
1473
1474 static SkImageDecoder_DecodeReg gDReg(sk_libjpeg_dfactory);
1475 static SkImageDecoder_FormatReg gFormatReg(get_format_jpeg);
1476 static SkImageEncoder_EncodeReg gEReg(sk_libjpeg_efactory);