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