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 |