1 /*
2  * Copyright 2015 Google Inc.
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 #include "src/codec/SkJpegCodec.h"
9 
10 #include "include/codec/SkCodec.h"
11 #include "include/core/SkStream.h"
12 #include "include/core/SkTypes.h"
13 #include "include/private/SkColorData.h"
14 #include "include/private/SkTemplates.h"
15 #include "include/private/SkTo.h"
16 #include "src/codec/SkCodecPriv.h"
17 #include "src/codec/SkJpegDecoderMgr.h"
18 #include "src/codec/SkParseEncodedOrigin.h"
19 
20 // stdio is needed for libjpeg-turbo
21 #include <stdio.h>
22 #include "src/codec/SkJpegUtility.h"
23 
24 // This warning triggers false postives way too often in here.
25 #if defined(__GNUC__) && !defined(__clang__)
26     #pragma GCC diagnostic ignored "-Wclobbered"
27 #endif
28 
29 extern "C" {
30     #include "jerror.h"
31     #include "jpeglib.h"
32 }
33 
IsJpeg(const void* buffer, size_t bytesRead)34 bool SkJpegCodec::IsJpeg(const void* buffer, size_t bytesRead) {
35     constexpr uint8_t jpegSig[] = { 0xFF, 0xD8, 0xFF };
36     return bytesRead >= 3 && !memcmp(buffer, jpegSig, sizeof(jpegSig));
37 }
38 
39 const uint32_t kExifHeaderSize = 14;
40 const uint32_t kExifMarker = JPEG_APP0 + 1;
41 const uint32_t kApp3Marker = JPEG_APP0 + 3;
42 const uint32_t kApp4Marker = JPEG_APP0 + 4;
43 const uint32_t kApp5Marker = JPEG_APP0 + 5;
44 const uint32_t kApp6Marker = JPEG_APP0 + 6;
45 const uint32_t kApp7Marker = JPEG_APP0 + 7;
46 const uint32_t kApp8Marker = JPEG_APP0 + 8;
47 const uint32_t kApp9Marker = JPEG_APP0 + 9;
48 const uint32_t kApp10Marker = JPEG_APP0 + 10;
49 const uint32_t kApp11Marker = JPEG_APP0 + 11;
50 const uint32_t kApp12Marker = JPEG_APP0 + 12;
51 const uint32_t kApp13Marker = JPEG_APP0 + 13;
52 const uint32_t kApp14Marker = JPEG_APP0 + 14;
53 const uint32_t kApp15Marker = JPEG_APP0 + 15;
54 
is_orientation_marker(jpeg_marker_struct* marker, SkEncodedOrigin* orientation)55 static bool is_orientation_marker(jpeg_marker_struct* marker, SkEncodedOrigin* orientation) {
56     if (kExifMarker != marker->marker || marker->data_length < kExifHeaderSize) {
57         return false;
58     }
59 
60     constexpr uint8_t kExifSig[] { 'E', 'x', 'i', 'f', '\0' };
61     if (0 != memcmp(marker->data, kExifSig, sizeof(kExifSig))) {
62         return false;
63     }
64 
65     // Account for 'E', 'x', 'i', 'f', '\0', '<fill byte>'.
66     constexpr size_t kOffset = 6;
67     return SkParseEncodedOrigin(marker->data + kOffset, marker->data_length - kOffset,
68             orientation);
69 }
70 
get_exif_orientation(jpeg_decompress_struct* dinfo)71 static SkEncodedOrigin get_exif_orientation(jpeg_decompress_struct* dinfo) {
72     SkEncodedOrigin orientation;
73     for (jpeg_marker_struct* marker = dinfo->marker_list; marker; marker = marker->next) {
74         if (is_orientation_marker(marker, &orientation)) {
75             return orientation;
76         }
77     }
78 
79     return kDefault_SkEncodedOrigin;
80 }
81 
is_icc_marker(jpeg_marker_struct* marker)82 static bool is_icc_marker(jpeg_marker_struct* marker) {
83     if (kICCMarker != marker->marker || marker->data_length < kICCMarkerHeaderSize) {
84         return false;
85     }
86 
87     return !memcmp(marker->data, kICCSig, sizeof(kICCSig));
88 }
89 
90 /*
91  * ICC profiles may be stored using a sequence of multiple markers.  We obtain the ICC profile
92  * in two steps:
93  *     (1) Discover all ICC profile markers and verify that they are numbered properly.
94  *     (2) Copy the data from each marker into a contiguous ICC profile.
95  */
read_color_profile(jpeg_decompress_struct* dinfo)96 static std::unique_ptr<SkEncodedInfo::ICCProfile> read_color_profile(jpeg_decompress_struct* dinfo)
97 {
98     // Note that 256 will be enough storage space since each markerIndex is stored in 8-bits.
99     jpeg_marker_struct* markerSequence[256];
100     memset(markerSequence, 0, sizeof(markerSequence));
101     uint8_t numMarkers = 0;
102     size_t totalBytes = 0;
103 
104     // Discover any ICC markers and verify that they are numbered properly.
105     for (jpeg_marker_struct* marker = dinfo->marker_list; marker; marker = marker->next) {
106         if (is_icc_marker(marker)) {
107             // Verify that numMarkers is valid and consistent.
108             if (0 == numMarkers) {
109                 numMarkers = marker->data[13];
110                 if (0 == numMarkers) {
111                     SkCodecPrintf("ICC Profile Error: numMarkers must be greater than zero.\n");
112                     return nullptr;
113                 }
114             } else if (numMarkers != marker->data[13]) {
115                 SkCodecPrintf("ICC Profile Error: numMarkers must be consistent.\n");
116                 return nullptr;
117             }
118 
119             // Verify that the markerIndex is valid and unique.  Note that zero is not
120             // a valid index.
121             uint8_t markerIndex = marker->data[12];
122             if (markerIndex == 0 || markerIndex > numMarkers) {
123                 SkCodecPrintf("ICC Profile Error: markerIndex is invalid.\n");
124                 return nullptr;
125             }
126             if (markerSequence[markerIndex]) {
127                 SkCodecPrintf("ICC Profile Error: Duplicate value of markerIndex.\n");
128                 return nullptr;
129             }
130             markerSequence[markerIndex] = marker;
131             SkASSERT(marker->data_length >= kICCMarkerHeaderSize);
132             totalBytes += marker->data_length - kICCMarkerHeaderSize;
133         }
134     }
135 
136     if (0 == totalBytes) {
137         // No non-empty ICC profile markers were found.
138         return nullptr;
139     }
140 
141     // Combine the ICC marker data into a contiguous profile.
142     sk_sp<SkData> iccData = SkData::MakeUninitialized(totalBytes);
143     void* dst = iccData->writable_data();
144     for (uint32_t i = 1; i <= numMarkers; i++) {
145         jpeg_marker_struct* marker = markerSequence[i];
146         if (!marker) {
147             SkCodecPrintf("ICC Profile Error: Missing marker %d of %d.\n", i, numMarkers);
148             return nullptr;
149         }
150 
151         void* src = SkTAddOffset<void>(marker->data, kICCMarkerHeaderSize);
152         size_t bytes = marker->data_length - kICCMarkerHeaderSize;
153         memcpy(dst, src, bytes);
154         dst = SkTAddOffset<void>(dst, bytes);
155     }
156 
157     return SkEncodedInfo::ICCProfile::Make(std::move(iccData));
158 }
159 
ReadHeader(SkStream* stream, SkCodec** codecOut, JpegDecoderMgr** decoderMgrOut, std::unique_ptr<SkEncodedInfo::ICCProfile> defaultColorProfile)160 SkCodec::Result SkJpegCodec::ReadHeader(SkStream* stream, SkCodec** codecOut,
161         JpegDecoderMgr** decoderMgrOut,
162         std::unique_ptr<SkEncodedInfo::ICCProfile> defaultColorProfile) {
163 
164     // Create a JpegDecoderMgr to own all of the decompress information
165     std::unique_ptr<JpegDecoderMgr> decoderMgr(new JpegDecoderMgr(stream));
166 
167     // libjpeg errors will be caught and reported here
168     skjpeg_error_mgr::AutoPushJmpBuf jmp(decoderMgr->errorMgr());
169     if (setjmp(jmp)) {
170         return decoderMgr->returnFailure("ReadHeader", kInvalidInput);
171     }
172 
173     // Initialize the decompress info and the source manager
174     decoderMgr->init();
175     auto* dinfo = decoderMgr->dinfo();
176 
177     // Instruct jpeg library to save the markers that we care about.  Since
178     // the orientation and color profile will not change, we can skip this
179     // step on rewinds.
180     if (codecOut) {
181         jpeg_save_markers(dinfo, kExifMarker, 0xFFFF);
182         jpeg_save_markers(dinfo, kICCMarker, 0xFFFF);
183         jpeg_save_markers(dinfo, JPEG_APP0, 0xFFFF);
184         jpeg_save_markers(dinfo, kApp3Marker, 0xFFFF);
185         jpeg_save_markers(dinfo, kApp4Marker, 0xFFFF);
186         jpeg_save_markers(dinfo, kApp5Marker, 0xFFFF);
187         jpeg_save_markers(dinfo, kApp6Marker, 0xFFFF);
188         jpeg_save_markers(dinfo, kApp7Marker, 0xFFFF);
189         jpeg_save_markers(dinfo, kApp8Marker, 0xFFFF);
190         jpeg_save_markers(dinfo, kApp9Marker, 0xFFFF);
191         jpeg_save_markers(dinfo, kApp10Marker, 0xFFFF);
192         jpeg_save_markers(dinfo, kApp11Marker, 0xFFFF);
193         jpeg_save_markers(dinfo, kApp12Marker, 0xFFFF);
194         jpeg_save_markers(dinfo, kApp13Marker, 0xFFFF);
195         jpeg_save_markers(dinfo, kApp14Marker, 0xFFFF);
196         jpeg_save_markers(dinfo, kApp15Marker, 0xFFFF);
197     }
198 
199     // Read the jpeg header
200     switch (jpeg_read_header(dinfo, true)) {
201         case JPEG_HEADER_OK:
202             break;
203         case JPEG_SUSPENDED:
204             return decoderMgr->returnFailure("ReadHeader", kIncompleteInput);
205         default:
206             return decoderMgr->returnFailure("ReadHeader", kInvalidInput);
207     }
208 
209     if (codecOut) {
210         // Get the encoded color type
211         SkEncodedInfo::Color color;
212         if (!decoderMgr->getEncodedColor(&color)) {
213             return kInvalidInput;
214         }
215 
216         SkEncodedOrigin orientation = get_exif_orientation(dinfo);
217         auto profile = read_color_profile(dinfo);
218         if (profile) {
219             auto type = profile->profile()->data_color_space;
220             switch (decoderMgr->dinfo()->jpeg_color_space) {
221                 case JCS_CMYK:
222                 case JCS_YCCK:
223                     if (type != skcms_Signature_CMYK) {
224                         profile = nullptr;
225                     }
226                     break;
227                 case JCS_GRAYSCALE:
228                     if (type != skcms_Signature_Gray &&
229                         type != skcms_Signature_RGB)
230                     {
231                         profile = nullptr;
232                     }
233                     break;
234                 default:
235                     if (type != skcms_Signature_RGB) {
236                         profile = nullptr;
237                     }
238                     break;
239             }
240         }
241         if (!profile) {
242             profile = std::move(defaultColorProfile);
243         }
244 
245         SkEncodedInfo info = SkEncodedInfo::Make(dinfo->image_width, dinfo->image_height,
246                                                  color, SkEncodedInfo::kOpaque_Alpha, 8,
247                                                  std::move(profile));
248 
249         SkJpegCodec* codec = new SkJpegCodec(std::move(info), std::unique_ptr<SkStream>(stream),
250                                              decoderMgr.release(), orientation);
251         *codecOut = codec;
252     } else {
253         SkASSERT(nullptr != decoderMgrOut);
254         *decoderMgrOut = decoderMgr.release();
255     }
256     return kSuccess;
257 }
258 
MakeFromStream(std::unique_ptr<SkStream> stream, Result* result)259 std::unique_ptr<SkCodec> SkJpegCodec::MakeFromStream(std::unique_ptr<SkStream> stream,
260                                                      Result* result) {
261     return SkJpegCodec::MakeFromStream(std::move(stream), result, nullptr);
262 }
263 
MakeFromStream(std::unique_ptr<SkStream> stream, Result* result, std::unique_ptr<SkEncodedInfo::ICCProfile> defaultColorProfile)264 std::unique_ptr<SkCodec> SkJpegCodec::MakeFromStream(std::unique_ptr<SkStream> stream,
265         Result* result, std::unique_ptr<SkEncodedInfo::ICCProfile> defaultColorProfile) {
266     SkCodec* codec = nullptr;
267     *result = ReadHeader(stream.get(), &codec, nullptr, std::move(defaultColorProfile));
268     if (kSuccess == *result) {
269         // Codec has taken ownership of the stream, we do not need to delete it
270         SkASSERT(codec);
271         stream.release();
272         return std::unique_ptr<SkCodec>(codec);
273     }
274     return nullptr;
275 }
276 
SkJpegCodec(SkEncodedInfo&& info, std::unique_ptr<SkStream> stream, JpegDecoderMgr* decoderMgr, SkEncodedOrigin origin)277 SkJpegCodec::SkJpegCodec(SkEncodedInfo&& info, std::unique_ptr<SkStream> stream,
278                          JpegDecoderMgr* decoderMgr, SkEncodedOrigin origin)
279     : INHERITED(std::move(info), skcms_PixelFormat_RGBA_8888, std::move(stream), origin)
280     , fDecoderMgr(decoderMgr)
281     , fReadyState(decoderMgr->dinfo()->global_state)
282     , fSwizzleSrcRow(nullptr)
283     , fColorXformSrcRow(nullptr)
284     , fSwizzlerSubset(SkIRect::MakeEmpty())
285 {}
286 
287 /*
288  * Return the row bytes of a particular image type and width
289  */
get_row_bytes(const j_decompress_ptr dinfo)290 static size_t get_row_bytes(const j_decompress_ptr dinfo) {
291     const size_t colorBytes = (dinfo->out_color_space == JCS_RGB565) ? 2 :
292             dinfo->out_color_components;
293     return dinfo->output_width * colorBytes;
294 
295 }
296 
297 /*
298  *  Calculate output dimensions based on the provided factors.
299  *
300  *  Not to be used on the actual jpeg_decompress_struct used for decoding, since it will
301  *  incorrectly modify num_components.
302  */
calc_output_dimensions(jpeg_decompress_struct* dinfo, unsigned int num, unsigned int denom)303 void calc_output_dimensions(jpeg_decompress_struct* dinfo, unsigned int num, unsigned int denom) {
304     dinfo->num_components = 0;
305     dinfo->scale_num = num;
306     dinfo->scale_denom = denom;
307     jpeg_calc_output_dimensions(dinfo);
308 }
309 
310 /*
311  * Return a valid set of output dimensions for this decoder, given an input scale
312  */
onGetScaledDimensions(float desiredScale) const313 SkISize SkJpegCodec::onGetScaledDimensions(float desiredScale) const {
314     // libjpeg-turbo supports scaling by 1/8, 1/4, 3/8, 1/2, 5/8, 3/4, 7/8, and 1/1, so we will
315     // support these as well
316     unsigned int num;
317     unsigned int denom = 8;
318     if (desiredScale >= 0.9375) {
319         num = 8;
320     } else if (desiredScale >= 0.8125) {
321         num = 7;
322     } else if (desiredScale >= 0.6875f) {
323         num = 6;
324     } else if (desiredScale >= 0.5625f) {
325         num = 5;
326     } else if (desiredScale >= 0.4375f) {
327         num = 4;
328     } else if (desiredScale >= 0.3125f) {
329         num = 3;
330     } else if (desiredScale >= 0.1875f) {
331         num = 2;
332     } else {
333         num = 1;
334     }
335 
336     // Set up a fake decompress struct in order to use libjpeg to calculate output dimensions
337     jpeg_decompress_struct dinfo;
338     sk_bzero(&dinfo, sizeof(dinfo));
339     dinfo.image_width = this->dimensions().width();
340     dinfo.image_height = this->dimensions().height();
341     dinfo.global_state = fReadyState;
342     calc_output_dimensions(&dinfo, num, denom);
343 
344     // Return the calculated output dimensions for the given scale
345     return SkISize::Make(dinfo.output_width, dinfo.output_height);
346 }
347 
onRewind()348 bool SkJpegCodec::onRewind() {
349     JpegDecoderMgr* decoderMgr = nullptr;
350     if (kSuccess != ReadHeader(this->stream(), nullptr, &decoderMgr, nullptr)) {
351         return fDecoderMgr->returnFalse("onRewind");
352     }
353     SkASSERT(nullptr != decoderMgr);
354     fDecoderMgr.reset(decoderMgr);
355 
356     fSwizzler.reset(nullptr);
357     fSwizzleSrcRow = nullptr;
358     fColorXformSrcRow = nullptr;
359     fStorage.reset();
360 
361     return true;
362 }
363 
conversionSupported(const SkImageInfo& dstInfo, bool srcIsOpaque, bool needsColorXform)364 bool SkJpegCodec::conversionSupported(const SkImageInfo& dstInfo, bool srcIsOpaque,
365                                       bool needsColorXform) {
366     SkASSERT(srcIsOpaque);
367 
368     if (kUnknown_SkAlphaType == dstInfo.alphaType()) {
369         return false;
370     }
371 
372     if (kOpaque_SkAlphaType != dstInfo.alphaType()) {
373         SkCodecPrintf("Warning: an opaque image should be decoded as opaque "
374                       "- it is being decoded as non-opaque, which will draw slower\n");
375     }
376 
377     J_COLOR_SPACE encodedColorType = fDecoderMgr->dinfo()->jpeg_color_space;
378 
379     // Check for valid color types and set the output color space
380     switch (dstInfo.colorType()) {
381         case kRGBA_8888_SkColorType:
382             fDecoderMgr->dinfo()->out_color_space = JCS_EXT_RGBA;
383             break;
384         case kBGRA_8888_SkColorType:
385             if (needsColorXform) {
386                 // Always using RGBA as the input format for color xforms makes the
387                 // implementation a little simpler.
388                 fDecoderMgr->dinfo()->out_color_space = JCS_EXT_RGBA;
389             } else {
390                 fDecoderMgr->dinfo()->out_color_space = JCS_EXT_BGRA;
391             }
392             break;
393         case kRGB_565_SkColorType:
394             if (needsColorXform) {
395                 fDecoderMgr->dinfo()->out_color_space = JCS_EXT_RGBA;
396             } else {
397                 fDecoderMgr->dinfo()->dither_mode = JDITHER_NONE;
398                 fDecoderMgr->dinfo()->out_color_space = JCS_RGB565;
399             }
400             break;
401         case kGray_8_SkColorType:
402             if (JCS_GRAYSCALE != encodedColorType) {
403                 return false;
404             }
405 
406             if (needsColorXform) {
407                 fDecoderMgr->dinfo()->out_color_space = JCS_EXT_RGBA;
408             } else {
409                 fDecoderMgr->dinfo()->out_color_space = JCS_GRAYSCALE;
410             }
411             break;
412         case kRGBA_F16_SkColorType:
413             SkASSERT(needsColorXform);
414             fDecoderMgr->dinfo()->out_color_space = JCS_EXT_RGBA;
415             break;
416         default:
417             return false;
418     }
419 
420     // Check if we will decode to CMYK.  libjpeg-turbo does not convert CMYK to RGBA, so
421     // we must do it ourselves.
422     if (JCS_CMYK == encodedColorType || JCS_YCCK == encodedColorType) {
423         fDecoderMgr->dinfo()->out_color_space = JCS_CMYK;
424     }
425 
426     return true;
427 }
428 
429 /*
430  * Checks if we can natively scale to the requested dimensions and natively scales the
431  * dimensions if possible
432  */
onDimensionsSupported(const SkISize& size)433 bool SkJpegCodec::onDimensionsSupported(const SkISize& size) {
434     skjpeg_error_mgr::AutoPushJmpBuf jmp(fDecoderMgr->errorMgr());
435     if (setjmp(jmp)) {
436         return fDecoderMgr->returnFalse("onDimensionsSupported");
437     }
438 
439     const unsigned int dstWidth = size.width();
440     const unsigned int dstHeight = size.height();
441 
442     // Set up a fake decompress struct in order to use libjpeg to calculate output dimensions
443     // FIXME: Why is this necessary?
444     jpeg_decompress_struct dinfo;
445     sk_bzero(&dinfo, sizeof(dinfo));
446     dinfo.image_width = this->dimensions().width();
447     dinfo.image_height = this->dimensions().height();
448     dinfo.global_state = fReadyState;
449 
450     // libjpeg-turbo can scale to 1/8, 1/4, 3/8, 1/2, 5/8, 3/4, 7/8, and 1/1
451     unsigned int num = 8;
452     const unsigned int denom = 8;
453     calc_output_dimensions(&dinfo, num, denom);
454     while (dinfo.output_width != dstWidth || dinfo.output_height != dstHeight) {
455 
456         // Return a failure if we have tried all of the possible scales
457         if (1 == num || dstWidth > dinfo.output_width || dstHeight > dinfo.output_height) {
458             return false;
459         }
460 
461         // Try the next scale
462         num -= 1;
463         calc_output_dimensions(&dinfo, num, denom);
464     }
465 
466     fDecoderMgr->dinfo()->scale_num = num;
467     fDecoderMgr->dinfo()->scale_denom = denom;
468     return true;
469 }
470 
readRows(const SkImageInfo& dstInfo, void* dst, size_t rowBytes, int count, const Options& opts)471 int SkJpegCodec::readRows(const SkImageInfo& dstInfo, void* dst, size_t rowBytes, int count,
472                           const Options& opts) {
473     // Set the jump location for libjpeg-turbo errors
474     skjpeg_error_mgr::AutoPushJmpBuf jmp(fDecoderMgr->errorMgr());
475     if (setjmp(jmp)) {
476         return 0;
477     }
478 
479     // When fSwizzleSrcRow is non-null, it means that we need to swizzle.  In this case,
480     // we will always decode into fSwizzlerSrcRow before swizzling into the next buffer.
481     // We can never swizzle "in place" because the swizzler may perform sampling and/or
482     // subsetting.
483     // When fColorXformSrcRow is non-null, it means that we need to color xform and that
484     // we cannot color xform "in place" (many times we can, but not when the src and dst
485     // are different sizes).
486     // In this case, we will color xform from fColorXformSrcRow into the dst.
487     JSAMPLE* decodeDst = (JSAMPLE*) dst;
488     uint32_t* swizzleDst = (uint32_t*) dst;
489     size_t decodeDstRowBytes = rowBytes;
490     size_t swizzleDstRowBytes = rowBytes;
491     int dstWidth = opts.fSubset ? opts.fSubset->width() : dstInfo.width();
492     if (fSwizzleSrcRow && fColorXformSrcRow) {
493         decodeDst = (JSAMPLE*) fSwizzleSrcRow;
494         swizzleDst = fColorXformSrcRow;
495         decodeDstRowBytes = 0;
496         swizzleDstRowBytes = 0;
497         dstWidth = fSwizzler->swizzleWidth();
498     } else if (fColorXformSrcRow) {
499         decodeDst = (JSAMPLE*) fColorXformSrcRow;
500         swizzleDst = fColorXformSrcRow;
501         decodeDstRowBytes = 0;
502         swizzleDstRowBytes = 0;
503     } else if (fSwizzleSrcRow) {
504         decodeDst = (JSAMPLE*) fSwizzleSrcRow;
505         decodeDstRowBytes = 0;
506         dstWidth = fSwizzler->swizzleWidth();
507     }
508 
509     for (int y = 0; y < count; y++) {
510         uint32_t lines = jpeg_read_scanlines(fDecoderMgr->dinfo(), &decodeDst, 1);
511         if (0 == lines) {
512             return y;
513         }
514 
515         if (fSwizzler) {
516             fSwizzler->swizzle(swizzleDst, decodeDst);
517         }
518 
519         if (this->colorXform()) {
520             this->applyColorXform(dst, swizzleDst, dstWidth);
521             dst = SkTAddOffset<void>(dst, rowBytes);
522         }
523 
524         decodeDst = SkTAddOffset<JSAMPLE>(decodeDst, decodeDstRowBytes);
525         swizzleDst = SkTAddOffset<uint32_t>(swizzleDst, swizzleDstRowBytes);
526     }
527 
528     return count;
529 }
530 
531 /*
532  * This is a bit tricky.  We only need the swizzler to do format conversion if the jpeg is
533  * encoded as CMYK.
534  * And even then we still may not need it.  If the jpeg has a CMYK color profile and a color
535  * xform, the color xform will handle the CMYK->RGB conversion.
536  */
needs_swizzler_to_convert_from_cmyk(J_COLOR_SPACE jpegColorType, const skcms_ICCProfile* srcProfile, bool hasColorSpaceXform)537 static inline bool needs_swizzler_to_convert_from_cmyk(J_COLOR_SPACE jpegColorType,
538                                                        const skcms_ICCProfile* srcProfile,
539                                                        bool hasColorSpaceXform) {
540     if (JCS_CMYK != jpegColorType) {
541         return false;
542     }
543 
544     bool hasCMYKColorSpace = srcProfile && srcProfile->data_color_space == skcms_Signature_CMYK;
545     return !hasCMYKColorSpace || !hasColorSpaceXform;
546 }
547 
548 /*
549  * Performs the jpeg decode
550  */
onGetPixels(const SkImageInfo& dstInfo, void* dst, size_t dstRowBytes, const Options& options, int* rowsDecoded)551 SkCodec::Result SkJpegCodec::onGetPixels(const SkImageInfo& dstInfo,
552                                          void* dst, size_t dstRowBytes,
553                                          const Options& options,
554                                          int* rowsDecoded) {
555     if (options.fSubset) {
556         // Subsets are not supported.
557         return kUnimplemented;
558     }
559 
560     // Get a pointer to the decompress info since we will use it quite frequently
561     jpeg_decompress_struct* dinfo = fDecoderMgr->dinfo();
562 
563     // Set the jump location for libjpeg errors
564     skjpeg_error_mgr::AutoPushJmpBuf jmp(fDecoderMgr->errorMgr());
565     if (setjmp(jmp)) {
566         return fDecoderMgr->returnFailure("setjmp", kInvalidInput);
567     }
568 
569     if (!jpeg_start_decompress(dinfo)) {
570         return fDecoderMgr->returnFailure("startDecompress", kInvalidInput);
571     }
572 
573     // The recommended output buffer height should always be 1 in high quality modes.
574     // If it's not, we want to know because it means our strategy is not optimal.
575     SkASSERT(1 == dinfo->rec_outbuf_height);
576 
577     if (needs_swizzler_to_convert_from_cmyk(dinfo->out_color_space,
578                                             this->getEncodedInfo().profile(), this->colorXform())) {
579         this->initializeSwizzler(dstInfo, options, true);
580     }
581 
582     if (!this->allocateStorage(dstInfo)) {
583         return kInternalError;
584     }
585 
586     int rows = this->readRows(dstInfo, dst, dstRowBytes, dstInfo.height(), options);
587     if (rows < dstInfo.height()) {
588         *rowsDecoded = rows;
589         return fDecoderMgr->returnFailure("Incomplete image data", kIncompleteInput);
590     }
591 
592     return kSuccess;
593 }
594 
allocateStorage(const SkImageInfo& dstInfo)595 bool SkJpegCodec::allocateStorage(const SkImageInfo& dstInfo) {
596     int dstWidth = dstInfo.width();
597 
598     size_t swizzleBytes = 0;
599     if (fSwizzler) {
600         swizzleBytes = get_row_bytes(fDecoderMgr->dinfo());
601         dstWidth = fSwizzler->swizzleWidth();
602         SkASSERT(!this->colorXform() || SkIsAlign4(swizzleBytes));
603     }
604 
605     size_t xformBytes = 0;
606 
607     if (this->colorXform() && sizeof(uint32_t) != dstInfo.bytesPerPixel()) {
608         xformBytes = dstWidth * sizeof(uint32_t);
609     }
610 
611     size_t totalBytes = swizzleBytes + xformBytes;
612     if (totalBytes > 0) {
613         if (!fStorage.reset(totalBytes)) {
614             return false;
615         }
616         fSwizzleSrcRow = (swizzleBytes > 0) ? fStorage.get() : nullptr;
617         fColorXformSrcRow = (xformBytes > 0) ?
618                 SkTAddOffset<uint32_t>(fStorage.get(), swizzleBytes) : nullptr;
619     }
620     return true;
621 }
622 
initializeSwizzler(const SkImageInfo& dstInfo, const Options& options, bool needsCMYKToRGB)623 void SkJpegCodec::initializeSwizzler(const SkImageInfo& dstInfo, const Options& options,
624         bool needsCMYKToRGB) {
625     Options swizzlerOptions = options;
626     if (options.fSubset) {
627         // Use fSwizzlerSubset if this is a subset decode.  This is necessary in the case
628         // where libjpeg-turbo provides a subset and then we need to subset it further.
629         // Also, verify that fSwizzlerSubset is initialized and valid.
630         SkASSERT(!fSwizzlerSubset.isEmpty() && fSwizzlerSubset.x() <= options.fSubset->x() &&
631                 fSwizzlerSubset.width() == options.fSubset->width());
632         swizzlerOptions.fSubset = &fSwizzlerSubset;
633     }
634 
635     SkImageInfo swizzlerDstInfo = dstInfo;
636     if (this->colorXform()) {
637         // The color xform will be expecting RGBA 8888 input.
638         swizzlerDstInfo = swizzlerDstInfo.makeColorType(kRGBA_8888_SkColorType);
639     }
640 
641     if (needsCMYKToRGB) {
642         // The swizzler is used to convert to from CMYK.
643         // The swizzler does not use the width or height on SkEncodedInfo.
644         auto swizzlerInfo = SkEncodedInfo::Make(0, 0, SkEncodedInfo::kInvertedCMYK_Color,
645                                                 SkEncodedInfo::kOpaque_Alpha, 8);
646         fSwizzler = SkSwizzler::Make(swizzlerInfo, nullptr, swizzlerDstInfo, swizzlerOptions);
647     } else {
648         int srcBPP = 0;
649         switch (fDecoderMgr->dinfo()->out_color_space) {
650             case JCS_EXT_RGBA:
651             case JCS_EXT_BGRA:
652             case JCS_CMYK:
653                 srcBPP = 4;
654                 break;
655             case JCS_RGB565:
656                 srcBPP = 2;
657                 break;
658             case JCS_GRAYSCALE:
659                 srcBPP = 1;
660                 break;
661             default:
662                 SkASSERT(false);
663                 break;
664         }
665         fSwizzler = SkSwizzler::MakeSimple(srcBPP, swizzlerDstInfo, swizzlerOptions);
666     }
667     SkASSERT(fSwizzler);
668 }
669 
getSampler(bool createIfNecessary)670 SkSampler* SkJpegCodec::getSampler(bool createIfNecessary) {
671     if (!createIfNecessary || fSwizzler) {
672         SkASSERT(!fSwizzler || (fSwizzleSrcRow && fStorage.get() == fSwizzleSrcRow));
673         return fSwizzler.get();
674     }
675 
676     bool needsCMYKToRGB = needs_swizzler_to_convert_from_cmyk(
677             fDecoderMgr->dinfo()->out_color_space, this->getEncodedInfo().profile(),
678             this->colorXform());
679     this->initializeSwizzler(this->dstInfo(), this->options(), needsCMYKToRGB);
680     if (!this->allocateStorage(this->dstInfo())) {
681         return nullptr;
682     }
683     return fSwizzler.get();
684 }
685 
onStartScanlineDecode(const SkImageInfo& dstInfo, const Options& options)686 SkCodec::Result SkJpegCodec::onStartScanlineDecode(const SkImageInfo& dstInfo,
687         const Options& options) {
688     // Set the jump location for libjpeg errors
689     skjpeg_error_mgr::AutoPushJmpBuf jmp(fDecoderMgr->errorMgr());
690     if (setjmp(jmp)) {
691         SkCodecPrintf("setjmp: Error from libjpeg\n");
692         return kInvalidInput;
693     }
694 
695     if (!jpeg_start_decompress(fDecoderMgr->dinfo())) {
696         SkCodecPrintf("start decompress failed\n");
697         return kInvalidInput;
698     }
699 
700     bool needsCMYKToRGB = needs_swizzler_to_convert_from_cmyk(
701             fDecoderMgr->dinfo()->out_color_space, this->getEncodedInfo().profile(),
702             this->colorXform());
703     if (options.fSubset) {
704         uint32_t startX = options.fSubset->x();
705         uint32_t width = options.fSubset->width();
706 
707         // libjpeg-turbo may need to align startX to a multiple of the IDCT
708         // block size.  If this is the case, it will decrease the value of
709         // startX to the appropriate alignment and also increase the value
710         // of width so that the right edge of the requested subset remains
711         // the same.
712         jpeg_crop_scanline(fDecoderMgr->dinfo(), &startX, &width);
713 
714         SkASSERT(startX <= (uint32_t) options.fSubset->x());
715         SkASSERT(width >= (uint32_t) options.fSubset->width());
716         SkASSERT(startX + width >= (uint32_t) options.fSubset->right());
717 
718         // Instruct the swizzler (if it is necessary) to further subset the
719         // output provided by libjpeg-turbo.
720         //
721         // We set this here (rather than in the if statement below), so that
722         // if (1) we don't need a swizzler for the subset, and (2) we need a
723         // swizzler for CMYK, the swizzler will still use the proper subset
724         // dimensions.
725         //
726         // Note that the swizzler will ignore the y and height parameters of
727         // the subset.  Since the scanline decoder (and the swizzler) handle
728         // one row at a time, only the subsetting in the x-dimension matters.
729         fSwizzlerSubset.setXYWH(options.fSubset->x() - startX, 0,
730                 options.fSubset->width(), options.fSubset->height());
731 
732         // We will need a swizzler if libjpeg-turbo cannot provide the exact
733         // subset that we request.
734         if (startX != (uint32_t) options.fSubset->x() ||
735                 width != (uint32_t) options.fSubset->width()) {
736             this->initializeSwizzler(dstInfo, options, needsCMYKToRGB);
737         }
738     }
739 
740     // Make sure we have a swizzler if we are converting from CMYK.
741     if (!fSwizzler && needsCMYKToRGB) {
742         this->initializeSwizzler(dstInfo, options, true);
743     }
744 
745     if (!this->allocateStorage(dstInfo)) {
746         return kInternalError;
747     }
748 
749     return kSuccess;
750 }
751 
onGetScanlines(void* dst, int count, size_t dstRowBytes)752 int SkJpegCodec::onGetScanlines(void* dst, int count, size_t dstRowBytes) {
753     int rows = this->readRows(this->dstInfo(), dst, dstRowBytes, count, this->options());
754     if (rows < count) {
755         // This allows us to skip calling jpeg_finish_decompress().
756         fDecoderMgr->dinfo()->output_scanline = this->dstInfo().height();
757     }
758 
759     return rows;
760 }
761 
onSkipScanlines(int count)762 bool SkJpegCodec::onSkipScanlines(int count) {
763     // Set the jump location for libjpeg errors
764     skjpeg_error_mgr::AutoPushJmpBuf jmp(fDecoderMgr->errorMgr());
765     if (setjmp(jmp)) {
766         return fDecoderMgr->returnFalse("onSkipScanlines");
767     }
768 
769     return (uint32_t) count == jpeg_skip_scanlines(fDecoderMgr->dinfo(), count);
770 }
771 
is_yuv_supported(const jpeg_decompress_struct* dinfo, const SkJpegCodec& codec, const SkYUVAPixmapInfo::SupportedDataTypes* supportedDataTypes, SkYUVAPixmapInfo* yuvaPixmapInfo)772 static bool is_yuv_supported(const jpeg_decompress_struct* dinfo,
773                              const SkJpegCodec& codec,
774                              const SkYUVAPixmapInfo::SupportedDataTypes* supportedDataTypes,
775                              SkYUVAPixmapInfo* yuvaPixmapInfo) {
776     // Scaling is not supported in raw data mode.
777     SkASSERT(dinfo->scale_num == dinfo->scale_denom);
778 
779     // I can't imagine that this would ever change, but we do depend on it.
780     static_assert(8 == DCTSIZE, "DCTSIZE (defined in jpeg library) should always be 8.");
781 
782     if (JCS_YCbCr != dinfo->jpeg_color_space) {
783         return false;
784     }
785 
786     SkASSERT(3 == dinfo->num_components);
787     SkASSERT(dinfo->comp_info);
788 
789     // It is possible to perform a YUV decode for any combination of
790     // horizontal and vertical sampling that is supported by
791     // libjpeg/libjpeg-turbo.  However, we will start by supporting only the
792     // common cases (where U and V have samp_factors of one).
793     //
794     // The definition of samp_factor is kind of the opposite of what SkCodec
795     // thinks of as a sampling factor.  samp_factor is essentially a
796     // multiplier, and the larger the samp_factor is, the more samples that
797     // there will be.  Ex:
798     //     U_plane_width = image_width * (U_h_samp_factor / max_h_samp_factor)
799     //
800     // Supporting cases where the samp_factors for U or V were larger than
801     // that of Y would be an extremely difficult change, given that clients
802     // allocate memory as if the size of the Y plane is always the size of the
803     // image.  However, this case is very, very rare.
804     if  ((1 != dinfo->comp_info[1].h_samp_factor) ||
805          (1 != dinfo->comp_info[1].v_samp_factor) ||
806          (1 != dinfo->comp_info[2].h_samp_factor) ||
807          (1 != dinfo->comp_info[2].v_samp_factor))
808     {
809         return false;
810     }
811 
812     // Support all common cases of Y samp_factors.
813     // TODO (msarett): As mentioned above, it would be possible to support
814     //                 more combinations of samp_factors.  The issues are:
815     //                 (1) Are there actually any images that are not covered
816     //                     by these cases?
817     //                 (2) How much complexity would be added to the
818     //                     implementation in order to support these rare
819     //                     cases?
820     int hSampY = dinfo->comp_info[0].h_samp_factor;
821     int vSampY = dinfo->comp_info[0].v_samp_factor;
822     SkASSERT(hSampY == dinfo->max_h_samp_factor);
823     SkASSERT(vSampY == dinfo->max_v_samp_factor);
824 
825     SkYUVAInfo::Subsampling tempSubsampling;
826     if        (1 == hSampY && 1 == vSampY) {
827         tempSubsampling = SkYUVAInfo::Subsampling::k444;
828     } else if (2 == hSampY && 1 == vSampY) {
829         tempSubsampling = SkYUVAInfo::Subsampling::k422;
830     } else if (2 == hSampY && 2 == vSampY) {
831         tempSubsampling = SkYUVAInfo::Subsampling::k420;
832     } else if (1 == hSampY && 2 == vSampY) {
833         tempSubsampling = SkYUVAInfo::Subsampling::k440;
834     } else if (4 == hSampY && 1 == vSampY) {
835         tempSubsampling = SkYUVAInfo::Subsampling::k411;
836     } else if (4 == hSampY && 2 == vSampY) {
837         tempSubsampling = SkYUVAInfo::Subsampling::k410;
838     } else {
839         return false;
840     }
841     if (supportedDataTypes &&
842         !supportedDataTypes->supported(SkYUVAInfo::PlaneConfig::kY_U_V,
843                                        SkYUVAPixmapInfo::DataType::kUnorm8)) {
844         return false;
845     }
846     if (yuvaPixmapInfo) {
847         SkColorType colorTypes[SkYUVAPixmapInfo::kMaxPlanes];
848         size_t rowBytes[SkYUVAPixmapInfo::kMaxPlanes];
849         for (int i = 0; i < 3; ++i) {
850             colorTypes[i] = kAlpha_8_SkColorType;
851             rowBytes[i] = dinfo->comp_info[i].width_in_blocks * DCTSIZE;
852         }
853         SkYUVAInfo yuvaInfo(codec.dimensions(),
854                             SkYUVAInfo::PlaneConfig::kY_U_V,
855                             tempSubsampling,
856                             kJPEG_Full_SkYUVColorSpace,
857                             codec.getOrigin(),
858                             SkYUVAInfo::Siting::kCentered,
859                             SkYUVAInfo::Siting::kCentered);
860         *yuvaPixmapInfo = SkYUVAPixmapInfo(yuvaInfo, colorTypes, rowBytes);
861     }
862     return true;
863 }
864 
onQueryYUVAInfo(const SkYUVAPixmapInfo::SupportedDataTypes& supportedDataTypes, SkYUVAPixmapInfo* yuvaPixmapInfo) const865 bool SkJpegCodec::onQueryYUVAInfo(const SkYUVAPixmapInfo::SupportedDataTypes& supportedDataTypes,
866                                   SkYUVAPixmapInfo* yuvaPixmapInfo) const {
867     jpeg_decompress_struct* dinfo = fDecoderMgr->dinfo();
868     return is_yuv_supported(dinfo, *this, &supportedDataTypes, yuvaPixmapInfo);
869 }
870 
onGetYUVAPlanes(const SkYUVAPixmaps& yuvaPixmaps)871 SkCodec::Result SkJpegCodec::onGetYUVAPlanes(const SkYUVAPixmaps& yuvaPixmaps) {
872     // Get a pointer to the decompress info since we will use it quite frequently
873     jpeg_decompress_struct* dinfo = fDecoderMgr->dinfo();
874     if (!is_yuv_supported(dinfo, *this, nullptr, nullptr)) {
875         return fDecoderMgr->returnFailure("onGetYUVAPlanes", kInvalidInput);
876     }
877     // Set the jump location for libjpeg errors
878     skjpeg_error_mgr::AutoPushJmpBuf jmp(fDecoderMgr->errorMgr());
879     if (setjmp(jmp)) {
880         return fDecoderMgr->returnFailure("setjmp", kInvalidInput);
881     }
882 
883     dinfo->raw_data_out = TRUE;
884     if (!jpeg_start_decompress(dinfo)) {
885         return fDecoderMgr->returnFailure("startDecompress", kInvalidInput);
886     }
887 
888     const std::array<SkPixmap, SkYUVAPixmaps::kMaxPlanes>& planes = yuvaPixmaps.planes();
889 
890 #ifdef SK_DEBUG
891     {
892         // A previous implementation claims that the return value of is_yuv_supported()
893         // may change after calling jpeg_start_decompress().  It looks to me like this
894         // was caused by a bug in the old code, but we'll be safe and check here.
895         // Also check that pixmap properties agree with expectations.
896         SkYUVAPixmapInfo info;
897         SkASSERT(is_yuv_supported(dinfo, *this, nullptr, &info));
898         SkASSERT(info.yuvaInfo() == yuvaPixmaps.yuvaInfo());
899         for (int i = 0; i < info.numPlanes(); ++i) {
900             SkASSERT(planes[i].colorType() == kAlpha_8_SkColorType);
901             SkASSERT(info.planeInfo(i) == planes[i].info());
902         }
903     }
904 #endif
905 
906     // Build a JSAMPIMAGE to handle output from libjpeg-turbo.  A JSAMPIMAGE has
907     // a 2-D array of pixels for each of the components (Y, U, V) in the image.
908     // Cheat Sheet:
909     //     JSAMPIMAGE == JSAMPLEARRAY* == JSAMPROW** == JSAMPLE***
910     JSAMPARRAY yuv[3];
911 
912     // Set aside enough space for pointers to rows of Y, U, and V.
913     JSAMPROW rowptrs[2 * DCTSIZE + DCTSIZE + DCTSIZE];
914     yuv[0] = &rowptrs[0];            // Y rows (DCTSIZE or 2 * DCTSIZE)
915     yuv[1] = &rowptrs[2 * DCTSIZE];  // U rows (DCTSIZE)
916     yuv[2] = &rowptrs[3 * DCTSIZE];  // V rows (DCTSIZE)
917 
918     // Initialize rowptrs.
919     int numYRowsPerBlock = DCTSIZE * dinfo->comp_info[0].v_samp_factor;
920     static_assert(sizeof(JSAMPLE) == 1);
921     for (int i = 0; i < numYRowsPerBlock; i++) {
922         rowptrs[i] = static_cast<JSAMPLE*>(planes[0].writable_addr()) + i* planes[0].rowBytes();
923     }
924     for (int i = 0; i < DCTSIZE; i++) {
925         rowptrs[i + 2 * DCTSIZE] =
926                 static_cast<JSAMPLE*>(planes[1].writable_addr()) + i* planes[1].rowBytes();
927         rowptrs[i + 3 * DCTSIZE] =
928                 static_cast<JSAMPLE*>(planes[2].writable_addr()) + i* planes[2].rowBytes();
929     }
930 
931     // After each loop iteration, we will increment pointers to Y, U, and V.
932     size_t blockIncrementY = numYRowsPerBlock * planes[0].rowBytes();
933     size_t blockIncrementU = DCTSIZE * planes[1].rowBytes();
934     size_t blockIncrementV = DCTSIZE * planes[2].rowBytes();
935 
936     uint32_t numRowsPerBlock = numYRowsPerBlock;
937 
938     // We intentionally round down here, as this first loop will only handle
939     // full block rows.  As a special case at the end, we will handle any
940     // remaining rows that do not make up a full block.
941     const int numIters = dinfo->output_height / numRowsPerBlock;
942     for (int i = 0; i < numIters; i++) {
943         JDIMENSION linesRead = jpeg_read_raw_data(dinfo, yuv, numRowsPerBlock);
944         if (linesRead < numRowsPerBlock) {
945             // FIXME: Handle incomplete YUV decodes without signalling an error.
946             return kInvalidInput;
947         }
948 
949         // Update rowptrs.
950         for (int j = 0; j < numYRowsPerBlock; j++) {
951             rowptrs[j] += blockIncrementY;
952         }
953         for (int j = 0; j < DCTSIZE; j++) {
954             rowptrs[j + 2 * DCTSIZE] += blockIncrementU;
955             rowptrs[j + 3 * DCTSIZE] += blockIncrementV;
956         }
957     }
958 
959     uint32_t remainingRows = dinfo->output_height - dinfo->output_scanline;
960     SkASSERT(remainingRows == dinfo->output_height % numRowsPerBlock);
961     SkASSERT(dinfo->output_scanline == numIters * numRowsPerBlock);
962     if (remainingRows > 0) {
963         // libjpeg-turbo needs memory to be padded by the block sizes.  We will fulfill
964         // this requirement using an extra row buffer.
965         // FIXME: Should SkCodec have an extra memory buffer that can be shared among
966         //        all of the implementations that use temporary/garbage memory?
967         SkAutoTMalloc<JSAMPLE> extraRow(planes[0].rowBytes());
968         for (int i = remainingRows; i < numYRowsPerBlock; i++) {
969             rowptrs[i] = extraRow.get();
970         }
971         int remainingUVRows = dinfo->comp_info[1].downsampled_height - DCTSIZE * numIters;
972         for (int i = remainingUVRows; i < DCTSIZE; i++) {
973             rowptrs[i + 2 * DCTSIZE] = extraRow.get();
974             rowptrs[i + 3 * DCTSIZE] = extraRow.get();
975         }
976 
977         JDIMENSION linesRead = jpeg_read_raw_data(dinfo, yuv, numRowsPerBlock);
978         if (linesRead < remainingRows) {
979             // FIXME: Handle incomplete YUV decodes without signalling an error.
980             return kInvalidInput;
981         }
982     }
983 
984     return kSuccess;
985 }
986 
987 // This function is declared in SkJpegInfo.h, used by SkPDF.
SkGetJpegInfo(const void* data, size_t len, SkISize* size, SkEncodedInfo::Color* colorType, SkEncodedOrigin* orientation)988 bool SkGetJpegInfo(const void* data, size_t len,
989                    SkISize* size,
990                    SkEncodedInfo::Color* colorType,
991                    SkEncodedOrigin* orientation) {
992     if (!SkJpegCodec::IsJpeg(data, len)) {
993         return false;
994     }
995 
996     SkMemoryStream stream(data, len);
997     JpegDecoderMgr decoderMgr(&stream);
998     // libjpeg errors will be caught and reported here
999     skjpeg_error_mgr::AutoPushJmpBuf jmp(decoderMgr.errorMgr());
1000     if (setjmp(jmp)) {
1001         return false;
1002     }
1003     decoderMgr.init();
1004     jpeg_decompress_struct* dinfo = decoderMgr.dinfo();
1005     jpeg_save_markers(dinfo, kExifMarker, 0xFFFF);
1006     jpeg_save_markers(dinfo, kICCMarker, 0xFFFF);
1007     if (JPEG_HEADER_OK != jpeg_read_header(dinfo, true)) {
1008         return false;
1009     }
1010     SkEncodedInfo::Color encodedColorType;
1011     if (!decoderMgr.getEncodedColor(&encodedColorType)) {
1012         return false;  // Unable to interpret the color channels as colors.
1013     }
1014     if (colorType) {
1015         *colorType = encodedColorType;
1016     }
1017     if (orientation) {
1018         *orientation = get_exif_orientation(dinfo);
1019     }
1020     if (size) {
1021         *size = {SkToS32(dinfo->image_width), SkToS32(dinfo->image_height)};
1022     }
1023     return true;
1024 }
1025