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