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

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

Issue 1321433002: Add subsetting to SkScaledCodec (Closed) Base URL: https://skia.googlesource.com/skia.git@gif-scan
Patch Set: 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
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 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
156 156
157 } 157 }
158 /* 158 /*
159 * Return a valid set of output dimensions for this decoder, given an input scal e 159 * Return a valid set of output dimensions for this decoder, given an input scal e
160 */ 160 */
161 SkISize SkJpegCodec::onGetScaledDimensions(float desiredScale) const { 161 SkISize SkJpegCodec::onGetScaledDimensions(float desiredScale) const {
162 // 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 162 // 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
163 // support these as well 163 // support these as well
164 long num; 164 long num;
165 long denom = 8; 165 long denom = 8;
166 if (desiredScale > 0.875f) { 166 if (desiredScale >= 0.9375) {
scroggo 2015/10/02 18:27:03 why did this change?
msarett 2015/10/06 23:01:27 IMO, it used to make sense to always round up, sin
167 num = 8; 167 num = 8;
168 } else if (desiredScale > 0.75f) { 168 } else if (desiredScale >= 0.8125) {
169 num = 7; 169 num = 7;
170 } else if (desiredScale > 0.625f) { 170 } else if (desiredScale >= 0.6875f) {
171 num = 6; 171 num = 6;
172 } else if (desiredScale > 0.5f) { 172 } else if (desiredScale >= 0.5625f) {
173 num = 5; 173 num = 5;
174 } else if (desiredScale > 0.375f) { 174 } else if (desiredScale >= 0.4375f) {
175 num = 4; 175 num = 4;
176 } else if (desiredScale > 0.25f) { 176 } else if (desiredScale >= 0.3125f) {
177 num = 3; 177 num = 3;
178 } else if (desiredScale > 0.125f) { 178 } else if (desiredScale >= 0.1875f) {
179 num = 2; 179 num = 2;
180 } else { 180 } else {
181 num = 1; 181 num = 1;
182 } 182 }
183 183
184 // Set up a fake decompress struct in order to use libjpeg to calculate outp ut dimensions 184 // Set up a fake decompress struct in order to use libjpeg to calculate outp ut dimensions
185 jpeg_decompress_struct dinfo; 185 jpeg_decompress_struct dinfo;
186 sk_bzero(&dinfo, sizeof(dinfo)); 186 sk_bzero(&dinfo, sizeof(dinfo));
187 dinfo.image_width = this->getInfo().width(); 187 dinfo.image_width = this->getInfo().width();
188 dinfo.image_height = this->getInfo().height(); 188 dinfo.image_height = this->getInfo().height();
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after
361 } 361 }
362 362
363 // Move to the next row 363 // Move to the next row
364 dstRow = SkTAddOffset<JSAMPLE>(dstRow, dstRowBytes); 364 dstRow = SkTAddOffset<JSAMPLE>(dstRow, dstRowBytes);
365 } 365 }
366 jpeg_finish_decompress(dinfo); 366 jpeg_finish_decompress(dinfo);
367 367
368 return kSuccess; 368 return kSuccess;
369 } 369 }
370 370
371 SkCodec::Result SkJpegCodec::initializeSwizzler(const SkImageInfo& info, const O ptions& options) { 371 SkCodec::Result SkJpegCodec::initializeSwizzler(const SkImageInfo& info, const O ptions& options,
372 int subsetLeft, int subsetWidth) {
372 SkSwizzler::SrcConfig srcConfig; 373 SkSwizzler::SrcConfig srcConfig;
373 switch (info.colorType()) { 374 switch (info.colorType()) {
374 case kGray_8_SkColorType: 375 case kGray_8_SkColorType:
375 srcConfig = SkSwizzler::kGray; 376 srcConfig = SkSwizzler::kGray;
376 break; 377 break;
377 case kRGBA_8888_SkColorType: 378 case kRGBA_8888_SkColorType:
378 srcConfig = SkSwizzler::kRGBX; 379 srcConfig = SkSwizzler::kRGBX;
379 break; 380 break;
380 case kBGRA_8888_SkColorType: 381 case kBGRA_8888_SkColorType:
381 srcConfig = SkSwizzler::kBGRX; 382 srcConfig = SkSwizzler::kBGRX;
382 break; 383 break;
383 case kRGB_565_SkColorType: 384 case kRGB_565_SkColorType:
384 srcConfig = SkSwizzler::kRGB_565; 385 srcConfig = SkSwizzler::kRGB_565;
385 break; 386 break;
386 default: 387 default:
387 // This function should only be called if the colorType is supported by jpeg 388 // This function should only be called if the colorType is supported by jpeg
388 SkASSERT(false); 389 SkASSERT(false);
389 } 390 }
390 391
391 fSwizzler.reset(SkSwizzler::CreateSwizzler(srcConfig, nullptr, info, options .fZeroInitialized, 392 fSwizzler.reset(SkSwizzler::CreateSwizzler(srcConfig, nullptr, info, options .fZeroInitialized,
392 this->getInfo())); 393 this->getInfo(), subsetLeft, subs etWidth));
393 if (!fSwizzler) { 394 if (!fSwizzler) {
394 return SkCodec::kUnimplemented; 395 return SkCodec::kUnimplemented;
395 } 396 }
396 397
397 return kSuccess; 398 return kSuccess;
398 } 399 }
399 400
400 SkCodec::Result SkJpegCodec::onStartScanlineDecode(const SkImageInfo& dstInfo, 401 SkCodec::Result SkJpegCodec::onStartScanlineDecode(const SkImageInfo& dstInfo,
401 const Options& options, SkPMColor ctable[], int* ctableCount) { 402 const Options& options, SkPMColor ctable[], int* ctableCount, int subset Left,
403 int subsetWidth) {
402 // Set the jump location for libjpeg errors 404 // Set the jump location for libjpeg errors
403 if (setjmp(fDecoderMgr->getJmpBuf())) { 405 if (setjmp(fDecoderMgr->getJmpBuf())) {
404 SkCodecPrintf("setjmp: Error from libjpeg\n"); 406 SkCodecPrintf("setjmp: Error from libjpeg\n");
405 return kInvalidInput; 407 return kInvalidInput;
406 } 408 }
407 409
408 // Check if we can decode to the requested destination and set the output co lor space 410 // Check if we can decode to the requested destination and set the output co lor space
409 if (!this->setOutputColorSpace(dstInfo)) { 411 if (!this->setOutputColorSpace(dstInfo)) {
410 return kInvalidConversion; 412 return kInvalidConversion;
411 } 413 }
412 414
413 // Perform the necessary scaling 415 // Perform the necessary scaling
414 if (!this->nativelyScaleToDimensions(dstInfo.width(), dstInfo.height())) { 416 if (!this->nativelyScaleToDimensions(dstInfo.width(), dstInfo.height())) {
415 // full native scaling to dstInfo dimensions not supported 417 // full native scaling to dstInfo dimensions not supported
416 418
417 if (!SkScaledCodec::DimensionsSupportedForSampling(this->getInfo(), dstI nfo)) { 419 if (!SkScaledCodec::DimensionsSupportedForSampling(this->getInfo(), dstI nfo)) {
418 return kInvalidScale; 420 return kInvalidScale;
419 } 421 }
422
420 // create swizzler for sampling 423 // create swizzler for sampling
421 Result result = this->initializeSwizzler(dstInfo, options); 424 SkCodec::Result result = this->initializeSwizzler(dstInfo, options, subs etLeft,
422 if (kSuccess != result) { 425 subsetWidth);
426 if (SkCodec::kSuccess != result) {
423 SkCodecPrintf("failed to initialize the swizzler.\n"); 427 SkCodecPrintf("failed to initialize the swizzler.\n");
424 return result; 428 return result;
425 } 429 }
426 fStorage.reset(get_row_bytes(fDecoderMgr->dinfo())); 430 fStorage.reset(get_row_bytes(this->fDecoderMgr->dinfo()));
431 fSrcRow = static_cast<uint8_t*>(fStorage.get());
432 } else if (0 != subsetLeft || dstInfo.width() != subsetWidth) {
433 // TODO (msarett): If we implement a read partial scanlines API in libjp eg-turbo, we
434 // won't need to use the swizzler here.
435 // Create swizzler for subsetting. We pass in the original info because scaling is
436 // handlded natively.
437 SkCodec::Result result = this->initializeSwizzler(
438 dstInfo.makeWH(this->getInfo().width(), this->getInfo().height() ), options,
439 subsetLeft, subsetWidth);
440 if (SkCodec::kSuccess != result) {
441 SkCodecPrintf("failed to initialize the swizzler.\n");
442 return result;
443 }
444 fStorage.reset(get_row_bytes(this->fDecoderMgr->dinfo()));
427 fSrcRow = static_cast<uint8_t*>(fStorage.get()); 445 fSrcRow = static_cast<uint8_t*>(fStorage.get());
428 } else { 446 } else {
429 fSrcRow = nullptr; 447 fSrcRow = nullptr;
430 fSwizzler.reset(nullptr); 448 fSwizzler.reset(nullptr);
431 } 449 }
432 450
433 // Now, given valid output dimensions, we can start the decompress 451 // Now, given valid output dimensions, we can start the decompress
434 if (!jpeg_start_decompress(fDecoderMgr->dinfo())) { 452 if (!jpeg_start_decompress(fDecoderMgr->dinfo())) {
435 SkCodecPrintf("start decompress failed\n"); 453 SkCodecPrintf("start decompress failed\n");
436 return kInvalidInput; 454 return kInvalidInput;
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
504 #endif 522 #endif
505 523
506 bool SkJpegCodec::onSkipScanlines(int count) { 524 bool SkJpegCodec::onSkipScanlines(int count) {
507 // Set the jump location for libjpeg errors 525 // Set the jump location for libjpeg errors
508 if (setjmp(fDecoderMgr->getJmpBuf())) { 526 if (setjmp(fDecoderMgr->getJmpBuf())) {
509 return fDecoderMgr->returnFailure("setjmp", kInvalidInput); 527 return fDecoderMgr->returnFailure("setjmp", kInvalidInput);
510 } 528 }
511 529
512 return count == jpeg_skip_scanlines(fDecoderMgr->dinfo(), count); 530 return count == jpeg_skip_scanlines(fDecoderMgr->dinfo(), count);
513 } 531 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698