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 337 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
348 // behavior is unspecified but SkCodec consistently uses black as | 348 // behavior is unspecified but SkCodec consistently uses black as |
349 // the fill color for opaque images. If the destination is kGray, | 349 // the fill color for opaque images. If the destination is kGray, |
350 // the low 8 bits of SK_ColorBLACK will be used. Conveniently, | 350 // the low 8 bits of SK_ColorBLACK will be used. Conveniently, |
351 // these are zeros, which is the representation for black in kGray. | 351 // these are zeros, which is the representation for black in kGray. |
352 // If the destination is kRGB_565, the low 16 bits of SK_ColorBLACK | 352 // If the destination is kRGB_565, the low 16 bits of SK_ColorBLACK |
353 // will be used. Conveniently, these are zeros, which is the | 353 // will be used. Conveniently, these are zeros, which is the |
354 // representation for black in kRGB_565. | 354 // representation for black in kRGB_565. |
355 SkSwizzler::Fill(dstRow, dstInfo, dstRowBytes, dstHeight - y, | 355 SkSwizzler::Fill(dstRow, dstInfo, dstRowBytes, dstHeight - y, |
356 SK_ColorBLACK, nullptr, options.fZeroInitialized); | 356 SK_ColorBLACK, nullptr, options.fZeroInitialized); |
357 | 357 |
358 // Prevent libjpeg from failing on incomplete decode | |
359 dinfo->output_scanline = dstHeight; | |
360 | |
361 // Finish the decode and indicate that the input was incomplete. | |
362 jpeg_finish_decompress(dinfo); | |
363 return fDecoderMgr->returnFailure("Incomplete image data", kIncomple
teInput); | 358 return fDecoderMgr->returnFailure("Incomplete image data", kIncomple
teInput); |
364 } | 359 } |
365 | 360 |
366 // Convert to RGBA if necessary | 361 // Convert to RGBA if necessary |
367 if (JCS_CMYK == dinfo->out_color_space) { | 362 if (JCS_CMYK == dinfo->out_color_space) { |
368 convert_CMYK_to_RGBA(dstRow, dstInfo.width()); | 363 convert_CMYK_to_RGBA(dstRow, dstInfo.width()); |
369 } | 364 } |
370 | 365 |
371 // Move to the next row | 366 // Move to the next row |
372 dstRow = SkTAddOffset<JSAMPLE>(dstRow, dstRowBytes); | 367 dstRow = SkTAddOffset<JSAMPLE>(dstRow, dstRowBytes); |
373 } | 368 } |
374 jpeg_finish_decompress(dinfo); | |
375 | 369 |
376 return kSuccess; | 370 return kSuccess; |
377 } | 371 } |
378 | 372 |
379 SkCodec::Result SkJpegCodec::initializeSwizzler(const SkImageInfo& info, const O
ptions& options) { | 373 SkCodec::Result SkJpegCodec::initializeSwizzler(const SkImageInfo& info, const O
ptions& options) { |
380 SkSwizzler::SrcConfig srcConfig; | 374 SkSwizzler::SrcConfig srcConfig; |
381 switch (info.colorType()) { | 375 switch (info.colorType()) { |
382 case kGray_8_SkColorType: | 376 case kGray_8_SkColorType: |
383 srcConfig = SkSwizzler::kGray; | 377 srcConfig = SkSwizzler::kGray; |
384 break; | 378 break; |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
440 | 434 |
441 // Now, given valid output dimensions, we can start the decompress | 435 // Now, given valid output dimensions, we can start the decompress |
442 if (!jpeg_start_decompress(fDecoderMgr->dinfo())) { | 436 if (!jpeg_start_decompress(fDecoderMgr->dinfo())) { |
443 SkCodecPrintf("start decompress failed\n"); | 437 SkCodecPrintf("start decompress failed\n"); |
444 return kInvalidInput; | 438 return kInvalidInput; |
445 } | 439 } |
446 | 440 |
447 return kSuccess; | 441 return kSuccess; |
448 } | 442 } |
449 | 443 |
450 SkJpegCodec::~SkJpegCodec() { | |
451 // FIXME: This probably does not need to be called after a full decode | |
452 // FIXME: Is it safe to call when it doesn't need to be called? | |
453 if (setjmp(fDecoderMgr->getJmpBuf())) { | |
454 SkCodecPrintf("setjmp: Error in libjpeg finish_decompress\n"); | |
455 return; | |
456 } | |
457 | |
458 // We may not have decoded the entire image. Prevent libjpeg-turbo from fai
ling on a | |
459 // partial decode. | |
460 fDecoderMgr->dinfo()->output_scanline = this->getInfo().height(); | |
461 jpeg_finish_decompress(fDecoderMgr->dinfo()); | |
462 } | |
463 | |
464 SkCodec::Result SkJpegCodec::onGetScanlines(void* dst, int count, size_t rowByte
s) { | 444 SkCodec::Result SkJpegCodec::onGetScanlines(void* dst, int count, size_t rowByte
s) { |
465 // Set the jump location for libjpeg errors | 445 // Set the jump location for libjpeg errors |
466 if (setjmp(fDecoderMgr->getJmpBuf())) { | 446 if (setjmp(fDecoderMgr->getJmpBuf())) { |
467 return fDecoderMgr->returnFailure("setjmp", kInvalidInput); | 447 return fDecoderMgr->returnFailure("setjmp", kInvalidInput); |
468 } | 448 } |
469 // Read rows one at a time | 449 // Read rows one at a time |
470 JSAMPLE* dstRow; | 450 JSAMPLE* dstRow; |
471 if (fSwizzler) { | 451 if (fSwizzler) { |
472 // write data to storage row, then sample using swizzler | 452 // write data to storage row, then sample using swizzler |
473 dstRow = fSrcRow; | 453 dstRow = fSrcRow; |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
517 // Set the jump location for libjpeg errors | 497 // Set the jump location for libjpeg errors |
518 if (setjmp(fDecoderMgr->getJmpBuf())) { | 498 if (setjmp(fDecoderMgr->getJmpBuf())) { |
519 return fDecoderMgr->returnFailure("setjmp", kInvalidInput); | 499 return fDecoderMgr->returnFailure("setjmp", kInvalidInput); |
520 } | 500 } |
521 | 501 |
522 jpeg_skip_scanlines(fDecoderMgr->dinfo(), count); | 502 jpeg_skip_scanlines(fDecoderMgr->dinfo(), count); |
523 | 503 |
524 return kSuccess; | 504 return kSuccess; |
525 } | 505 } |
526 | 506 |
OLD | NEW |