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