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_libpng.h" | 8 #include "SkCodec_libpng.h" |
9 #include "SkCodecPriv.h" | 9 #include "SkCodecPriv.h" |
10 #include "SkColorPriv.h" | 10 #include "SkColorPriv.h" |
(...skipping 28 matching lines...) Expand all Loading... |
39 | 39 |
40 #ifndef png_flush_ptr_NULL | 40 #ifndef png_flush_ptr_NULL |
41 #define png_flush_ptr_NULL NULL | 41 #define png_flush_ptr_NULL NULL |
42 #endif | 42 #endif |
43 | 43 |
44 /////////////////////////////////////////////////////////////////////////////// | 44 /////////////////////////////////////////////////////////////////////////////// |
45 // Callback functions | 45 // Callback functions |
46 /////////////////////////////////////////////////////////////////////////////// | 46 /////////////////////////////////////////////////////////////////////////////// |
47 | 47 |
48 static void sk_error_fn(png_structp png_ptr, png_const_charp msg) { | 48 static void sk_error_fn(png_structp png_ptr, png_const_charp msg) { |
49 SkDebugf("------ png error %s\n", msg); | 49 SkCodecPrintf("------ png error %s\n", msg); |
50 longjmp(png_jmpbuf(png_ptr), 1); | 50 longjmp(png_jmpbuf(png_ptr), 1); |
51 } | 51 } |
52 | 52 |
53 static void sk_read_fn(png_structp png_ptr, png_bytep data, | 53 static void sk_read_fn(png_structp png_ptr, png_bytep data, |
54 png_size_t length) { | 54 png_size_t length) { |
55 SkStream* stream = static_cast<SkStream*>(png_get_io_ptr(png_ptr)); | 55 SkStream* stream = static_cast<SkStream*>(png_get_io_ptr(png_ptr)); |
56 const size_t bytes = stream->read(data, length); | 56 const size_t bytes = stream->read(data, length); |
57 if (bytes != length) { | 57 if (bytes != length) { |
58 // FIXME: We want to report the fact that the stream was truncated. | 58 // FIXME: We want to report the fact that the stream was truncated. |
59 // One way to do that might be to pass a enum to longjmp so setjmp can | 59 // One way to do that might be to pass a enum to longjmp so setjmp can |
(...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
362 return kPremul_SkAlphaType == dst.alphaType() && | 362 return kPremul_SkAlphaType == dst.alphaType() && |
363 kUnpremul_SkAlphaType == src.alphaType(); | 363 kUnpremul_SkAlphaType == src.alphaType(); |
364 } | 364 } |
365 | 365 |
366 SkCodec::Result SkPngCodec::initializeSwizzler(const SkImageInfo& requestedInfo, | 366 SkCodec::Result SkPngCodec::initializeSwizzler(const SkImageInfo& requestedInfo, |
367 void* dst, size_t rowBytes, | 367 void* dst, size_t rowBytes, |
368 const Options& options) { | 368 const Options& options) { |
369 // FIXME: Could we use the return value of setjmp to specify the type of | 369 // FIXME: Could we use the return value of setjmp to specify the type of |
370 // error? | 370 // error? |
371 if (setjmp(png_jmpbuf(fPng_ptr))) { | 371 if (setjmp(png_jmpbuf(fPng_ptr))) { |
372 SkDebugf("setjmp long jump!\n"); | 372 SkCodecPrintf("setjmp long jump!\n"); |
373 return kInvalidInput; | 373 return kInvalidInput; |
374 } | 374 } |
375 | 375 |
376 // FIXME: We already retrieved this information. Store it in SkPngCodec? | 376 // FIXME: We already retrieved this information. Store it in SkPngCodec? |
377 png_uint_32 origWidth, origHeight; | 377 png_uint_32 origWidth, origHeight; |
378 int bitDepth, pngColorType, interlaceType; | 378 int bitDepth, pngColorType, interlaceType; |
379 png_get_IHDR(fPng_ptr, fInfo_ptr, &origWidth, &origHeight, &bitDepth, | 379 png_get_IHDR(fPng_ptr, fInfo_ptr, &origWidth, &origHeight, &bitDepth, |
380 &pngColorType, &interlaceType, int_p_NULL, int_p_NULL); | 380 &pngColorType, &interlaceType, int_p_NULL, int_p_NULL); |
381 | 381 |
382 fNumberPasses = (interlaceType != PNG_INTERLACE_NONE) ? | 382 fNumberPasses = (interlaceType != PNG_INTERLACE_NONE) ? |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
429 | 429 |
430 const Result result = this->initializeSwizzler(requestedInfo, dst, rowBytes, | 430 const Result result = this->initializeSwizzler(requestedInfo, dst, rowBytes, |
431 options); | 431 options); |
432 if (result != kSuccess) { | 432 if (result != kSuccess) { |
433 return result; | 433 return result; |
434 } | 434 } |
435 | 435 |
436 // FIXME: Could we use the return value of setjmp to specify the type of | 436 // FIXME: Could we use the return value of setjmp to specify the type of |
437 // error? | 437 // error? |
438 if (setjmp(png_jmpbuf(fPng_ptr))) { | 438 if (setjmp(png_jmpbuf(fPng_ptr))) { |
439 SkDebugf("setjmp long jump!\n"); | 439 SkCodecPrintf("setjmp long jump!\n"); |
440 return kInvalidInput; | 440 return kInvalidInput; |
441 } | 441 } |
442 | 442 |
443 SkASSERT(fNumberPasses != INVALID_NUMBER_PASSES); | 443 SkASSERT(fNumberPasses != INVALID_NUMBER_PASSES); |
444 SkAutoMalloc storage; | 444 SkAutoMalloc storage; |
445 if (fNumberPasses > 1) { | 445 if (fNumberPasses > 1) { |
446 const int width = requestedInfo.width(); | 446 const int width = requestedInfo.width(); |
447 const int height = requestedInfo.height(); | 447 const int height = requestedInfo.height(); |
448 const int bpp = SkSwizzler::BytesPerPixel(fSrcConfig); | 448 const int bpp = SkSwizzler::BytesPerPixel(fSrcConfig); |
449 const size_t rowBytes = width * bpp; | 449 const size_t rowBytes = width * bpp; |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
498 : INHERITED(dstInfo) | 498 : INHERITED(dstInfo) |
499 , fCodec(codec) | 499 , fCodec(codec) |
500 , fHasAlpha(false) | 500 , fHasAlpha(false) |
501 { | 501 { |
502 fStorage.reset(dstInfo.width() * SkSwizzler::BytesPerPixel(fCodec->fSrcC
onfig)); | 502 fStorage.reset(dstInfo.width() * SkSwizzler::BytesPerPixel(fCodec->fSrcC
onfig)); |
503 fSrcRow = static_cast<uint8_t*>(fStorage.get()); | 503 fSrcRow = static_cast<uint8_t*>(fStorage.get()); |
504 } | 504 } |
505 | 505 |
506 SkImageGenerator::Result onGetScanlines(void* dst, int count, size_t rowByte
s) override { | 506 SkImageGenerator::Result onGetScanlines(void* dst, int count, size_t rowByte
s) override { |
507 if (setjmp(png_jmpbuf(fCodec->fPng_ptr))) { | 507 if (setjmp(png_jmpbuf(fCodec->fPng_ptr))) { |
508 SkDebugf("setjmp long jump!\n"); | 508 SkCodecPrintf("setjmp long jump!\n"); |
509 return SkImageGenerator::kInvalidInput; | 509 return SkImageGenerator::kInvalidInput; |
510 } | 510 } |
511 | 511 |
512 for (int i = 0; i < count; i++) { | 512 for (int i = 0; i < count; i++) { |
513 png_read_rows(fCodec->fPng_ptr, &fSrcRow, png_bytepp_NULL, 1); | 513 png_read_rows(fCodec->fPng_ptr, &fSrcRow, png_bytepp_NULL, 1); |
514 fCodec->fSwizzler->setDstRow(dst); | 514 fCodec->fSwizzler->setDstRow(dst); |
515 fHasAlpha |= !SkSwizzler::IsOpaque(fCodec->fSwizzler->next(fSrcRow))
; | 515 fHasAlpha |= !SkSwizzler::IsOpaque(fCodec->fSwizzler->next(fSrcRow))
; |
516 dst = SkTAddOffset<void>(dst, rowBytes); | 516 dst = SkTAddOffset<void>(dst, rowBytes); |
517 } | 517 } |
518 return SkImageGenerator::kSuccess; | 518 return SkImageGenerator::kSuccess; |
519 } | 519 } |
520 | 520 |
521 SkImageGenerator::Result onSkipScanlines(int count) override { | 521 SkImageGenerator::Result onSkipScanlines(int count) override { |
522 // FIXME: Could we use the return value of setjmp to specify the type of | 522 // FIXME: Could we use the return value of setjmp to specify the type of |
523 // error? | 523 // error? |
524 if (setjmp(png_jmpbuf(fCodec->fPng_ptr))) { | 524 if (setjmp(png_jmpbuf(fCodec->fPng_ptr))) { |
525 SkDebugf("setjmp long jump!\n"); | 525 SkCodecPrintf("setjmp long jump!\n"); |
526 return SkImageGenerator::kInvalidInput; | 526 return SkImageGenerator::kInvalidInput; |
527 } | 527 } |
528 | 528 |
529 png_read_rows(fCodec->fPng_ptr, png_bytepp_NULL, png_bytepp_NULL, count)
; | 529 png_read_rows(fCodec->fPng_ptr, png_bytepp_NULL, png_bytepp_NULL, count)
; |
530 return SkImageGenerator::kSuccess; | 530 return SkImageGenerator::kSuccess; |
531 } | 531 } |
532 | 532 |
533 void onFinish() override { | 533 void onFinish() override { |
534 fCodec->finish(); | 534 fCodec->finish(); |
535 } | 535 } |
536 | 536 |
537 bool onReallyHasAlpha() const override { return fHasAlpha; } | 537 bool onReallyHasAlpha() const override { return fHasAlpha; } |
538 | 538 |
539 private: | 539 private: |
540 SkPngCodec* fCodec; // Unowned. | 540 SkPngCodec* fCodec; // Unowned. |
541 bool fHasAlpha; | 541 bool fHasAlpha; |
542 SkAutoMalloc fStorage; | 542 SkAutoMalloc fStorage; |
543 uint8_t* fSrcRow; | 543 uint8_t* fSrcRow; |
544 | 544 |
545 typedef SkScanlineDecoder INHERITED; | 545 typedef SkScanlineDecoder INHERITED; |
546 }; | 546 }; |
547 | 547 |
548 SkScanlineDecoder* SkPngCodec::onGetScanlineDecoder(const SkImageInfo& dstInfo)
{ | 548 SkScanlineDecoder* SkPngCodec::onGetScanlineDecoder(const SkImageInfo& dstInfo)
{ |
549 // Check to see if scaling was requested. | 549 // Check to see if scaling was requested. |
550 if (dstInfo.dimensions() != this->getInfo().dimensions()) { | 550 if (dstInfo.dimensions() != this->getInfo().dimensions()) { |
551 return NULL; | 551 return NULL; |
552 } | 552 } |
553 | 553 |
554 if (!conversion_possible(dstInfo, this->getInfo())) { | 554 if (!conversion_possible(dstInfo, this->getInfo())) { |
555 SkDebugf("no conversion possible\n"); | 555 SkCodecPrintf("no conversion possible\n"); |
556 return NULL; | 556 return NULL; |
557 } | 557 } |
558 | 558 |
559 // Note: We set dst to NULL since we do not know it yet. rowBytes is not nee
ded, | 559 // Note: We set dst to NULL since we do not know it yet. rowBytes is not nee
ded, |
560 // since we'll be manually updating the dstRow, but the SkSwizzler requires
it to | 560 // since we'll be manually updating the dstRow, but the SkSwizzler requires
it to |
561 // be at least dstInfo.minRowBytes. | 561 // be at least dstInfo.minRowBytes. |
562 Options opts; | 562 Options opts; |
563 // FIXME: Pass this in to getScanlineDecoder? | 563 // FIXME: Pass this in to getScanlineDecoder? |
564 opts.fZeroInitialized = kNo_ZeroInitialized; | 564 opts.fZeroInitialized = kNo_ZeroInitialized; |
565 if (this->initializeSwizzler(dstInfo, NULL, dstInfo.minRowBytes(), opts) !=
kSuccess) { | 565 if (this->initializeSwizzler(dstInfo, NULL, dstInfo.minRowBytes(), opts) !=
kSuccess) { |
566 SkDebugf("failed to initialize the swizzler.\n"); | 566 SkCodecPrintf("failed to initialize the swizzler.\n"); |
567 return NULL; | 567 return NULL; |
568 } | 568 } |
569 | 569 |
570 SkASSERT(fNumberPasses != INVALID_NUMBER_PASSES); | 570 SkASSERT(fNumberPasses != INVALID_NUMBER_PASSES); |
571 if (fNumberPasses > 1) { | 571 if (fNumberPasses > 1) { |
572 // We cannot efficiently do scanline decoding. | 572 // We cannot efficiently do scanline decoding. |
573 return NULL; | 573 return NULL; |
574 } | 574 } |
575 | 575 |
576 return SkNEW_ARGS(SkPngScanlineDecoder, (dstInfo, this)); | 576 return SkNEW_ARGS(SkPngScanlineDecoder, (dstInfo, this)); |
577 } | 577 } |
578 | 578 |
OLD | NEW |