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