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 364 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
375 turbo_jpeg_finish_decompress(dinfo); | 375 turbo_jpeg_finish_decompress(dinfo); |
376 | 376 |
377 return kSuccess; | 377 return kSuccess; |
378 } | 378 } |
379 | 379 |
380 /* | 380 /* |
381 * Enable scanline decoding for jpegs | 381 * Enable scanline decoding for jpegs |
382 */ | 382 */ |
383 class SkJpegScanlineDecoder : public SkScanlineDecoder { | 383 class SkJpegScanlineDecoder : public SkScanlineDecoder { |
384 public: | 384 public: |
385 SkJpegScanlineDecoder(const SkImageInfo& dstInfo, SkJpegCodec* codec) | 385 SkJpegScanlineDecoder(const SkImageInfo& srcInfo, SkJpegCodec* codec) |
386 : INHERITED(dstInfo) | 386 : INHERITED(srcInfo) |
387 , fCodec(codec) | 387 , fCodec(codec) |
388 {} | 388 {} |
389 | 389 |
| 390 SkCodec::Result onReset(const SkImageInfo& dstInfo, const SkCodec::Options&
options, |
| 391 SkPMColor ctable[], int* ctableCount) override { |
| 392 |
| 393 // Rewind the stream if needed |
| 394 if (!fCodec->handleRewind()) { |
| 395 return SkCodec::kCouldNotRewind; |
| 396 } |
| 397 |
| 398 // Set the jump location for libjpeg errors |
| 399 if (setjmp(fCodec->fDecoderMgr->getJmpBuf())) { |
| 400 SkCodecPrintf("setjmp: Error from libjpeg\n"); |
| 401 return SkCodec::kInvalidInput; |
| 402 } |
| 403 |
| 404 // Check if we can decode to the requested destination and set the outpu
t color space |
| 405 if (!fCodec->setOutputColorSpace(dstInfo)) { |
| 406 return SkCodec::kInvalidConversion; |
| 407 } |
| 408 |
| 409 // Perform the necessary scaling |
| 410 if (!fCodec->scaleToDimensions(dstInfo.width(), dstInfo.height())) { |
| 411 return SkCodec::kInvalidScale; |
| 412 } |
| 413 |
| 414 // Now, given valid output dimensions, we can start the decompress |
| 415 if (!turbo_jpeg_start_decompress(fCodec->fDecoderMgr->dinfo())) { |
| 416 SkCodecPrintf("start decompress failed\n"); |
| 417 return SkCodec::kInvalidInput; |
| 418 } |
| 419 |
| 420 return SkCodec::kSuccess; |
| 421 } |
| 422 |
390 virtual ~SkJpegScanlineDecoder() { | 423 virtual ~SkJpegScanlineDecoder() { |
391 if (setjmp(fCodec->fDecoderMgr->getJmpBuf())) { | 424 if (setjmp(fCodec->fDecoderMgr->getJmpBuf())) { |
392 SkCodecPrintf("setjmp: Error in libjpeg finish_decompress\n"); | 425 SkCodecPrintf("setjmp: Error in libjpeg finish_decompress\n"); |
393 return; | 426 return; |
394 } | 427 } |
395 | 428 |
396 // We may not have decoded the entire image. Prevent libjpeg-turbo from
failing on a | 429 // We may not have decoded the entire image. Prevent libjpeg-turbo from
failing on a |
397 // partial decode. | 430 // partial decode. |
398 fCodec->fDecoderMgr->dinfo()->output_scanline = fCodec->getInfo().height
(); | 431 fCodec->fDecoderMgr->dinfo()->output_scanline = fCodec->getInfo().height
(); |
399 turbo_jpeg_finish_decompress(fCodec->fDecoderMgr->dinfo()); | 432 turbo_jpeg_finish_decompress(fCodec->fDecoderMgr->dinfo()); |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
449 | 482 |
450 return SkCodec::kSuccess; | 483 return SkCodec::kSuccess; |
451 } | 484 } |
452 | 485 |
453 private: | 486 private: |
454 SkAutoTDelete<SkJpegCodec> fCodec; | 487 SkAutoTDelete<SkJpegCodec> fCodec; |
455 | 488 |
456 typedef SkScanlineDecoder INHERITED; | 489 typedef SkScanlineDecoder INHERITED; |
457 }; | 490 }; |
458 | 491 |
459 SkScanlineDecoder* SkJpegCodec::onGetScanlineDecoder(const SkImageInfo& dstInfo, | 492 SkScanlineDecoder* SkJpegCodec::NewSDFromStream(SkStream* stream) { |
460 const Options& options, SkPMColor ctable[], int* ctableCount) { | |
461 | |
462 // Rewind the stream if needed | |
463 if (!this->handleRewind()) { | |
464 SkCodecPrintf("Could not rewind\n"); | |
465 return NULL; | |
466 } | |
467 | |
468 // Set the jump location for libjpeg errors | |
469 if (setjmp(fDecoderMgr->getJmpBuf())) { | |
470 SkCodecPrintf("setjmp: Error from libjpeg\n"); | |
471 return NULL; | |
472 } | |
473 | |
474 SkStream* stream = this->stream()->duplicate(); | |
475 if (!stream) { | |
476 return NULL; | |
477 } | |
478 SkAutoTDelete<SkJpegCodec> codec(static_cast<SkJpegCodec*>(SkJpegCodec::NewF
romStream(stream))); | 493 SkAutoTDelete<SkJpegCodec> codec(static_cast<SkJpegCodec*>(SkJpegCodec::NewF
romStream(stream))); |
479 if (!codec) { | 494 if (!codec) { |
480 return NULL; | 495 return NULL; |
481 } | 496 } |
482 | 497 |
483 // Check if we can decode to the requested destination and set the output co
lor space | 498 const SkImageInfo& srcInfo = codec->getInfo(); |
484 if (!codec->setOutputColorSpace(dstInfo)) { | |
485 SkCodecPrintf("Cannot convert to output type\n"); | |
486 return NULL; | |
487 } | |
488 | |
489 // Perform the necessary scaling | |
490 if (!codec->scaleToDimensions(dstInfo.width(), dstInfo.height())) { | |
491 SkCodecPrintf("Cannot scale to output dimensions\n"); | |
492 return NULL; | |
493 } | |
494 | |
495 // Now, given valid output dimensions, we can start the decompress | |
496 if (!turbo_jpeg_start_decompress(codec->fDecoderMgr->dinfo())) { | |
497 SkCodecPrintf("start decompress failed\n"); | |
498 return NULL; | |
499 } | |
500 | |
501 // Return the new scanline decoder | 499 // Return the new scanline decoder |
502 return SkNEW_ARGS(SkJpegScanlineDecoder, (dstInfo, codec.detach())); | 500 return SkNEW_ARGS(SkJpegScanlineDecoder, (srcInfo, codec.detach())); |
503 } | 501 } |
OLD | NEW |