| OLD | NEW | 
|---|
| 1 /* | 1 /* | 
| 2  * Copyright 2015 Google Inc. | 2  * Copyright 2015 Google Inc. | 
| 3  * | 3  * | 
| 4  * Use of this source code is governed by a BSD-style license that can be | 4  * Use of this source code is governed by a BSD-style license that can be | 
| 5  * found in the LICENSE file. | 5  * found in the LICENSE file. | 
| 6  */ | 6  */ | 
| 7 | 7 | 
| 8 #include "SkCodec.h" | 8 #include "SkCodec.h" | 
| 9 #include "SkJpegCodec.h" | 9 #include "SkJpegCodec.h" | 
| 10 #include "SkJpegDecoderMgr.h" | 10 #include "SkJpegDecoderMgr.h" | 
| (...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 170 } | 170 } | 
| 171 | 171 | 
| 172 /* | 172 /* | 
| 173  * Return a valid set of output dimensions for this decoder, given an input scal
     e | 173  * Return a valid set of output dimensions for this decoder, given an input scal
     e | 
| 174  */ | 174  */ | 
| 175 SkISize SkJpegCodec::onGetScaledDimensions(float desiredScale) const { | 175 SkISize SkJpegCodec::onGetScaledDimensions(float desiredScale) const { | 
| 176     // 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 | 176     // 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 | 
| 177     // support these as well | 177     // support these as well | 
| 178     unsigned int num; | 178     unsigned int num; | 
| 179     unsigned int denom = 8; | 179     unsigned int denom = 8; | 
| 180     if (desiredScale > 0.875f) { | 180     if (desiredScale >= 0.9375) { | 
| 181         num = 8; | 181         num = 8; | 
| 182     } else if (desiredScale > 0.75f) { | 182     } else if (desiredScale >= 0.8125) { | 
| 183         num = 7; | 183         num = 7; | 
| 184     } else if (desiredScale > 0.625f) { | 184     } else if (desiredScale >= 0.6875f) { | 
| 185         num = 6; | 185         num = 6; | 
| 186     } else if (desiredScale > 0.5f) { | 186     } else if (desiredScale >= 0.5625f) { | 
| 187         num = 5; | 187         num = 5; | 
| 188     } else if (desiredScale > 0.375f) { | 188     } else if (desiredScale >= 0.4375f) { | 
| 189         num = 4; | 189         num = 4; | 
| 190     } else if (desiredScale > 0.25f) { | 190     } else if (desiredScale >= 0.3125f) { | 
| 191         num = 3; | 191         num = 3; | 
| 192     } else if (desiredScale > 0.125f) { | 192     } else if (desiredScale >= 0.1875f) { | 
| 193         num = 2; | 193         num = 2; | 
| 194     } else { | 194     } else { | 
| 195         num = 1; | 195         num = 1; | 
| 196     } | 196     } | 
| 197 | 197 | 
| 198     // Set up a fake decompress struct in order to use libjpeg to calculate outp
     ut dimensions | 198     // Set up a fake decompress struct in order to use libjpeg to calculate outp
     ut dimensions | 
| 199     jpeg_decompress_struct dinfo; | 199     jpeg_decompress_struct dinfo; | 
| 200     sk_bzero(&dinfo, sizeof(dinfo)); | 200     sk_bzero(&dinfo, sizeof(dinfo)); | 
| 201     dinfo.image_width = this->getInfo().width(); | 201     dinfo.image_width = this->getInfo().width(); | 
| 202     dinfo.image_height = this->getInfo().height(); | 202     dinfo.image_height = this->getInfo().height(); | 
| (...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 373             convert_CMYK_to_RGBA(dstRow, dstInfo.width()); | 373             convert_CMYK_to_RGBA(dstRow, dstInfo.width()); | 
| 374         } | 374         } | 
| 375 | 375 | 
| 376         // Move to the next row | 376         // Move to the next row | 
| 377         dstRow = SkTAddOffset<JSAMPLE>(dstRow, dstRowBytes); | 377         dstRow = SkTAddOffset<JSAMPLE>(dstRow, dstRowBytes); | 
| 378     } | 378     } | 
| 379 | 379 | 
| 380     return kSuccess; | 380     return kSuccess; | 
| 381 } | 381 } | 
| 382 | 382 | 
| 383 SkSampler* SkJpegCodec::getSampler(bool createIfNecessary) { | 383 void SkJpegCodec::initializeSwizzler(const SkImageInfo& dstInfo, const Options& 
     options) { | 
| 384     if (!createIfNecessary || fSwizzler) { |  | 
| 385         SkASSERT(!fSwizzler || (fSrcRow && static_cast<uint8_t*>(fStorage.get())
      == fSrcRow)); |  | 
| 386         return fSwizzler; |  | 
| 387     } |  | 
| 388 |  | 
| 389     const SkImageInfo& info = this->dstInfo(); |  | 
| 390     SkSwizzler::SrcConfig srcConfig; | 384     SkSwizzler::SrcConfig srcConfig; | 
| 391     switch (info.colorType()) { | 385     switch (dstInfo.colorType()) { | 
| 392         case kGray_8_SkColorType: | 386         case kGray_8_SkColorType: | 
| 393             srcConfig = SkSwizzler::kGray; | 387             srcConfig = SkSwizzler::kGray; | 
| 394             break; | 388             break; | 
| 395         case kRGBA_8888_SkColorType: | 389         case kRGBA_8888_SkColorType: | 
| 396             srcConfig = SkSwizzler::kRGBX; | 390             srcConfig = SkSwizzler::kRGBX; | 
| 397             break; | 391             break; | 
| 398         case kBGRA_8888_SkColorType: | 392         case kBGRA_8888_SkColorType: | 
| 399             srcConfig = SkSwizzler::kBGRX; | 393             srcConfig = SkSwizzler::kBGRX; | 
| 400             break; | 394             break; | 
| 401         case kRGB_565_SkColorType: | 395         case kRGB_565_SkColorType: | 
| 402             srcConfig = SkSwizzler::kRGB_565; | 396             srcConfig = SkSwizzler::kRGB_565; | 
| 403             break; | 397             break; | 
| 404         default: | 398         default: | 
| 405             // This function should only be called if the colorType is supported
      by jpeg | 399             // This function should only be called if the colorType is supported
      by jpeg | 
| 406             SkASSERT(false); | 400             SkASSERT(false); | 
| 407     } | 401     } | 
| 408 | 402 | 
| 409     fSwizzler.reset(SkSwizzler::CreateSwizzler(srcConfig, nullptr, info, | 403     fSwizzler.reset(SkSwizzler::CreateSwizzler(srcConfig, nullptr, dstInfo, opti
     ons)); | 
| 410                                                this->options().fZeroInitialized)
     ); | 404     fStorage.reset(get_row_bytes(fDecoderMgr->dinfo())); | 
| 411     if (!fSwizzler) { | 405     fSrcRow = static_cast<uint8_t*>(fStorage.get()); | 
| 412         return nullptr; | 406 } | 
|  | 407 | 
|  | 408 SkSampler* SkJpegCodec::getSampler(bool createIfNecessary) { | 
|  | 409     if (!createIfNecessary || fSwizzler) { | 
|  | 410         SkASSERT(!fSwizzler || (fSrcRow && static_cast<uint8_t*>(fStorage.get())
      == fSrcRow)); | 
|  | 411         return fSwizzler; | 
| 413     } | 412     } | 
| 414 | 413 | 
| 415     fStorage.reset(get_row_bytes(fDecoderMgr->dinfo())); | 414     this->initializeSwizzler(this->dstInfo(), this->options()); | 
| 416     fSrcRow = static_cast<uint8_t*>(fStorage.get()); |  | 
| 417     return fSwizzler; | 415     return fSwizzler; | 
| 418 } | 416 } | 
| 419 | 417 | 
| 420 SkCodec::Result SkJpegCodec::onStartScanlineDecode(const SkImageInfo& dstInfo, | 418 SkCodec::Result SkJpegCodec::onStartScanlineDecode(const SkImageInfo& dstInfo, | 
| 421         const Options& options, SkPMColor ctable[], int* ctableCount) { | 419         const Options& options, SkPMColor ctable[], int* ctableCount) { | 
| 422     // Set the jump location for libjpeg errors | 420     // Set the jump location for libjpeg errors | 
| 423     if (setjmp(fDecoderMgr->getJmpBuf())) { | 421     if (setjmp(fDecoderMgr->getJmpBuf())) { | 
| 424         SkCodecPrintf("setjmp: Error from libjpeg\n"); | 422         SkCodecPrintf("setjmp: Error from libjpeg\n"); | 
| 425         return kInvalidInput; | 423         return kInvalidInput; | 
| 426     } | 424     } | 
| 427 | 425 | 
| 428     // Check if we can decode to the requested destination and set the output co
     lor space | 426     // Check if we can decode to the requested destination and set the output co
     lor space | 
| 429     if (!this->setOutputColorSpace(dstInfo)) { | 427     if (!this->setOutputColorSpace(dstInfo)) { | 
| 430         return kInvalidConversion; | 428         return kInvalidConversion; | 
| 431     } | 429     } | 
| 432 | 430 | 
| 433     // Remove objects used for sampling. | 431     // Remove objects used for sampling. | 
| 434     fSwizzler.reset(nullptr); | 432     fSwizzler.reset(nullptr); | 
| 435     fSrcRow = nullptr; | 433     fSrcRow = nullptr; | 
| 436     fStorage.free(); | 434     fStorage.free(); | 
| 437 | 435 | 
| 438     // Now, given valid output dimensions, we can start the decompress | 436     // Now, given valid output dimensions, we can start the decompress | 
| 439     if (!jpeg_start_decompress(fDecoderMgr->dinfo())) { | 437     if (!jpeg_start_decompress(fDecoderMgr->dinfo())) { | 
| 440         SkCodecPrintf("start decompress failed\n"); | 438         SkCodecPrintf("start decompress failed\n"); | 
| 441         return kInvalidInput; | 439         return kInvalidInput; | 
| 442     } | 440     } | 
| 443 | 441 | 
|  | 442     // We will need a swizzler if we are performing a subset decode | 
|  | 443     if (options.fSubset) { | 
|  | 444         this->initializeSwizzler(dstInfo, options); | 
|  | 445     } | 
|  | 446 | 
| 444     return kSuccess; | 447     return kSuccess; | 
| 445 } | 448 } | 
| 446 | 449 | 
| 447 int SkJpegCodec::onGetScanlines(void* dst, int count, size_t rowBytes) { | 450 int SkJpegCodec::onGetScanlines(void* dst, int count, size_t rowBytes) { | 
| 448     // Set the jump location for libjpeg errors | 451     // Set the jump location for libjpeg errors | 
| 449     if (setjmp(fDecoderMgr->getJmpBuf())) { | 452     if (setjmp(fDecoderMgr->getJmpBuf())) { | 
| 450         return fDecoderMgr->returnFailure("setjmp", kInvalidInput); | 453         return fDecoderMgr->returnFailure("setjmp", kInvalidInput); | 
| 451     } | 454     } | 
| 452     // Read rows one at a time | 455     // Read rows one at a time | 
| 453     JSAMPLE* dstRow; | 456     JSAMPLE* dstRow; | 
| 454     if (fSwizzler) { | 457     if (fSwizzler) { | 
| 455         // write data to storage row, then sample using swizzler | 458         // write data to storage row, then sample using swizzler | 
| 456         dstRow = fSrcRow; | 459         dstRow = fSrcRow; | 
| 457     } else { | 460     } else { | 
| 458         // write data directly to dst | 461         // write data directly to dst | 
| 459         dstRow = (JSAMPLE*) dst; | 462         dstRow = (JSAMPLE*) dst; | 
| 460     } | 463     } | 
| 461 | 464 | 
| 462     for (int y = 0; y < count; y++) { | 465     for (int y = 0; y < count; y++) { | 
| 463         // Read row of the image | 466         // Read row of the image | 
| 464         uint32_t rowsDecoded = jpeg_read_scanlines(fDecoderMgr->dinfo(), &dstRow
     , 1); | 467         uint32_t rowsDecoded = jpeg_read_scanlines(fDecoderMgr->dinfo(), &dstRow
     , 1); | 
| 465         if (rowsDecoded != 1) { | 468         if (rowsDecoded != 1) { | 
| (...skipping 29 matching lines...) Expand all  Loading... | 
| 495 #endif | 498 #endif | 
| 496 | 499 | 
| 497 bool SkJpegCodec::onSkipScanlines(int count) { | 500 bool SkJpegCodec::onSkipScanlines(int count) { | 
| 498     // Set the jump location for libjpeg errors | 501     // Set the jump location for libjpeg errors | 
| 499     if (setjmp(fDecoderMgr->getJmpBuf())) { | 502     if (setjmp(fDecoderMgr->getJmpBuf())) { | 
| 500         return fDecoderMgr->returnFalse("setjmp"); | 503         return fDecoderMgr->returnFalse("setjmp"); | 
| 501     } | 504     } | 
| 502 | 505 | 
| 503     return count == jpeg_skip_scanlines(fDecoderMgr->dinfo(), count); | 506     return count == jpeg_skip_scanlines(fDecoderMgr->dinfo(), count); | 
| 504 } | 507 } | 
| OLD | NEW | 
|---|