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