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 "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 
     27 extern "C" {
     28     #include "jerror.h"
     29     #include "jpeglib.h"
     30 }
     31 
     32 bool 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 
     37 static 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 
     45 const uint32_t kExifHeaderSize = 14;
     46 const uint32_t kExifMarker = JPEG_APP0 + 1;
     47 
     48 static 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 
    100 static 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 
    111 static 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  */
    125 static 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 
    188 SkCodec::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 
    265 SkCodec* SkJpegCodec::NewFromStream(SkStream* stream, Result* result) {
    266     return SkJpegCodec::NewFromStream(stream, result, SkColorSpace::MakeSRGB());
    267 }
    268 
    269 SkCodec* 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 
    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, 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  */
    297 static 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  */
    310 void 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  */
    320 SkISize 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 
    355 bool 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  */
    376 bool 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  */
    450 bool 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 
    487 int 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  */
    551 static 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  */
    564 SkCodec::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 
    614 void 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 
    639 void 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 
    669 SkSampler* 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 
    682 SkCodec::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 
    753 int 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 
    763 bool 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 
    772 static 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 
    827 bool 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 
    850 SkCodec::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