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