| 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 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 109 } | 109 } |
| 110 | 110 |
| 111 // Initialize the decompress info and the source manager | 111 // Initialize the decompress info and the source manager |
| 112 decoderMgr->init(); | 112 decoderMgr->init(); |
| 113 | 113 |
| 114 // Read the jpeg header | 114 // Read the jpeg header |
| 115 if (JPEG_HEADER_OK != chromium_jpeg_read_header(decoderMgr->dinfo(), true))
{ | 115 if (JPEG_HEADER_OK != chromium_jpeg_read_header(decoderMgr->dinfo(), true))
{ |
| 116 return decoderMgr->returnFalse("read_header"); | 116 return decoderMgr->returnFalse("read_header"); |
| 117 } | 117 } |
| 118 | 118 |
| 119 if (NULL != codecOut) { | 119 if (nullptr != codecOut) { |
| 120 // Recommend the color type to decode to | 120 // Recommend the color type to decode to |
| 121 const SkColorType colorType = decoderMgr->getColorType(); | 121 const SkColorType colorType = decoderMgr->getColorType(); |
| 122 | 122 |
| 123 // Create image info object and the codec | 123 // Create image info object and the codec |
| 124 const SkImageInfo& imageInfo = SkImageInfo::Make(decoderMgr->dinfo()->im
age_width, | 124 const SkImageInfo& imageInfo = SkImageInfo::Make(decoderMgr->dinfo()->im
age_width, |
| 125 decoderMgr->dinfo()->image_height, colorType, kOpaque_SkAlphaTyp
e); | 125 decoderMgr->dinfo()->image_height, colorType, kOpaque_SkAlphaTyp
e); |
| 126 *codecOut = new SkJpegCodec(imageInfo, stream, decoderMgr.detach()); | 126 *codecOut = new SkJpegCodec(imageInfo, stream, decoderMgr.detach()); |
| 127 } else { | 127 } else { |
| 128 SkASSERT(NULL != decoderMgrOut); | 128 SkASSERT(nullptr != decoderMgrOut); |
| 129 *decoderMgrOut = decoderMgr.detach(); | 129 *decoderMgrOut = decoderMgr.detach(); |
| 130 } | 130 } |
| 131 return true; | 131 return true; |
| 132 } | 132 } |
| 133 | 133 |
| 134 SkCodec* SkJpegCodec::NewFromStream(SkStream* stream) { | 134 SkCodec* SkJpegCodec::NewFromStream(SkStream* stream) { |
| 135 SkAutoTDelete<SkStream> streamDeleter(stream); | 135 SkAutoTDelete<SkStream> streamDeleter(stream); |
| 136 SkCodec* codec = NULL; | 136 SkCodec* codec = nullptr; |
| 137 if (ReadHeader(stream, &codec, NULL)) { | 137 if (ReadHeader(stream, &codec, nullptr)) { |
| 138 // Codec has taken ownership of the stream, we do not need to delete it | 138 // Codec has taken ownership of the stream, we do not need to delete it |
| 139 SkASSERT(codec); | 139 SkASSERT(codec); |
| 140 streamDeleter.detach(); | 140 streamDeleter.detach(); |
| 141 return codec; | 141 return codec; |
| 142 } | 142 } |
| 143 return NULL; | 143 return nullptr; |
| 144 } | 144 } |
| 145 | 145 |
| 146 SkJpegCodec::SkJpegCodec(const SkImageInfo& srcInfo, SkStream* stream, | 146 SkJpegCodec::SkJpegCodec(const SkImageInfo& srcInfo, SkStream* stream, |
| 147 JpegDecoderMgr* decoderMgr) | 147 JpegDecoderMgr* decoderMgr) |
| 148 : INHERITED(srcInfo, stream) | 148 : INHERITED(srcInfo, stream) |
| 149 , fDecoderMgr(decoderMgr) | 149 , fDecoderMgr(decoderMgr) |
| 150 {} | 150 {} |
| 151 | 151 |
| 152 /* | 152 /* |
| 153 * Return the row bytes of a particular image type and width | 153 * Return the row bytes of a particular image type and width |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 192 dinfo.num_components = 0; | 192 dinfo.num_components = 0; |
| 193 dinfo.scale_num = num; | 193 dinfo.scale_num = num; |
| 194 dinfo.scale_denom = denom; | 194 dinfo.scale_denom = denom; |
| 195 chromium_jpeg_calc_output_dimensions(&dinfo); | 195 chromium_jpeg_calc_output_dimensions(&dinfo); |
| 196 | 196 |
| 197 // Return the calculated output dimensions for the given scale | 197 // Return the calculated output dimensions for the given scale |
| 198 return SkISize::Make(dinfo.output_width, dinfo.output_height); | 198 return SkISize::Make(dinfo.output_width, dinfo.output_height); |
| 199 } | 199 } |
| 200 | 200 |
| 201 bool SkJpegCodec::onRewind() { | 201 bool SkJpegCodec::onRewind() { |
| 202 JpegDecoderMgr* decoderMgr = NULL; | 202 JpegDecoderMgr* decoderMgr = nullptr; |
| 203 if (!ReadHeader(this->stream(), NULL, &decoderMgr)) { | 203 if (!ReadHeader(this->stream(), nullptr, &decoderMgr)) { |
| 204 return fDecoderMgr->returnFalse("could not rewind"); | 204 return fDecoderMgr->returnFalse("could not rewind"); |
| 205 } | 205 } |
| 206 SkASSERT(NULL != decoderMgr); | 206 SkASSERT(nullptr != decoderMgr); |
| 207 fDecoderMgr.reset(decoderMgr); | 207 fDecoderMgr.reset(decoderMgr); |
| 208 return true; | 208 return true; |
| 209 } | 209 } |
| 210 | 210 |
| 211 /* | 211 /* |
| 212 * Checks if the conversion between the input image and the requested output | 212 * Checks if the conversion between the input image and the requested output |
| 213 * image has been implemented | 213 * image has been implemented |
| 214 * Sets the output color space | 214 * Sets the output color space |
| 215 */ | 215 */ |
| 216 bool SkJpegCodec::setOutputColorSpace(const SkImageInfo& dst) { | 216 bool SkJpegCodec::setOutputColorSpace(const SkImageInfo& dst) { |
| (...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 351 // behavior is unspecified but SkCodec consistently uses black as | 351 // behavior is unspecified but SkCodec consistently uses black as |
| 352 // the fill color for opaque images. If the destination is kGray, | 352 // the fill color for opaque images. If the destination is kGray, |
| 353 // the low 8 bits of SK_ColorBLACK will be used. Conveniently, | 353 // the low 8 bits of SK_ColorBLACK will be used. Conveniently, |
| 354 // these are zeros, which is the representation for black in kGray. | 354 // these are zeros, which is the representation for black in kGray. |
| 355 // If the destination is kRGB_565, the low 16 bits of SK_ColorBLACK | 355 // If the destination is kRGB_565, the low 16 bits of SK_ColorBLACK |
| 356 // will be used. Conveniently, these are zeros, which is the | 356 // will be used. Conveniently, these are zeros, which is the |
| 357 // representation for black in kRGB_565. | 357 // representation for black in kRGB_565. |
| 358 if (kNo_ZeroInitialized == options.fZeroInitialized || | 358 if (kNo_ZeroInitialized == options.fZeroInitialized || |
| 359 kN32_SkColorType == dstInfo.colorType()) { | 359 kN32_SkColorType == dstInfo.colorType()) { |
| 360 SkSwizzler::Fill(dstRow, dstInfo, dstRowBytes, dstHeight - y, | 360 SkSwizzler::Fill(dstRow, dstInfo, dstRowBytes, dstHeight - y, |
| 361 SK_ColorBLACK, NULL); | 361 SK_ColorBLACK, nullptr); |
| 362 } | 362 } |
| 363 | 363 |
| 364 // Prevent libjpeg from failing on incomplete decode | 364 // Prevent libjpeg from failing on incomplete decode |
| 365 dinfo->output_scanline = dstHeight; | 365 dinfo->output_scanline = dstHeight; |
| 366 | 366 |
| 367 // Finish the decode and indicate that the input was incomplete. | 367 // Finish the decode and indicate that the input was incomplete. |
| 368 chromium_jpeg_finish_decompress(dinfo); | 368 chromium_jpeg_finish_decompress(dinfo); |
| 369 return fDecoderMgr->returnFailure("Incomplete image data", kIncomple
teInput); | 369 return fDecoderMgr->returnFailure("Incomplete image data", kIncomple
teInput); |
| 370 } | 370 } |
| 371 | 371 |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 418 srcConfig = SkSwizzler::kBGRX; | 418 srcConfig = SkSwizzler::kBGRX; |
| 419 break; | 419 break; |
| 420 case kRGB_565_SkColorType: | 420 case kRGB_565_SkColorType: |
| 421 srcConfig = SkSwizzler::kRGB_565; | 421 srcConfig = SkSwizzler::kRGB_565; |
| 422 break; | 422 break; |
| 423 default: | 423 default: |
| 424 //would have exited before now if the colorType was supported by
jpeg | 424 //would have exited before now if the colorType was supported by
jpeg |
| 425 SkASSERT(false); | 425 SkASSERT(false); |
| 426 } | 426 } |
| 427 | 427 |
| 428 fSwizzler.reset(SkSwizzler::CreateSwizzler(srcConfig, NULL, info, option
s.fZeroInitialized, | 428 fSwizzler.reset(SkSwizzler::CreateSwizzler(srcConfig, nullptr, info, opt
ions.fZeroInitialized, |
| 429 this->getInfo())); | 429 this->getInfo())); |
| 430 if (!fSwizzler) { | 430 if (!fSwizzler) { |
| 431 // FIXME: CreateSwizzler could fail for another reason. | 431 // FIXME: CreateSwizzler could fail for another reason. |
| 432 return SkCodec::kUnimplemented; | 432 return SkCodec::kUnimplemented; |
| 433 } | 433 } |
| 434 return SkCodec::kSuccess; | 434 return SkCodec::kSuccess; |
| 435 } | 435 } |
| 436 | 436 |
| 437 SkCodec::Result onStart(const SkImageInfo& dstInfo, const SkCodec::Options&
options, | 437 SkCodec::Result onStart(const SkImageInfo& dstInfo, const SkCodec::Options&
options, |
| 438 SkPMColor ctable[], int* ctableCount) override { | 438 SkPMColor ctable[], int* ctableCount) override { |
| (...skipping 23 matching lines...) Expand all Loading... |
| 462 } | 462 } |
| 463 // create swizzler for sampling | 463 // create swizzler for sampling |
| 464 SkCodec::Result result = this->initializeSwizzler(dstInfo, options); | 464 SkCodec::Result result = this->initializeSwizzler(dstInfo, options); |
| 465 if (SkCodec::kSuccess != result) { | 465 if (SkCodec::kSuccess != result) { |
| 466 SkCodecPrintf("failed to initialize the swizzler.\n"); | 466 SkCodecPrintf("failed to initialize the swizzler.\n"); |
| 467 return result; | 467 return result; |
| 468 } | 468 } |
| 469 fStorage.reset(get_row_bytes(fCodec->fDecoderMgr->dinfo())); | 469 fStorage.reset(get_row_bytes(fCodec->fDecoderMgr->dinfo())); |
| 470 fSrcRow = static_cast<uint8_t*>(fStorage.get()); | 470 fSrcRow = static_cast<uint8_t*>(fStorage.get()); |
| 471 } else { | 471 } else { |
| 472 fSrcRow = NULL; | 472 fSrcRow = nullptr; |
| 473 fSwizzler.reset(NULL); | 473 fSwizzler.reset(nullptr); |
| 474 } | 474 } |
| 475 | 475 |
| 476 // Now, given valid output dimensions, we can start the decompress | 476 // Now, given valid output dimensions, we can start the decompress |
| 477 if (!chromium_jpeg_start_decompress(fCodec->fDecoderMgr->dinfo())) { | 477 if (!chromium_jpeg_start_decompress(fCodec->fDecoderMgr->dinfo())) { |
| 478 SkCodecPrintf("start decompress failed\n"); | 478 SkCodecPrintf("start decompress failed\n"); |
| 479 return SkCodec::kInvalidInput; | 479 return SkCodec::kInvalidInput; |
| 480 } | 480 } |
| 481 | 481 |
| 482 fOpts = options; | 482 fOpts = options; |
| 483 | 483 |
| (...skipping 28 matching lines...) Expand all Loading... |
| 512 } | 512 } |
| 513 | 513 |
| 514 for (int y = 0; y < count; y++) { | 514 for (int y = 0; y < count; y++) { |
| 515 // Read row of the image | 515 // Read row of the image |
| 516 uint32_t rowsDecoded = | 516 uint32_t rowsDecoded = |
| 517 chromium_jpeg_read_scanlines(fCodec->fDecoderMgr->dinfo(), &
dstRow, 1); | 517 chromium_jpeg_read_scanlines(fCodec->fDecoderMgr->dinfo(), &
dstRow, 1); |
| 518 if (rowsDecoded != 1) { | 518 if (rowsDecoded != 1) { |
| 519 if (SkCodec::kNo_ZeroInitialized == fOpts.fZeroInitialized || | 519 if (SkCodec::kNo_ZeroInitialized == fOpts.fZeroInitialized || |
| 520 kN32_SkColorType == this->dstInfo().colorType()) { | 520 kN32_SkColorType == this->dstInfo().colorType()) { |
| 521 SkSwizzler::Fill(dstRow, this->dstInfo(), rowBytes, | 521 SkSwizzler::Fill(dstRow, this->dstInfo(), rowBytes, |
| 522 count - y, SK_ColorBLACK, NULL); | 522 count - y, SK_ColorBLACK, nullptr); |
| 523 } | 523 } |
| 524 fCodec->fDecoderMgr->dinfo()->output_scanline = this->dstInfo().
height(); | 524 fCodec->fDecoderMgr->dinfo()->output_scanline = this->dstInfo().
height(); |
| 525 return SkCodec::kIncompleteInput; | 525 return SkCodec::kIncompleteInput; |
| 526 } | 526 } |
| 527 | 527 |
| 528 // Convert to RGBA if necessary | 528 // Convert to RGBA if necessary |
| 529 if (JCS_CMYK == fCodec->fDecoderMgr->dinfo()->out_color_space) { | 529 if (JCS_CMYK == fCodec->fDecoderMgr->dinfo()->out_color_space) { |
| 530 convert_CMYK_to_RGBA(dstRow, fCodec->fDecoderMgr->dinfo()->outpu
t_width); | 530 convert_CMYK_to_RGBA(dstRow, fCodec->fDecoderMgr->dinfo()->outpu
t_width); |
| 531 } | 531 } |
| 532 | 532 |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 573 uint8_t* fSrcRow; // Only used if sampling is needed | 573 uint8_t* fSrcRow; // Only used if sampling is needed |
| 574 SkCodec::Options fOpts; | 574 SkCodec::Options fOpts; |
| 575 SkAutoTDelete<SkSwizzler> fSwizzler; | 575 SkAutoTDelete<SkSwizzler> fSwizzler; |
| 576 | 576 |
| 577 typedef SkScanlineDecoder INHERITED; | 577 typedef SkScanlineDecoder INHERITED; |
| 578 }; | 578 }; |
| 579 | 579 |
| 580 SkScanlineDecoder* SkJpegCodec::NewSDFromStream(SkStream* stream) { | 580 SkScanlineDecoder* SkJpegCodec::NewSDFromStream(SkStream* stream) { |
| 581 SkAutoTDelete<SkJpegCodec> codec(static_cast<SkJpegCodec*>(SkJpegCodec::NewF
romStream(stream))); | 581 SkAutoTDelete<SkJpegCodec> codec(static_cast<SkJpegCodec*>(SkJpegCodec::NewF
romStream(stream))); |
| 582 if (!codec) { | 582 if (!codec) { |
| 583 return NULL; | 583 return nullptr; |
| 584 } | 584 } |
| 585 | 585 |
| 586 const SkImageInfo& srcInfo = codec->getInfo(); | 586 const SkImageInfo& srcInfo = codec->getInfo(); |
| 587 | 587 |
| 588 // Return the new scanline decoder | 588 // Return the new scanline decoder |
| 589 return new SkJpegScanlineDecoder(srcInfo, codec.detach()); | 589 return new SkJpegScanlineDecoder(srcInfo, codec.detach()); |
| 590 } | 590 } |
| OLD | NEW |