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