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 |