| 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" |
| 11 #include "SkJpegUtility_codec.h" | 11 #include "SkJpegUtility_codec.h" |
| 12 #include "SkCodecPriv.h" | 12 #include "SkCodecPriv.h" |
| 13 #include "SkColorPriv.h" | 13 #include "SkColorPriv.h" |
| 14 #include "SkScanlineDecoder.h" |
| 14 #include "SkStream.h" | 15 #include "SkStream.h" |
| 15 #include "SkTemplates.h" | 16 #include "SkTemplates.h" |
| 16 #include "SkTypes.h" | 17 #include "SkTypes.h" |
| 17 | 18 |
| 18 // stdio is needed for libjpeg-turbo | 19 // stdio is needed for libjpeg-turbo |
| 19 #include <stdio.h> | 20 #include <stdio.h> |
| 20 | 21 |
| 21 extern "C" { | 22 extern "C" { |
| 22 #include "jpeglibmangler.h" | 23 #include "jpeglibmangler.h" |
| 23 #include "jerror.h" | 24 #include "jerror.h" |
| (...skipping 376 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 400 /* | 401 /* |
| 401 * Enable scanline decoding for jpegs | 402 * Enable scanline decoding for jpegs |
| 402 */ | 403 */ |
| 403 class SkJpegScanlineDecoder : public SkScanlineDecoder { | 404 class SkJpegScanlineDecoder : public SkScanlineDecoder { |
| 404 public: | 405 public: |
| 405 SkJpegScanlineDecoder(const SkImageInfo& dstInfo, SkJpegCodec* codec) | 406 SkJpegScanlineDecoder(const SkImageInfo& dstInfo, SkJpegCodec* codec) |
| 406 : INHERITED(dstInfo) | 407 : INHERITED(dstInfo) |
| 407 , fCodec(codec) | 408 , fCodec(codec) |
| 408 {} | 409 {} |
| 409 | 410 |
| 410 SkImageGenerator::Result onGetScanlines(void* dst, int count, size_t rowByte
s) override { | 411 SkCodec::Result onGetScanlines(void* dst, int count, size_t rowBytes) overri
de { |
| 411 // Set the jump location for libjpeg errors | 412 // Set the jump location for libjpeg errors |
| 412 if (setjmp(fCodec->fDecoderMgr->getJmpBuf())) { | 413 if (setjmp(fCodec->fDecoderMgr->getJmpBuf())) { |
| 413 return fCodec->fDecoderMgr->returnFailure("setjmp", SkImageGenerator
::kInvalidInput); | 414 return fCodec->fDecoderMgr->returnFailure("setjmp", SkCodec::kInvali
dInput); |
| 414 } | 415 } |
| 415 | 416 |
| 416 // Read rows one at a time | 417 // Read rows one at a time |
| 417 JSAMPLE* dstRow = (JSAMPLE*) dst; | 418 JSAMPLE* dstRow = (JSAMPLE*) dst; |
| 418 for (int y = 0; y < count; y++) { | 419 for (int y = 0; y < count; y++) { |
| 419 // Read row of the image | 420 // Read row of the image |
| 420 uint32_t rowsDecoded = | 421 uint32_t rowsDecoded = |
| 421 turbo_jpeg_read_scanlines(fCodec->fDecoderMgr->dinfo(), &dst
Row, 1); | 422 turbo_jpeg_read_scanlines(fCodec->fDecoderMgr->dinfo(), &dst
Row, 1); |
| 422 if (rowsDecoded != 1) { | 423 if (rowsDecoded != 1) { |
| 423 SkSwizzler::Fill( | 424 SkSwizzler::Fill( |
| 424 dstRow, this->dstInfo(), rowBytes, count - y, SK_ColorBL
ACK, NULL); | 425 dstRow, this->dstInfo(), rowBytes, count - y, SK_ColorBL
ACK, NULL); |
| 425 fCodec->fDecoderMgr->dinfo()->output_scanline = this->dstInfo().
height(); | 426 fCodec->fDecoderMgr->dinfo()->output_scanline = this->dstInfo().
height(); |
| 426 return SkImageGenerator::kIncompleteInput; | 427 return SkCodec::kIncompleteInput; |
| 427 } | 428 } |
| 428 | 429 |
| 429 // Convert to RGBA if necessary | 430 // Convert to RGBA if necessary |
| 430 if (JCS_CMYK == fCodec->fDecoderMgr->dinfo()->out_color_space) { | 431 if (JCS_CMYK == fCodec->fDecoderMgr->dinfo()->out_color_space) { |
| 431 convert_CMYK_to_RGBA(dstRow, this->dstInfo().width()); | 432 convert_CMYK_to_RGBA(dstRow, this->dstInfo().width()); |
| 432 } | 433 } |
| 433 | 434 |
| 434 // Move to the next row | 435 // Move to the next row |
| 435 dstRow = SkTAddOffset<JSAMPLE>(dstRow, rowBytes); | 436 dstRow = SkTAddOffset<JSAMPLE>(dstRow, rowBytes); |
| 436 } | 437 } |
| 437 | 438 |
| 438 return SkImageGenerator::kSuccess; | 439 return SkCodec::kSuccess; |
| 439 } | 440 } |
| 440 | 441 |
| 441 #ifndef TURBO_HAS_SKIP | 442 #ifndef TURBO_HAS_SKIP |
| 442 #define turbo_jpeg_skip_scanlines(dinfo, count) \ | 443 #define turbo_jpeg_skip_scanlines(dinfo, count) \ |
| 443 SkAutoMalloc storage(dinfo->output_width * dinfo->out_color_components); \ | 444 SkAutoMalloc storage(dinfo->output_width * dinfo->out_color_components); \ |
| 444 uint8_t* storagePtr = static_cast<uint8_t*>(storage.get()); \ | 445 uint8_t* storagePtr = static_cast<uint8_t*>(storage.get()); \ |
| 445 for (int y = 0; y < count; y++) { \ | 446 for (int y = 0; y < count; y++) { \ |
| 446 turbo_jpeg_read_scanlines(dinfo, &storagePtr, 1); \ | 447 turbo_jpeg_read_scanlines(dinfo, &storagePtr, 1); \ |
| 447 } | 448 } |
| 448 #endif | 449 #endif |
| 449 | 450 |
| 450 SkImageGenerator::Result onSkipScanlines(int count) override { | 451 SkCodec::Result onSkipScanlines(int count) override { |
| 451 // Set the jump location for libjpeg errors | 452 // Set the jump location for libjpeg errors |
| 452 if (setjmp(fCodec->fDecoderMgr->getJmpBuf())) { | 453 if (setjmp(fCodec->fDecoderMgr->getJmpBuf())) { |
| 453 return fCodec->fDecoderMgr->returnFailure("setjmp", SkImageGenerator
::kInvalidInput); | 454 return fCodec->fDecoderMgr->returnFailure("setjmp", SkCodec::kInvali
dInput); |
| 454 } | 455 } |
| 455 | 456 |
| 456 turbo_jpeg_skip_scanlines(fCodec->fDecoderMgr->dinfo(), count); | 457 turbo_jpeg_skip_scanlines(fCodec->fDecoderMgr->dinfo(), count); |
| 457 | 458 |
| 458 return SkImageGenerator::kSuccess; | 459 return SkCodec::kSuccess; |
| 459 } | 460 } |
| 460 | 461 |
| 461 private: | 462 private: |
| 462 SkJpegCodec* fCodec; // unowned | 463 SkJpegCodec* fCodec; // unowned |
| 463 | 464 |
| 464 typedef SkScanlineDecoder INHERITED; | 465 typedef SkScanlineDecoder INHERITED; |
| 465 }; | 466 }; |
| 466 | 467 |
| 467 SkScanlineDecoder* SkJpegCodec::onGetScanlineDecoder(const SkImageInfo& dstInfo, | 468 SkScanlineDecoder* SkJpegCodec::onGetScanlineDecoder(const SkImageInfo& dstInfo, |
| 468 const Options& options, SkPMColor ctable[], int* ctableCount) { | 469 const Options& options, SkPMColor ctable[], int* ctableCount) { |
| (...skipping 24 matching lines...) Expand all Loading... |
| 493 | 494 |
| 494 // Now, given valid output dimensions, we can start the decompress | 495 // Now, given valid output dimensions, we can start the decompress |
| 495 if (!turbo_jpeg_start_decompress(fDecoderMgr->dinfo())) { | 496 if (!turbo_jpeg_start_decompress(fDecoderMgr->dinfo())) { |
| 496 SkCodecPrintf("start decompress failed\n"); | 497 SkCodecPrintf("start decompress failed\n"); |
| 497 return NULL; | 498 return NULL; |
| 498 } | 499 } |
| 499 | 500 |
| 500 // Return the new scanline decoder | 501 // Return the new scanline decoder |
| 501 return SkNEW_ARGS(SkJpegScanlineDecoder, (dstInfo, this)); | 502 return SkNEW_ARGS(SkJpegScanlineDecoder, (dstInfo, this)); |
| 502 } | 503 } |
| OLD | NEW |