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 "SkJpegUtility.h"
     12 #include "SkCodecPriv.h"
     13 #include "SkColorPriv.h"
     14 #include "SkStream.h"
     15 #include "SkTemplates.h"
     16 #include "SkTypes.h"
     17 
     18 // stdio is needed for jpeglib
     19 #include <stdio.h>
     20 
     21 extern "C" {
     22     #include "jerror.h"
     23     #include "jmorecfg.h"
     24     #include "jpegint.h"
     25     #include "jpeglib.h"
     26 }
     27 
     28 // ANDROID_RGB
     29 // If this is defined in the jpeg headers it indicates that jpeg offers
     30 // support for two additional formats: JCS_RGBA_8888 and JCS_RGB_565.
     31 
     32 /*
     33  * Get the source configuarion for the swizzler
     34  */
     35 SkSwizzler::SrcConfig get_src_config(const jpeg_decompress_struct& dinfo) {
     36     if (JCS_CMYK == dinfo.out_color_space) {
     37         // We will need to perform a manual conversion
     38         return  SkSwizzler::kRGBX;
     39     }
     40     if (3 == dinfo.out_color_components && JCS_RGB == dinfo.out_color_space) {
     41         return SkSwizzler::kRGB;
     42     }
     43 #ifdef ANDROID_RGB
     44     if (JCS_RGBA_8888 == dinfo.out_color_space) {
     45         return SkSwizzler::kRGBX;
     46     }
     47 
     48     if (JCS_RGB_565 == dinfo.out_color_space) {
     49         return SkSwizzler::kRGB_565;
     50     }
     51 #endif
     52     if (1 == dinfo.out_color_components && JCS_GRAYSCALE == dinfo.out_color_space) {
     53         return SkSwizzler::kGray;
     54     }
     55     return SkSwizzler::kUnknown;
     56 }
     57 
     58 /*
     59  * Convert a row of CMYK samples to RGBX in place.
     60  * Note that this method moves the row pointer.
     61  * @param width the number of pixels in the row that is being converted
     62  *              CMYK is stored as four bytes per pixel
     63  */
     64 static void convert_CMYK_to_RGB(uint8_t* row, uint32_t width) {
     65     // We will implement a crude conversion from CMYK -> RGB using formulas
     66     // from easyrgb.com.
     67     //
     68     // CMYK -> CMY
     69     // C = C * (1 - K) + K
     70     // M = M * (1 - K) + K
     71     // Y = Y * (1 - K) + K
     72     //
     73     // libjpeg actually gives us inverted CMYK, so we must subtract the
     74     // original terms from 1.
     75     // CMYK -> CMY
     76     // C = (1 - C) * (1 - (1 - K)) + (1 - K)
     77     // M = (1 - M) * (1 - (1 - K)) + (1 - K)
     78     // Y = (1 - Y) * (1 - (1 - K)) + (1 - K)
     79     //
     80     // Simplifying the above expression.
     81     // CMYK -> CMY
     82     // C = 1 - CK
     83     // M = 1 - MK
     84     // Y = 1 - YK
     85     //
     86     // CMY -> RGB
     87     // R = (1 - C) * 255
     88     // G = (1 - M) * 255
     89     // B = (1 - Y) * 255
     90     //
     91     // Therefore the full conversion is below.  This can be verified at
     92     // www.rapidtables.com (assuming inverted CMYK).
     93     // CMYK -> RGB
     94     // R = C * K * 255
     95     // G = M * K * 255
     96     // B = Y * K * 255
     97     //
     98     // As a final note, we have treated the CMYK values as if they were on
     99     // a scale from 0-1, when in fact they are 8-bit ints scaling from 0-255.
    100     // We must divide each CMYK component by 255 to obtain the true conversion
    101     // we should perform.
    102     // CMYK -> RGB
    103     // R = C * K / 255
    104     // G = M * K / 255
    105     // B = Y * K / 255
    106     for (uint32_t x = 0; x < width; x++, row += 4) {
    107         row[0] = SkMulDiv255Round(row[0], row[3]);
    108         row[1] = SkMulDiv255Round(row[1], row[3]);
    109         row[2] = SkMulDiv255Round(row[2], row[3]);
    110         row[3] = 0xFF;
    111     }
    112 }
    113 
    114 bool SkJpegCodec::IsJpeg(SkStream* stream) {
    115     static const uint8_t jpegSig[] = { 0xFF, 0xD8, 0xFF };
    116     char buffer[sizeof(jpegSig)];
    117     return stream->read(buffer, sizeof(jpegSig)) == sizeof(jpegSig) &&
    118             !memcmp(buffer, jpegSig, sizeof(jpegSig));
    119 }
    120 
    121 bool SkJpegCodec::ReadHeader(SkStream* stream, SkCodec** codecOut,
    122         JpegDecoderMgr** decoderMgrOut) {
    123 
    124     // Create a JpegDecoderMgr to own all of the decompress information
    125     SkAutoTDelete<JpegDecoderMgr> decoderMgr(SkNEW_ARGS(JpegDecoderMgr, (stream)));
    126 
    127     // libjpeg errors will be caught and reported here
    128     if (setjmp(decoderMgr->getJmpBuf())) {
    129         return decoderMgr->returnFalse("setjmp");
    130     }
    131 
    132     // Initialize the decompress info and the source manager
    133     decoderMgr->init();
    134 
    135     // Read the jpeg header
    136     if (JPEG_HEADER_OK != jpeg_read_header(decoderMgr->dinfo(), true)) {
    137         return decoderMgr->returnFalse("read_header");
    138     }
    139 
    140     if (NULL != codecOut) {
    141         // Recommend the color type to decode to
    142         const SkColorType colorType = decoderMgr->getColorType();
    143 
    144         // Create image info object and the codec
    145         const SkImageInfo& imageInfo = SkImageInfo::Make(decoderMgr->dinfo()->image_width,
    146                 decoderMgr->dinfo()->image_height, colorType, kOpaque_SkAlphaType);
    147         *codecOut = SkNEW_ARGS(SkJpegCodec, (imageInfo, stream, decoderMgr.detach()));
    148     } else {
    149         SkASSERT(NULL != decoderMgrOut);
    150         *decoderMgrOut = decoderMgr.detach();
    151     }
    152     return true;
    153 }
    154 
    155 SkCodec* SkJpegCodec::NewFromStream(SkStream* stream) {
    156     SkAutoTDelete<SkStream> streamDeleter(stream);
    157     SkCodec* codec = NULL;
    158     if (ReadHeader(stream,  &codec, NULL)) {
    159         // Codec has taken ownership of the stream, we do not need to delete it
    160         SkASSERT(codec);
    161         streamDeleter.detach();
    162         return codec;
    163     }
    164     return NULL;
    165 }
    166 
    167 SkJpegCodec::SkJpegCodec(const SkImageInfo& srcInfo, SkStream* stream,
    168         JpegDecoderMgr* decoderMgr)
    169     : INHERITED(srcInfo, stream)
    170     , fDecoderMgr(decoderMgr)
    171     , fSwizzler(NULL)
    172     , fSrcRowBytes(0)
    173 {}
    174 
    175 /*
    176  * Return a valid set of output dimensions for this decoder, given an input scale
    177  */
    178 SkISize SkJpegCodec::onGetScaledDimensions(float desiredScale) const {
    179     // libjpeg supports scaling by 1/1, 1/2, 1/4, and 1/8, so we will support these as well
    180     long scale;
    181     if (desiredScale > 0.75f) {
    182         scale = 1;
    183     } else if (desiredScale > 0.375f) {
    184         scale = 2;
    185     } else if (desiredScale > 0.1875f) {
    186         scale = 4;
    187     } else {
    188         scale = 8;
    189     }
    190 
    191     // Set up a fake decompress struct in order to use libjpeg to calculate output dimensions
    192     jpeg_decompress_struct dinfo;
    193     sk_bzero(&dinfo, sizeof(dinfo));
    194     dinfo.image_width = this->getInfo().width();
    195     dinfo.image_height = this->getInfo().height();
    196     dinfo.global_state = DSTATE_READY;
    197     dinfo.num_components = 0;
    198     dinfo.scale_num = 1;
    199     dinfo.scale_denom = scale;
    200     jpeg_calc_output_dimensions(&dinfo);
    201 
    202     // Return the calculated output dimensions for the given scale
    203     return SkISize::Make(dinfo.output_width, dinfo.output_height);
    204 }
    205 
    206 /*
    207  * Checks if the conversion between the input image and the requested output
    208  * image has been implemented
    209  */
    210 static bool conversion_possible(const SkImageInfo& dst,
    211                                 const SkImageInfo& src) {
    212     // Ensure that the profile type is unchanged
    213     if (dst.profileType() != src.profileType()) {
    214         return false;
    215     }
    216 
    217     // Ensure that the alpha type is opaque
    218     if (kOpaque_SkAlphaType != dst.alphaType()) {
    219         return false;
    220     }
    221 
    222     // Always allow kN32 as the color type
    223     if (kN32_SkColorType == dst.colorType()) {
    224         return true;
    225     }
    226 
    227     // Otherwise require that the destination color type match our recommendation
    228     return dst.colorType() == src.colorType();
    229 }
    230 
    231 /*
    232  * Handles rewinding the input stream if it is necessary
    233  */
    234 bool SkJpegCodec::handleRewind() {
    235     switch(this->rewindIfNeeded()) {
    236         case kCouldNotRewind_RewindState:
    237             return fDecoderMgr->returnFalse("could not rewind");
    238         case kRewound_RewindState: {
    239             JpegDecoderMgr* decoderMgr = NULL;
    240             if (!ReadHeader(this->stream(), NULL, &decoderMgr)) {
    241                 return fDecoderMgr->returnFalse("could not rewind");
    242             }
    243             SkASSERT(NULL != decoderMgr);
    244             fDecoderMgr.reset(decoderMgr);
    245             return true;
    246         }
    247         case kNoRewindNecessary_RewindState:
    248             return true;
    249         default:
    250             SkASSERT(false);
    251             return false;
    252     }
    253 }
    254 
    255 /*
    256  * Checks if we can scale to the requested dimensions and scales the dimensions
    257  * if possible
    258  */
    259 bool SkJpegCodec::scaleToDimensions(uint32_t dstWidth, uint32_t dstHeight) {
    260     // libjpeg can scale to 1/1, 1/2, 1/4, and 1/8
    261     SkASSERT(1 == fDecoderMgr->dinfo()->scale_num);
    262     SkASSERT(1 == fDecoderMgr->dinfo()->scale_denom);
    263     jpeg_calc_output_dimensions(fDecoderMgr->dinfo());
    264     while (fDecoderMgr->dinfo()->output_width != dstWidth ||
    265             fDecoderMgr->dinfo()->output_height != dstHeight) {
    266 
    267         // Return a failure if we have tried all of the possible scales
    268         if (8 == fDecoderMgr->dinfo()->scale_denom ||
    269                 dstWidth > fDecoderMgr->dinfo()->output_width ||
    270                 dstHeight > fDecoderMgr->dinfo()->output_height) {
    271             return fDecoderMgr->returnFalse("could not scale to requested dimensions");
    272         }
    273 
    274         // Try the next scale
    275         fDecoderMgr->dinfo()->scale_denom *= 2;
    276         jpeg_calc_output_dimensions(fDecoderMgr->dinfo());
    277     }
    278     return true;
    279 }
    280 
    281 /*
    282  * Create the swizzler based on the encoded format
    283  */
    284 void SkJpegCodec::initializeSwizzler(const SkImageInfo& dstInfo,
    285                                      void* dst, size_t dstRowBytes,
    286                                      const Options& options) {
    287     SkSwizzler::SrcConfig srcConfig = get_src_config(*fDecoderMgr->dinfo());
    288     fSwizzler.reset(SkSwizzler::CreateSwizzler(srcConfig, NULL, dstInfo, dst, dstRowBytes,
    289             options.fZeroInitialized));
    290     fSrcRowBytes = SkSwizzler::BytesPerPixel(srcConfig) * dstInfo.width();
    291 }
    292 
    293 /*
    294  * Performs the jpeg decode
    295  */
    296 SkCodec::Result SkJpegCodec::onGetPixels(const SkImageInfo& dstInfo,
    297                                          void* dst, size_t dstRowBytes,
    298                                          const Options& options, SkPMColor*, int*) {
    299 
    300     // Rewind the stream if needed
    301     if (!this->handleRewind()) {
    302         fDecoderMgr->returnFailure("could not rewind stream", kCouldNotRewind);
    303     }
    304 
    305     // Get a pointer to the decompress info since we will use it quite frequently
    306     jpeg_decompress_struct* dinfo = fDecoderMgr->dinfo();
    307 
    308     // Set the jump location for libjpeg errors
    309     if (setjmp(fDecoderMgr->getJmpBuf())) {
    310         return fDecoderMgr->returnFailure("setjmp", kInvalidInput);
    311     }
    312 
    313     // Check if we can decode to the requested destination
    314     if (!conversion_possible(dstInfo, this->getInfo())) {
    315         return fDecoderMgr->returnFailure("conversion_possible", kInvalidConversion);
    316     }
    317 
    318     // Perform the necessary scaling
    319     if (!this->scaleToDimensions(dstInfo.width(), dstInfo.height())) {
    320         fDecoderMgr->returnFailure("cannot scale to requested dims", kInvalidScale);
    321     }
    322 
    323     // Now, given valid output dimensions, we can start the decompress
    324     if (!jpeg_start_decompress(dinfo)) {
    325         return fDecoderMgr->returnFailure("startDecompress", kInvalidInput);
    326     }
    327 
    328     // Create the swizzler
    329     this->initializeSwizzler(dstInfo, dst, dstRowBytes, options);
    330     if (NULL == fSwizzler) {
    331         return fDecoderMgr->returnFailure("getSwizzler", kUnimplemented);
    332     }
    333 
    334     // This is usually 1, but can also be 2 or 4.
    335     // If we wanted to always read one row at a time, we could, but we will save space and time
    336     // by using the recommendation from libjpeg.
    337     const uint32_t rowsPerDecode = dinfo->rec_outbuf_height;
    338     SkASSERT(rowsPerDecode <= 4);
    339 
    340     // Create a buffer to contain decoded rows (libjpeg requires a 2D array)
    341     SkASSERT(0 != fSrcRowBytes);
    342     SkAutoTDeleteArray<uint8_t> srcBuffer(SkNEW_ARRAY(uint8_t, fSrcRowBytes * rowsPerDecode));
    343     JSAMPLE* srcRows[4];
    344     uint8_t* srcPtr = srcBuffer.get();
    345     for (uint8_t i = 0; i < rowsPerDecode; i++) {
    346         srcRows[i] = (JSAMPLE*) srcPtr;
    347         srcPtr += fSrcRowBytes;
    348     }
    349 
    350     // Ensure that we loop enough times to decode all of the rows
    351     // libjpeg will prevent us from reading past the bottom of the image
    352     uint32_t dstHeight = dstInfo.height();
    353     for (uint32_t y = 0; y < dstHeight + rowsPerDecode - 1; y += rowsPerDecode) {
    354         // Read rows of the image
    355         uint32_t rowsDecoded = jpeg_read_scanlines(dinfo, srcRows, rowsPerDecode);
    356 
    357         // Convert to RGB if necessary
    358         if (JCS_CMYK == dinfo->out_color_space) {
    359             convert_CMYK_to_RGB(srcRows[0], dstInfo.width() * rowsDecoded);
    360         }
    361 
    362         // Swizzle to output destination
    363         for (uint32_t i = 0; i < rowsDecoded; i++) {
    364             fSwizzler->next(srcRows[i]);
    365         }
    366 
    367         // If we cannot read enough rows, assume the input is incomplete
    368         if (rowsDecoded < rowsPerDecode && y + rowsDecoded < dstHeight) {
    369             // Fill the remainder of the image with black. This error handling
    370             // behavior is unspecified but SkCodec consistently uses black as
    371             // the fill color for opaque images.  If the destination is kGray,
    372             // the low 8 bits of SK_ColorBLACK will be used.  Conveniently,
    373             // these are zeros, which is the representation for black in kGray.
    374             SkSwizzler::Fill(fSwizzler->getDstRow(), dstInfo, dstRowBytes,
    375                     dstHeight - y - rowsDecoded, SK_ColorBLACK, NULL);
    376 
    377             // Prevent libjpeg from failing on incomplete decode
    378             dinfo->output_scanline = dstHeight;
    379 
    380             // Finish the decode and indicate that the input was incomplete.
    381             jpeg_finish_decompress(dinfo);
    382             return fDecoderMgr->returnFailure("Incomplete image data", kIncompleteInput);
    383         }
    384     }
    385     jpeg_finish_decompress(dinfo);
    386 
    387     return kSuccess;
    388 }
    389 
    390 /*
    391  * Enable scanline decoding for jpegs
    392  */
    393 class SkJpegScanlineDecoder : public SkScanlineDecoder {
    394 public:
    395     SkJpegScanlineDecoder(const SkImageInfo& dstInfo, SkJpegCodec* codec)
    396         : INHERITED(dstInfo)
    397         , fCodec(codec)
    398     {
    399         fStorage.reset(fCodec->fSrcRowBytes);
    400         fSrcRow = static_cast<uint8_t*>(fStorage.get());
    401     }
    402 
    403     SkImageGenerator::Result onGetScanlines(void* dst, int count, size_t rowBytes) override {
    404         // Set the jump location for libjpeg errors
    405         if (setjmp(fCodec->fDecoderMgr->getJmpBuf())) {
    406             return fCodec->fDecoderMgr->returnFailure("setjmp", SkImageGenerator::kInvalidInput);
    407         }
    408 
    409         // Read rows one at a time
    410         for (int y = 0; y < count; y++) {
    411             // Read row of the image
    412             uint32_t rowsDecoded = jpeg_read_scanlines(fCodec->fDecoderMgr->dinfo(), &fSrcRow, 1);
    413             if (rowsDecoded != 1) {
    414                 SkSwizzler::Fill(dst, this->dstInfo(), rowBytes, count - y, SK_ColorBLACK, NULL);
    415                 return SkImageGenerator::kIncompleteInput;
    416             }
    417 
    418             // Convert to RGB if necessary
    419             if (JCS_CMYK == fCodec->fDecoderMgr->dinfo()->out_color_space) {
    420                 convert_CMYK_to_RGB(fSrcRow, dstInfo().width());
    421             }
    422 
    423             // Swizzle to output destination
    424             fCodec->fSwizzler->setDstRow(dst);
    425             fCodec->fSwizzler->next(fSrcRow);
    426             dst = SkTAddOffset<void>(dst, rowBytes);
    427         }
    428 
    429         return SkImageGenerator::kSuccess;
    430     }
    431 
    432     SkImageGenerator::Result onSkipScanlines(int count) override {
    433         // Set the jump location for libjpeg errors
    434         if (setjmp(fCodec->fDecoderMgr->getJmpBuf())) {
    435             return fCodec->fDecoderMgr->returnFailure("setjmp", SkImageGenerator::kInvalidInput);
    436         }
    437 
    438         // Read rows but ignore the output
    439         for (int y = 0; y < count; y++) {
    440             jpeg_read_scanlines(fCodec->fDecoderMgr->dinfo(), &fSrcRow, 1);
    441         }
    442 
    443         return SkImageGenerator::kSuccess;
    444     }
    445 
    446     void onFinish() override {
    447         if (setjmp(fCodec->fDecoderMgr->getJmpBuf())) {
    448             SkCodecPrintf("setjmp: Error in libjpeg finish_decompress\n");
    449             return;
    450         }
    451 
    452         jpeg_finish_decompress(fCodec->fDecoderMgr->dinfo());
    453     }
    454 
    455 private:
    456     SkJpegCodec*        fCodec;     // unowned
    457     SkAutoMalloc        fStorage;
    458     uint8_t*            fSrcRow;    // ptr into fStorage
    459 
    460     typedef SkScanlineDecoder INHERITED;
    461 };
    462 
    463 SkScanlineDecoder* SkJpegCodec::onGetScanlineDecoder(const SkImageInfo& dstInfo,
    464         const Options& options, SkPMColor ctable[], int* ctableCount) {
    465 
    466     // Rewind the stream if needed
    467     if (!this->handleRewind()) {
    468         SkCodecPrintf("Could not rewind\n");
    469         return NULL;
    470     }
    471 
    472     // Set the jump location for libjpeg errors
    473     if (setjmp(fDecoderMgr->getJmpBuf())) {
    474         SkCodecPrintf("setjmp: Error from libjpeg\n");
    475         return NULL;
    476     }
    477 
    478     // Check if we can decode to the requested destination
    479     if (!conversion_possible(dstInfo, this->getInfo())) {
    480         SkCodecPrintf("Cannot convert to output type\n");
    481         return NULL;
    482     }
    483 
    484     // Perform the necessary scaling
    485     if (!this->scaleToDimensions(dstInfo.width(), dstInfo.height())) {
    486         SkCodecPrintf("Cannot scale ot output dimensions\n");
    487         return NULL;
    488     }
    489 
    490     // Now, given valid output dimensions, we can start the decompress
    491     if (!jpeg_start_decompress(fDecoderMgr->dinfo())) {
    492         SkCodecPrintf("start decompress failed\n");
    493         return NULL;
    494     }
    495 
    496     // Create the swizzler
    497     this->initializeSwizzler(dstInfo, NULL, dstInfo.minRowBytes(), options);
    498     if (NULL == fSwizzler) {
    499         SkCodecPrintf("Could not create swizzler\n");
    500         return NULL;
    501     }
    502 
    503     // Return the new scanline decoder
    504     return SkNEW_ARGS(SkJpegScanlineDecoder, (dstInfo, this));
    505 }
    506