Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Side by Side Diff: src/codec/SkJpegCodec.cpp

Issue 1212593003: Destroy SkScanlineDecoder in the SkCodec subclass destructors (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Detachable SkScanlineDecoder Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 279 matching lines...) Expand 10 before | Expand all | Expand 10 after
290 fSrcRowBytes = SkSwizzler::BytesPerPixel(srcConfig) * dstInfo.width(); 290 fSrcRowBytes = SkSwizzler::BytesPerPixel(srcConfig) * dstInfo.width();
291 } 291 }
292 292
293 /* 293 /*
294 * Performs the jpeg decode 294 * Performs the jpeg decode
295 */ 295 */
296 SkCodec::Result SkJpegCodec::onGetPixels(const SkImageInfo& dstInfo, 296 SkCodec::Result SkJpegCodec::onGetPixels(const SkImageInfo& dstInfo,
297 void* dst, size_t dstRowBytes, 297 void* dst, size_t dstRowBytes,
298 const Options& options, SkPMColor*, int *) { 298 const Options& options, SkPMColor*, int *) {
299 299
300 // Do not allow a regular decode if the caller has asked for a scanline deco der
301 if (NULL != this->scanlineDecoder()) {
302 return fDecoderMgr->returnFailure("cannot getPixels() if a scanline deco der has been"
303 "created", kInvalidParameters);
304 }
305
300 // Rewind the stream if needed 306 // Rewind the stream if needed
301 if (!this->handleRewind()) { 307 if (!this->handleRewind()) {
302 fDecoderMgr->returnFailure("could not rewind stream", kCouldNotRewind); 308 return fDecoderMgr->returnFailure("could not rewind stream", kCouldNotRe wind);
303 } 309 }
304 310
305 // Get a pointer to the decompress info since we will use it quite frequentl y 311 // Get a pointer to the decompress info since we will use it quite frequentl y
306 jpeg_decompress_struct* dinfo = fDecoderMgr->dinfo(); 312 jpeg_decompress_struct* dinfo = fDecoderMgr->dinfo();
307 313
308 // Set the jump location for libjpeg errors 314 // Set the jump location for libjpeg errors
309 if (setjmp(fDecoderMgr->getJmpBuf())) { 315 if (setjmp(fDecoderMgr->getJmpBuf())) {
310 return fDecoderMgr->returnFailure("setjmp", kInvalidInput); 316 return fDecoderMgr->returnFailure("setjmp", kInvalidInput);
311 } 317 }
312 318
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
381 jpeg_finish_decompress(dinfo); 387 jpeg_finish_decompress(dinfo);
382 return fDecoderMgr->returnFailure("Incomplete image data", kIncomple teInput); 388 return fDecoderMgr->returnFailure("Incomplete image data", kIncomple teInput);
383 } 389 }
384 } 390 }
385 jpeg_finish_decompress(dinfo); 391 jpeg_finish_decompress(dinfo);
386 392
387 return kSuccess; 393 return kSuccess;
388 } 394 }
389 395
390 /* 396 /*
397 * We override the destructor to ensure that the scanline decoder is left in a
398 * finished state before destroying the decode manager.
399 */
400 SkJpegCodec::~SkJpegCodec() {
401 SkAutoTDelete<SkScanlineDecoder> decoder(this->detachScanlineDecoder());
402 if (NULL != decoder) {
403 if (setjmp(fDecoderMgr->getJmpBuf())) {
404 SkCodecPrintf("setjmp: Error in libjpeg finish_decompress\n");
scroggo 2015/06/30 20:59:58 Do we need this error message? I guess it could be
msarett 2015/06/30 21:33:00 I would lean towards keeping it. It doesn't print
405 return;
406 }
407
408 // We may not have decoded the entire image. Prevent libjpeg-turbo from failing on a
409 // partial decode.
410 fDecoderMgr->dinfo()->output_scanline = this->getInfo().height();
411 jpeg_finish_decompress(fDecoderMgr->dinfo());
412 }
413 }
414
415 /*
391 * Enable scanline decoding for jpegs 416 * Enable scanline decoding for jpegs
392 */ 417 */
393 class SkJpegScanlineDecoder : public SkScanlineDecoder { 418 class SkJpegScanlineDecoder : public SkScanlineDecoder {
394 public: 419 public:
395 SkJpegScanlineDecoder(const SkImageInfo& dstInfo, SkJpegCodec* codec) 420 SkJpegScanlineDecoder(const SkImageInfo& dstInfo, SkJpegCodec* codec)
396 : INHERITED(dstInfo) 421 : INHERITED(dstInfo)
397 , fCodec(codec) 422 , fCodec(codec)
398 { 423 {
399 fStorage.reset(fCodec->fSrcRowBytes); 424 fStorage.reset(fCodec->fSrcRowBytes);
400 fSrcRow = static_cast<uint8_t*>(fStorage.get()); 425 fSrcRow = static_cast<uint8_t*>(fStorage.get());
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
436 } 461 }
437 462
438 // Read rows but ignore the output 463 // Read rows but ignore the output
439 for (int y = 0; y < count; y++) { 464 for (int y = 0; y < count; y++) {
440 jpeg_read_scanlines(fCodec->fDecoderMgr->dinfo(), &fSrcRow, 1); 465 jpeg_read_scanlines(fCodec->fDecoderMgr->dinfo(), &fSrcRow, 1);
441 } 466 }
442 467
443 return SkImageGenerator::kSuccess; 468 return SkImageGenerator::kSuccess;
444 } 469 }
445 470
446 void onFinish() override {
447 if (setjmp(fCodec->fDecoderMgr->getJmpBuf())) {
448 SkCodecPrintf("setjmp: Error in libjpeg finish_decompress\n");
449 return;
450 }
451
452 jpeg_finish_decompress(fCodec->fDecoderMgr->dinfo());
453 }
454
455 private: 471 private:
456 SkJpegCodec* fCodec; // unowned 472 SkJpegCodec* fCodec; // unowned
457 SkAutoMalloc fStorage; 473 SkAutoMalloc fStorage;
458 uint8_t* fSrcRow; // ptr into fStorage 474 uint8_t* fSrcRow; // ptr into fStorage
459 475
460 typedef SkScanlineDecoder INHERITED; 476 typedef SkScanlineDecoder INHERITED;
461 }; 477 };
462 478
463 SkScanlineDecoder* SkJpegCodec::onGetScanlineDecoder(const SkImageInfo& dstInfo, 479 SkScanlineDecoder* SkJpegCodec::onGetScanlineDecoder(const SkImageInfo& dstInfo,
464 const Options& options, SkPMColor ctable[], int* ctableCount) { 480 const Options& options, SkPMColor ctable[], int* ctableCount) {
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
496 // Create the swizzler 512 // Create the swizzler
497 this->initializeSwizzler(dstInfo, NULL, dstInfo.minRowBytes(), options); 513 this->initializeSwizzler(dstInfo, NULL, dstInfo.minRowBytes(), options);
498 if (NULL == fSwizzler) { 514 if (NULL == fSwizzler) {
499 SkCodecPrintf("Could not create swizzler\n"); 515 SkCodecPrintf("Could not create swizzler\n");
500 return NULL; 516 return NULL;
501 } 517 }
502 518
503 // Return the new scanline decoder 519 // Return the new scanline decoder
504 return SkNEW_ARGS(SkJpegScanlineDecoder, (dstInfo, this)); 520 return SkNEW_ARGS(SkJpegScanlineDecoder, (dstInfo, this));
505 } 521 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698