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 330 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
341 break; | 341 break; |
342 case kRGB_565_SkColorType: | 342 case kRGB_565_SkColorType: |
343 srcConfig = SkSwizzler::kRGB_565; | 343 srcConfig = SkSwizzler::kRGB_565; |
344 break; | 344 break; |
345 default: | 345 default: |
346 // This function should only be called if the colorType is suppo
rted by jpeg | 346 // This function should only be called if the colorType is suppo
rted by jpeg |
347 SkASSERT(false); | 347 SkASSERT(false); |
348 } | 348 } |
349 } | 349 } |
350 | 350 |
351 fSwizzler.reset(SkSwizzler::CreateSwizzler(srcConfig, nullptr, dstInfo, opti
ons)); | 351 Options swizzlerOptions = options; |
| 352 if (options.fSubset) { |
| 353 // Use fSwizzlerSubset if this is a subset decode. This is necessary in
the case |
| 354 // where libjpeg-turbo provides a subset and then we need to subset it f
urther. |
| 355 swizzlerOptions.fSubset = &fSwizzlerSubset; |
| 356 } |
| 357 fSwizzler.reset(SkSwizzler::CreateSwizzler(srcConfig, nullptr, dstInfo, swiz
zlerOptions)); |
352 fStorage.reset(get_row_bytes(fDecoderMgr->dinfo())); | 358 fStorage.reset(get_row_bytes(fDecoderMgr->dinfo())); |
353 fSrcRow = fStorage.get(); | 359 fSrcRow = fStorage.get(); |
354 } | 360 } |
355 | 361 |
356 SkSampler* SkJpegCodec::getSampler(bool createIfNecessary) { | 362 SkSampler* SkJpegCodec::getSampler(bool createIfNecessary) { |
357 if (!createIfNecessary || fSwizzler) { | 363 if (!createIfNecessary || fSwizzler) { |
358 SkASSERT(!fSwizzler || (fSrcRow && fStorage.get() == fSrcRow)); | 364 SkASSERT(!fSwizzler || (fSrcRow && fStorage.get() == fSrcRow)); |
359 return fSwizzler; | 365 return fSwizzler; |
360 } | 366 } |
361 | 367 |
(...skipping 18 matching lines...) Expand all Loading... |
380 fSwizzler.reset(nullptr); | 386 fSwizzler.reset(nullptr); |
381 fSrcRow = nullptr; | 387 fSrcRow = nullptr; |
382 fStorage.free(); | 388 fStorage.free(); |
383 | 389 |
384 // Now, given valid output dimensions, we can start the decompress | 390 // Now, given valid output dimensions, we can start the decompress |
385 if (!jpeg_start_decompress(fDecoderMgr->dinfo())) { | 391 if (!jpeg_start_decompress(fDecoderMgr->dinfo())) { |
386 SkCodecPrintf("start decompress failed\n"); | 392 SkCodecPrintf("start decompress failed\n"); |
387 return kInvalidInput; | 393 return kInvalidInput; |
388 } | 394 } |
389 | 395 |
| 396 if (options.fSubset) { |
| 397 fSwizzlerSubset = *options.fSubset; |
| 398 } |
| 399 |
| 400 #ifdef TURBO_HAS_SUBSET |
| 401 if (options.fSubset) { |
| 402 uint32_t startX = options.fSubset->x(); |
| 403 uint32_t width = options.fSubset->width(); |
| 404 |
| 405 // libjpeg-turbo may need to align startX to a multiple of the IDCT |
| 406 // block size. If this is the case, it will decrease the value of |
| 407 // startX to the appropriate alignment and also increase the value |
| 408 // of width so that the right edge of the requested subset remains |
| 409 // the same. |
| 410 jpeg_set_partial_scanline(fDecoderMgr->dinfo(), &startX, &width); |
| 411 |
| 412 SkASSERT(startX <= (uint32_t) options.fSubset->x()); |
| 413 SkASSERT(width >= (uint32_t) options.fSubset->width()); |
| 414 SkASSERT(startX + width >= (uint32_t) options.fSubset->right()); |
| 415 |
| 416 // Instruct the swizzler (if it is necessary) to further subset the |
| 417 // output provided by libjpeg-turbo |
| 418 fSwizzlerSubset.setXYWH(options.fSubset->x() - startX, 0, |
| 419 options.fSubset->width(), options.fSubset->height()); |
| 420 |
| 421 // We will need a swizzler if libjpeg-turbo cannot provide the exact |
| 422 // subset that we request. Or if we are converting from CMYK. |
| 423 if (startX != (uint32_t) options.fSubset->x() || |
| 424 width != (uint32_t) options.fSubset->width()) { |
| 425 this->initializeSwizzler(dstInfo, options); |
| 426 } |
| 427 } |
| 428 |
| 429 // Make sure we have a swizzler if we are converting from CMYK. |
| 430 if (!fSwizzler && JCS_CMYK == fDecoderMgr->dinfo()->out_color_space) { |
| 431 this->initializeSwizzler(dstInfo, options); |
| 432 } |
| 433 #else |
390 // We will need a swizzler if we are performing a subset decode or | 434 // We will need a swizzler if we are performing a subset decode or |
391 // converting from CMYK. | 435 // converting from CMYK. |
392 if (options.fSubset || JCS_CMYK == fDecoderMgr->dinfo()->out_color_space) { | 436 if (options.fSubset || JCS_CMYK == fDecoderMgr->dinfo()->out_color_space) { |
393 this->initializeSwizzler(dstInfo, options); | 437 this->initializeSwizzler(dstInfo, options); |
394 } | 438 } |
| 439 #endif |
395 | 440 |
396 return kSuccess; | 441 return kSuccess; |
397 } | 442 } |
398 | 443 |
399 int SkJpegCodec::onGetScanlines(void* dst, int count, size_t rowBytes) { | 444 int SkJpegCodec::onGetScanlines(void* dst, int count, size_t rowBytes) { |
400 // Set the jump location for libjpeg errors | 445 // Set the jump location for libjpeg errors |
401 if (setjmp(fDecoderMgr->getJmpBuf())) { | 446 if (setjmp(fDecoderMgr->getJmpBuf())) { |
402 return fDecoderMgr->returnFailure("setjmp", kInvalidInput); | 447 return fDecoderMgr->returnFailure("setjmp", kInvalidInput); |
403 } | 448 } |
404 // Read rows one at a time | 449 // Read rows one at a time |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
445 #endif | 490 #endif |
446 | 491 |
447 bool SkJpegCodec::onSkipScanlines(int count) { | 492 bool SkJpegCodec::onSkipScanlines(int count) { |
448 // Set the jump location for libjpeg errors | 493 // Set the jump location for libjpeg errors |
449 if (setjmp(fDecoderMgr->getJmpBuf())) { | 494 if (setjmp(fDecoderMgr->getJmpBuf())) { |
450 return fDecoderMgr->returnFalse("setjmp"); | 495 return fDecoderMgr->returnFalse("setjmp"); |
451 } | 496 } |
452 | 497 |
453 return (uint32_t) count == jpeg_skip_scanlines(fDecoderMgr->dinfo(), count); | 498 return (uint32_t) count == jpeg_skip_scanlines(fDecoderMgr->dinfo(), count); |
454 } | 499 } |
OLD | NEW |