| 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 "SkBitmap.h" | 8 #include "SkBitmap.h" |
| 9 #include "SkCodecPriv.h" | 9 #include "SkCodecPriv.h" |
| 10 #include "SkColorPriv.h" | 10 #include "SkColorPriv.h" |
| (...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 351 case kBGRA_8888_SkColorType: | 351 case kBGRA_8888_SkColorType: |
| 352 case kRGBA_F16_SkColorType: | 352 case kRGBA_F16_SkColorType: |
| 353 return true; | 353 return true; |
| 354 case kRGB_565_SkColorType: | 354 case kRGB_565_SkColorType: |
| 355 return kOpaque_SkAlphaType == src.alphaType(); | 355 return kOpaque_SkAlphaType == src.alphaType(); |
| 356 default: | 356 default: |
| 357 return dst.colorType() == src.colorType(); | 357 return dst.colorType() == src.colorType(); |
| 358 } | 358 } |
| 359 } | 359 } |
| 360 | 360 |
| 361 void SkPngCodec::allocateStorage(const SkImageInfo& dstInfo) { | 361 void SkPngCodec::allocateStorage() { |
| 362 const int width = this->getInfo().width(); | 362 size_t colorXformBytes = fColorXform ? fSwizzler->swizzleWidth() * sizeof(ui
nt32_t) : 0; |
| 363 size_t colorXformBytes = fColorXform ? width * sizeof(uint32_t) : 0; | |
| 364 | 363 |
| 365 fStorage.reset(SkAlign4(fSrcRowBytes) + colorXformBytes); | 364 fStorage.reset(SkAlign4(fSrcRowBytes) + colorXformBytes); |
| 366 fSwizzlerSrcRow = fStorage.get(); | 365 fSwizzlerSrcRow = fStorage.get(); |
| 367 fColorXformSrcRow = | 366 fColorXformSrcRow = |
| 368 fColorXform ? SkTAddOffset<uint32_t>(fSwizzlerSrcRow, SkAlign4(fSrcR
owBytes)) : 0; | 367 fColorXform ? SkTAddOffset<uint32_t>(fSwizzlerSrcRow, SkAlign4(fSrcR
owBytes)) : 0; |
| 369 } | 368 } |
| 370 | 369 |
| 371 class SkPngNormalCodec : public SkPngCodec { | 370 class SkPngNormalCodec : public SkPngCodec { |
| 372 public: | 371 public: |
| 373 SkPngNormalCodec(const SkEncodedInfo& encodedInfo, const SkImageInfo& imageI
nfo, | 372 SkPngNormalCodec(const SkEncodedInfo& encodedInfo, const SkImageInfo& imageI
nfo, |
| 374 SkStream* stream, SkPngChunkReader* chunkReader, png_structp png_ptr
, | 373 SkStream* stream, SkPngChunkReader* chunkReader, png_structp png_ptr
, |
| 375 png_infop info_ptr, int bitDepth) | 374 png_infop info_ptr, int bitDepth) |
| 376 : INHERITED(encodedInfo, imageInfo, stream, chunkReader, png_ptr, info_p
tr, bitDepth, 1) | 375 : INHERITED(encodedInfo, imageInfo, stream, chunkReader, png_ptr, info_p
tr, bitDepth, 1) |
| 377 {} | 376 {} |
| 378 | 377 |
| 379 Result onStartScanlineDecode(const SkImageInfo& dstInfo, const Options& opti
ons, | 378 Result onStartScanlineDecode(const SkImageInfo& dstInfo, const Options& opti
ons, |
| 380 SkPMColor ctable[], int* ctableCount) override { | 379 SkPMColor ctable[], int* ctableCount) override { |
| 381 if (!png_conversion_possible(dstInfo, this->getInfo()) || | 380 if (!png_conversion_possible(dstInfo, this->getInfo()) || |
| 382 !this->initializeXforms(dstInfo, options, ctable, ctableCount)) | 381 !this->initializeXforms(dstInfo, options, ctable, ctableCount)) |
| 383 { | 382 { |
| 384 return kInvalidConversion; | 383 return kInvalidConversion; |
| 385 } | 384 } |
| 386 | 385 |
| 387 this->allocateStorage(dstInfo); | 386 this->allocateStorage(); |
| 388 return kSuccess; | 387 return kSuccess; |
| 389 } | 388 } |
| 390 | 389 |
| 391 int readRows(const SkImageInfo& dstInfo, void* dst, size_t rowBytes, int cou
nt, int startRow) | 390 int readRows(const SkImageInfo& dstInfo, void* dst, size_t rowBytes, int cou
nt, int startRow) |
| 392 override { | 391 override { |
| 393 SkASSERT(0 == startRow); | 392 SkASSERT(0 == startRow); |
| 394 | 393 |
| 395 // Assume that an error in libpng indicates an incomplete input. | 394 // Assume that an error in libpng indicates an incomplete input. |
| 396 int y = 0; | 395 int y = 0; |
| 397 if (setjmp(png_jmpbuf(fPng_ptr))) { | 396 if (setjmp(png_jmpbuf(fPng_ptr))) { |
| 398 SkCodecPrintf("Failed to read row.\n"); | 397 SkCodecPrintf("Failed to read row.\n"); |
| 399 return y; | 398 return y; |
| 400 } | 399 } |
| 401 | 400 |
| 402 void* swizzlerDstRow = dst; | 401 void* swizzlerDstRow = dst; |
| 403 size_t swizzlerDstRowBytes = rowBytes; | 402 size_t swizzlerDstRowBytes = rowBytes; |
| 404 if (fColorXform) { | 403 if (fColorXform) { |
| 405 swizzlerDstRow = fColorXformSrcRow; | 404 swizzlerDstRow = fColorXformSrcRow; |
| 406 swizzlerDstRowBytes = 0; | 405 swizzlerDstRowBytes = 0; |
| 407 } | 406 } |
| 408 | 407 |
| 409 SkAlphaType xformAlphaType = (kOpaque_SkAlphaType == this->getInfo().alp
haType()) ? | 408 SkAlphaType xformAlphaType = (kOpaque_SkAlphaType == this->getInfo().alp
haType()) ? |
| 410 kOpaque_SkAlphaType : dstInfo.alphaType(); | 409 kOpaque_SkAlphaType : dstInfo.alphaType(); |
| 411 for (; y < count; y++) { | 410 for (; y < count; y++) { |
| 412 png_read_row(fPng_ptr, fSwizzlerSrcRow, nullptr); | 411 png_read_row(fPng_ptr, fSwizzlerSrcRow, nullptr); |
| 413 fSwizzler->swizzle(swizzlerDstRow, fSwizzlerSrcRow); | 412 fSwizzler->swizzle(swizzlerDstRow, fSwizzlerSrcRow); |
| 414 | 413 |
| 415 if (fColorXform) { | 414 if (fColorXform) { |
| 416 fColorXform->apply(dst, (const uint32_t*) swizzlerDstRow, dstInf
o.width(), | 415 fColorXform->apply(dst, (const uint32_t*) swizzlerDstRow, fSwizz
ler->swizzleWidth(), |
| 417 dstInfo.colorType(), xformAlphaType); | 416 dstInfo.colorType(), xformAlphaType); |
| 418 dst = SkTAddOffset<void>(dst, rowBytes); | 417 dst = SkTAddOffset<void>(dst, rowBytes); |
| 419 } | 418 } |
| 420 | 419 |
| 421 swizzlerDstRow = SkTAddOffset<void>(swizzlerDstRow, swizzlerDstRowBy
tes); | 420 swizzlerDstRow = SkTAddOffset<void>(swizzlerDstRow, swizzlerDstRowBy
tes); |
| 422 } | 421 } |
| 423 | 422 |
| 424 return y; | 423 return y; |
| 425 } | 424 } |
| 426 | 425 |
| (...skipping 30 matching lines...) Expand all Loading... |
| 457 } | 456 } |
| 458 | 457 |
| 459 Result onStartScanlineDecode(const SkImageInfo& dstInfo, const Options& opti
ons, | 458 Result onStartScanlineDecode(const SkImageInfo& dstInfo, const Options& opti
ons, |
| 460 SkPMColor ctable[], int* ctableCount) override { | 459 SkPMColor ctable[], int* ctableCount) override { |
| 461 if (!png_conversion_possible(dstInfo, this->getInfo()) || | 460 if (!png_conversion_possible(dstInfo, this->getInfo()) || |
| 462 !this->initializeXforms(dstInfo, options, ctable, ctableCount)) | 461 !this->initializeXforms(dstInfo, options, ctable, ctableCount)) |
| 463 { | 462 { |
| 464 return kInvalidConversion; | 463 return kInvalidConversion; |
| 465 } | 464 } |
| 466 | 465 |
| 467 this->allocateStorage(dstInfo); | 466 this->allocateStorage(); |
| 468 fCanSkipRewind = true; | 467 fCanSkipRewind = true; |
| 469 return SkCodec::kSuccess; | 468 return SkCodec::kSuccess; |
| 470 } | 469 } |
| 471 | 470 |
| 472 int readRows(const SkImageInfo& dstInfo, void* dst, size_t rowBytes, int cou
nt, int startRow) | 471 int readRows(const SkImageInfo& dstInfo, void* dst, size_t rowBytes, int cou
nt, int startRow) |
| 473 override { | 472 override { |
| 474 if (setjmp(png_jmpbuf(fPng_ptr))) { | 473 if (setjmp(png_jmpbuf(fPng_ptr))) { |
| 475 SkCodecPrintf("Failed to get scanlines.\n"); | 474 SkCodecPrintf("Failed to get scanlines.\n"); |
| 476 // FIXME (msarett): Returning 0 is pessimistic. If we can complete
a single pass, | 475 // FIXME (msarett): Returning 0 is pessimistic. If we can complete
a single pass, |
| 477 // we may be able to report that all of the memory has been initiali
zed. Even if we | 476 // we may be able to report that all of the memory has been initiali
zed. Even if we |
| (...skipping 30 matching lines...) Expand all Loading... |
| 508 | 507 |
| 509 SkAlphaType xformAlphaType = (kOpaque_SkAlphaType == this->getInfo().alp
haType()) ? | 508 SkAlphaType xformAlphaType = (kOpaque_SkAlphaType == this->getInfo().alp
haType()) ? |
| 510 kOpaque_SkAlphaType : dstInfo.alphaType(); | 509 kOpaque_SkAlphaType : dstInfo.alphaType(); |
| 511 srcRow = storage.get(); | 510 srcRow = storage.get(); |
| 512 for (int y = 0; y < count; y++) { | 511 for (int y = 0; y < count; y++) { |
| 513 fSwizzler->swizzle(swizzlerDstRow, srcRow); | 512 fSwizzler->swizzle(swizzlerDstRow, srcRow); |
| 514 srcRow = SkTAddOffset<uint8_t>(srcRow, fSrcRowBytes); | 513 srcRow = SkTAddOffset<uint8_t>(srcRow, fSrcRowBytes); |
| 515 | 514 |
| 516 if (fColorXform) { | 515 if (fColorXform) { |
| 517 if (fColorXform) { | 516 if (fColorXform) { |
| 518 fColorXform->apply(dst, (const uint32_t*) swizzlerDstRow, ds
tInfo.width(), | 517 fColorXform->apply(dst, (const uint32_t*) swizzlerDstRow, |
| 519 dstInfo.colorType(), xformAlphaType); | 518 fSwizzler->swizzleWidth(), dstInfo.colorT
ype(), |
| 519 xformAlphaType); |
| 520 dst = SkTAddOffset<void>(dst, rowBytes); | 520 dst = SkTAddOffset<void>(dst, rowBytes); |
| 521 } | 521 } |
| 522 } | 522 } |
| 523 | 523 |
| 524 swizzlerDstRow = SkTAddOffset<void>(swizzlerDstRow, swizzlerDstRowBy
tes); | 524 swizzlerDstRow = SkTAddOffset<void>(swizzlerDstRow, swizzlerDstRowBy
tes); |
| 525 } | 525 } |
| 526 | 526 |
| 527 return count; | 527 return count; |
| 528 } | 528 } |
| 529 | 529 |
| (...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 858 if (!png_conversion_possible(dstInfo, this->getInfo()) || | 858 if (!png_conversion_possible(dstInfo, this->getInfo()) || |
| 859 !this->initializeXforms(dstInfo, options, ctable, ctableCount)) | 859 !this->initializeXforms(dstInfo, options, ctable, ctableCount)) |
| 860 { | 860 { |
| 861 return kInvalidConversion; | 861 return kInvalidConversion; |
| 862 } | 862 } |
| 863 | 863 |
| 864 if (options.fSubset) { | 864 if (options.fSubset) { |
| 865 return kUnimplemented; | 865 return kUnimplemented; |
| 866 } | 866 } |
| 867 | 867 |
| 868 this->allocateStorage(dstInfo); | 868 this->allocateStorage(); |
| 869 int count = this->readRows(dstInfo, dst, rowBytes, dstInfo.height(), 0); | 869 int count = this->readRows(dstInfo, dst, rowBytes, dstInfo.height(), 0); |
| 870 if (count > dstInfo.height()) { | 870 if (count > dstInfo.height()) { |
| 871 *rowsDecoded = count; | 871 *rowsDecoded = count; |
| 872 return kIncompleteInput; | 872 return kIncompleteInput; |
| 873 } | 873 } |
| 874 | 874 |
| 875 return kSuccess; | 875 return kSuccess; |
| 876 } | 876 } |
| 877 | 877 |
| 878 uint32_t SkPngCodec::onGetFillValue(SkColorType colorType) const { | 878 uint32_t SkPngCodec::onGetFillValue(SkColorType colorType) const { |
| (...skipping 10 matching lines...) Expand all Loading... |
| 889 SkCodec* outCodec; | 889 SkCodec* outCodec; |
| 890 if (read_header(stream, chunkReader, &outCodec, nullptr, nullptr)) { | 890 if (read_header(stream, chunkReader, &outCodec, nullptr, nullptr)) { |
| 891 // Codec has taken ownership of the stream. | 891 // Codec has taken ownership of the stream. |
| 892 SkASSERT(outCodec); | 892 SkASSERT(outCodec); |
| 893 streamDeleter.release(); | 893 streamDeleter.release(); |
| 894 return outCodec; | 894 return outCodec; |
| 895 } | 895 } |
| 896 | 896 |
| 897 return nullptr; | 897 return nullptr; |
| 898 } | 898 } |
| OLD | NEW |