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

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

Issue 1390213002: Add subsetting to SkScanlineDecoder (Closed) Base URL: https://skia.googlesource.com/skia.git@fill-refactor
Patch Set: Response to comments Created 5 years, 2 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
« no previous file with comments | « src/codec/SkJpegCodec.h ('k') | src/codec/SkMaskSwizzler.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
170 } 170 }
171 171
172 /* 172 /*
173 * Return a valid set of output dimensions for this decoder, given an input scal e 173 * Return a valid set of output dimensions for this decoder, given an input scal e
174 */ 174 */
175 SkISize SkJpegCodec::onGetScaledDimensions(float desiredScale) const { 175 SkISize SkJpegCodec::onGetScaledDimensions(float desiredScale) const {
176 // libjpeg-turbo supports scaling by 1/8, 1/4, 3/8, 1/2, 5/8, 3/4, 7/8, and 1/1, so we will 176 // libjpeg-turbo supports scaling by 1/8, 1/4, 3/8, 1/2, 5/8, 3/4, 7/8, and 1/1, so we will
177 // support these as well 177 // support these as well
178 unsigned int num; 178 unsigned int num;
179 unsigned int denom = 8; 179 unsigned int denom = 8;
180 if (desiredScale > 0.875f) { 180 if (desiredScale >= 0.9375) {
181 num = 8; 181 num = 8;
182 } else if (desiredScale > 0.75f) { 182 } else if (desiredScale >= 0.8125) {
183 num = 7; 183 num = 7;
184 } else if (desiredScale > 0.625f) { 184 } else if (desiredScale >= 0.6875f) {
185 num = 6; 185 num = 6;
186 } else if (desiredScale > 0.5f) { 186 } else if (desiredScale >= 0.5625f) {
187 num = 5; 187 num = 5;
188 } else if (desiredScale > 0.375f) { 188 } else if (desiredScale >= 0.4375f) {
189 num = 4; 189 num = 4;
190 } else if (desiredScale > 0.25f) { 190 } else if (desiredScale >= 0.3125f) {
191 num = 3; 191 num = 3;
192 } else if (desiredScale > 0.125f) { 192 } else if (desiredScale >= 0.1875f) {
193 num = 2; 193 num = 2;
194 } else { 194 } else {
195 num = 1; 195 num = 1;
196 } 196 }
197 197
198 // Set up a fake decompress struct in order to use libjpeg to calculate outp ut dimensions 198 // Set up a fake decompress struct in order to use libjpeg to calculate outp ut dimensions
199 jpeg_decompress_struct dinfo; 199 jpeg_decompress_struct dinfo;
200 sk_bzero(&dinfo, sizeof(dinfo)); 200 sk_bzero(&dinfo, sizeof(dinfo));
201 dinfo.image_width = this->getInfo().width(); 201 dinfo.image_width = this->getInfo().width();
202 dinfo.image_height = this->getInfo().height(); 202 dinfo.image_height = this->getInfo().height();
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after
373 convert_CMYK_to_RGBA(dstRow, dstInfo.width()); 373 convert_CMYK_to_RGBA(dstRow, dstInfo.width());
374 } 374 }
375 375
376 // Move to the next row 376 // Move to the next row
377 dstRow = SkTAddOffset<JSAMPLE>(dstRow, dstRowBytes); 377 dstRow = SkTAddOffset<JSAMPLE>(dstRow, dstRowBytes);
378 } 378 }
379 379
380 return kSuccess; 380 return kSuccess;
381 } 381 }
382 382
383 SkSampler* SkJpegCodec::getSampler(bool createIfNecessary) { 383 void SkJpegCodec::initializeSwizzler(const SkImageInfo& dstInfo, const Options& options) {
384 if (!createIfNecessary || fSwizzler) {
385 SkASSERT(!fSwizzler || (fSrcRow && static_cast<uint8_t*>(fStorage.get()) == fSrcRow));
386 return fSwizzler;
387 }
388
389 const SkImageInfo& info = this->dstInfo();
390 SkSwizzler::SrcConfig srcConfig; 384 SkSwizzler::SrcConfig srcConfig;
391 switch (info.colorType()) { 385 switch (dstInfo.colorType()) {
392 case kGray_8_SkColorType: 386 case kGray_8_SkColorType:
393 srcConfig = SkSwizzler::kGray; 387 srcConfig = SkSwizzler::kGray;
394 break; 388 break;
395 case kRGBA_8888_SkColorType: 389 case kRGBA_8888_SkColorType:
396 srcConfig = SkSwizzler::kRGBX; 390 srcConfig = SkSwizzler::kRGBX;
397 break; 391 break;
398 case kBGRA_8888_SkColorType: 392 case kBGRA_8888_SkColorType:
399 srcConfig = SkSwizzler::kBGRX; 393 srcConfig = SkSwizzler::kBGRX;
400 break; 394 break;
401 case kRGB_565_SkColorType: 395 case kRGB_565_SkColorType:
402 srcConfig = SkSwizzler::kRGB_565; 396 srcConfig = SkSwizzler::kRGB_565;
403 break; 397 break;
404 default: 398 default:
405 // This function should only be called if the colorType is supported by jpeg 399 // This function should only be called if the colorType is supported by jpeg
406 SkASSERT(false); 400 SkASSERT(false);
407 } 401 }
408 402
409 fSwizzler.reset(SkSwizzler::CreateSwizzler(srcConfig, nullptr, info, 403 fSwizzler.reset(SkSwizzler::CreateSwizzler(srcConfig, nullptr, dstInfo, opti ons));
410 this->options().fZeroInitialized) ); 404 fStorage.reset(get_row_bytes(fDecoderMgr->dinfo()));
411 if (!fSwizzler) { 405 fSrcRow = static_cast<uint8_t*>(fStorage.get());
412 return nullptr; 406 }
407
408 SkSampler* SkJpegCodec::getSampler(bool createIfNecessary) {
409 if (!createIfNecessary || fSwizzler) {
410 SkASSERT(!fSwizzler || (fSrcRow && static_cast<uint8_t*>(fStorage.get()) == fSrcRow));
411 return fSwizzler;
413 } 412 }
414 413
415 fStorage.reset(get_row_bytes(fDecoderMgr->dinfo())); 414 this->initializeSwizzler(this->dstInfo(), this->options());
416 fSrcRow = static_cast<uint8_t*>(fStorage.get());
417 return fSwizzler; 415 return fSwizzler;
418 } 416 }
419 417
420 SkCodec::Result SkJpegCodec::onStartScanlineDecode(const SkImageInfo& dstInfo, 418 SkCodec::Result SkJpegCodec::onStartScanlineDecode(const SkImageInfo& dstInfo,
421 const Options& options, SkPMColor ctable[], int* ctableCount) { 419 const Options& options, SkPMColor ctable[], int* ctableCount) {
422 // Set the jump location for libjpeg errors 420 // Set the jump location for libjpeg errors
423 if (setjmp(fDecoderMgr->getJmpBuf())) { 421 if (setjmp(fDecoderMgr->getJmpBuf())) {
424 SkCodecPrintf("setjmp: Error from libjpeg\n"); 422 SkCodecPrintf("setjmp: Error from libjpeg\n");
425 return kInvalidInput; 423 return kInvalidInput;
426 } 424 }
427 425
428 // Check if we can decode to the requested destination and set the output co lor space 426 // Check if we can decode to the requested destination and set the output co lor space
429 if (!this->setOutputColorSpace(dstInfo)) { 427 if (!this->setOutputColorSpace(dstInfo)) {
430 return kInvalidConversion; 428 return kInvalidConversion;
431 } 429 }
432 430
433 // Remove objects used for sampling. 431 // Remove objects used for sampling.
434 fSwizzler.reset(nullptr); 432 fSwizzler.reset(nullptr);
435 fSrcRow = nullptr; 433 fSrcRow = nullptr;
436 fStorage.free(); 434 fStorage.free();
437 435
438 // Now, given valid output dimensions, we can start the decompress 436 // Now, given valid output dimensions, we can start the decompress
439 if (!jpeg_start_decompress(fDecoderMgr->dinfo())) { 437 if (!jpeg_start_decompress(fDecoderMgr->dinfo())) {
440 SkCodecPrintf("start decompress failed\n"); 438 SkCodecPrintf("start decompress failed\n");
441 return kInvalidInput; 439 return kInvalidInput;
442 } 440 }
443 441
442 // We will need a swizzler if we are performing a subset decode
443 if (options.fSubset) {
444 this->initializeSwizzler(dstInfo, options);
445 }
446
444 return kSuccess; 447 return kSuccess;
445 } 448 }
446 449
447 int SkJpegCodec::onGetScanlines(void* dst, int count, size_t rowBytes) { 450 int SkJpegCodec::onGetScanlines(void* dst, int count, size_t rowBytes) {
448 // Set the jump location for libjpeg errors 451 // Set the jump location for libjpeg errors
449 if (setjmp(fDecoderMgr->getJmpBuf())) { 452 if (setjmp(fDecoderMgr->getJmpBuf())) {
450 return fDecoderMgr->returnFailure("setjmp", kInvalidInput); 453 return fDecoderMgr->returnFailure("setjmp", kInvalidInput);
451 } 454 }
452 // Read rows one at a time 455 // Read rows one at a time
453 JSAMPLE* dstRow; 456 JSAMPLE* dstRow;
454 if (fSwizzler) { 457 if (fSwizzler) {
455 // write data to storage row, then sample using swizzler 458 // write data to storage row, then sample using swizzler
456 dstRow = fSrcRow; 459 dstRow = fSrcRow;
457 } else { 460 } else {
458 // write data directly to dst 461 // write data directly to dst
459 dstRow = (JSAMPLE*) dst; 462 dstRow = (JSAMPLE*) dst;
460 } 463 }
461 464
462 for (int y = 0; y < count; y++) { 465 for (int y = 0; y < count; y++) {
463 // Read row of the image 466 // Read row of the image
464 uint32_t rowsDecoded = jpeg_read_scanlines(fDecoderMgr->dinfo(), &dstRow , 1); 467 uint32_t rowsDecoded = jpeg_read_scanlines(fDecoderMgr->dinfo(), &dstRow , 1);
465 if (rowsDecoded != 1) { 468 if (rowsDecoded != 1) {
(...skipping 29 matching lines...) Expand all
495 #endif 498 #endif
496 499
497 bool SkJpegCodec::onSkipScanlines(int count) { 500 bool SkJpegCodec::onSkipScanlines(int count) {
498 // Set the jump location for libjpeg errors 501 // Set the jump location for libjpeg errors
499 if (setjmp(fDecoderMgr->getJmpBuf())) { 502 if (setjmp(fDecoderMgr->getJmpBuf())) {
500 return fDecoderMgr->returnFalse("setjmp"); 503 return fDecoderMgr->returnFalse("setjmp");
501 } 504 }
502 505
503 return count == jpeg_skip_scanlines(fDecoderMgr->dinfo(), count); 506 return count == jpeg_skip_scanlines(fDecoderMgr->dinfo(), count);
504 } 507 }
OLDNEW
« no previous file with comments | « src/codec/SkJpegCodec.h ('k') | src/codec/SkMaskSwizzler.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698