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 |