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

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

Issue 1895383002: Revert of Add SkEncodedInfo to report properties of encoded image data (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 4 years, 8 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
« no previous file with comments | « src/codec/SkPngCodec.h ('k') | src/codec/SkRawCodec.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 "SkBitmap.h" 8 #include "SkBitmap.h"
9 #include "SkCodecPriv.h" 9 #include "SkCodecPriv.h"
10 #include "SkColorPriv.h" 10 #include "SkColorPriv.h"
(...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after
272 // 272 //
273 // @param stream Input data. Will be read to get enough information to properly 273 // @param stream Input data. Will be read to get enough information to properly
274 // setup the codec. 274 // setup the codec.
275 // @param chunkReader SkPngChunkReader, for reading unknown chunks. May be NULL. 275 // @param chunkReader SkPngChunkReader, for reading unknown chunks. May be NULL.
276 // If not NULL, png_ptr will hold an *unowned* pointer to it. The caller is 276 // If not NULL, png_ptr will hold an *unowned* pointer to it. The caller is
277 // expected to continue to own it for the lifetime of the png_ptr. 277 // expected to continue to own it for the lifetime of the png_ptr.
278 // @param png_ptrp Optional output variable. If non-NULL, will be set to a new 278 // @param png_ptrp Optional output variable. If non-NULL, will be set to a new
279 // png_structp on success. 279 // png_structp on success.
280 // @param info_ptrp Optional output variable. If non-NULL, will be set to a new 280 // @param info_ptrp Optional output variable. If non-NULL, will be set to a new
281 // png_infop on success; 281 // png_infop on success;
282 // @param info Optional output variable. If non-NULL, will be set to 282 // @param imageInfo Optional output variable. If non-NULL, will be set to
283 // reflect the properties of the encoded image on success. 283 // reflect the properties of the encoded image on success.
284 // @param bitDepthPtr Optional output variable. If non-NULL, will be set to the 284 // @param bitDepthPtr Optional output variable. If non-NULL, will be set to the
285 // bit depth of the encoded image on success. 285 // bit depth of the encoded image on success.
286 // @param numberPassesPtr Optional output variable. If non-NULL, will be set to 286 // @param numberPassesPtr Optional output variable. If non-NULL, will be set to
287 // the number_passes of the encoded image on success. 287 // the number_passes of the encoded image on success.
288 // @return true on success, in which case the caller is responsible for calling 288 // @return true on success, in which case the caller is responsible for calling
289 // png_destroy_read_struct(png_ptrp, info_ptrp). 289 // png_destroy_read_struct(png_ptrp, info_ptrp).
290 // If it returns false, the passed in fields (except stream) are unchanged. 290 // If it returns false, the passed in fields (except stream) are unchanged.
291 static bool read_header(SkStream* stream, SkPngChunkReader* chunkReader, 291 static bool read_header(SkStream* stream, SkPngChunkReader* chunkReader,
292 png_structp* png_ptrp, png_infop* info_ptrp, 292 png_structp* png_ptrp, png_infop* info_ptrp,
293 int* width, int* height, SkEncodedInfo* info, int* bitDe pthPtr, 293 SkImageInfo* imageInfo, int* bitDepthPtr, int* numberPas sesPtr) {
294 int* numberPassesPtr) {
295 // The image is known to be a PNG. Decode enough to know the SkImageInfo. 294 // The image is known to be a PNG. Decode enough to know the SkImageInfo.
296 png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, nullptr, 295 png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, nullptr,
297 sk_error_fn, sk_warning_fn); 296 sk_error_fn, sk_warning_fn);
298 if (!png_ptr) { 297 if (!png_ptr) {
299 return false; 298 return false;
300 } 299 }
301 300
302 AutoCleanPng autoClean(png_ptr); 301 AutoCleanPng autoClean(png_ptr);
303 302
304 png_infop info_ptr = png_create_info_struct(png_ptr); 303 png_infop info_ptr = png_create_info_struct(png_ptr);
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
342 // TODO: Should we handle this in SkSwizzler? Could this also benefit 341 // TODO: Should we handle this in SkSwizzler? Could this also benefit
343 // RAW decodes? 342 // RAW decodes?
344 if (bitDepth == 16) { 343 if (bitDepth == 16) {
345 SkASSERT(PNG_COLOR_TYPE_PALETTE != encodedColorType); 344 SkASSERT(PNG_COLOR_TYPE_PALETTE != encodedColorType);
346 png_set_strip_16(png_ptr); 345 png_set_strip_16(png_ptr);
347 } 346 }
348 347
349 // Now determine the default colorType and alphaType and set the required tr ansforms. 348 // Now determine the default colorType and alphaType and set the required tr ansforms.
350 // Often, we depend on SkSwizzler to perform any transforms that we need. H owever, we 349 // Often, we depend on SkSwizzler to perform any transforms that we need. H owever, we
351 // still depend on libpng for many of the rare and PNG-specific cases. 350 // still depend on libpng for many of the rare and PNG-specific cases.
352 SkEncodedInfo::Color color; 351 SkColorType colorType = kUnknown_SkColorType;
353 SkEncodedInfo::Alpha alpha; 352 SkAlphaType alphaType = kUnknown_SkAlphaType;
354 switch (encodedColorType) { 353 switch (encodedColorType) {
355 case PNG_COLOR_TYPE_PALETTE: 354 case PNG_COLOR_TYPE_PALETTE:
356 // Extract multiple pixels with bit depths of 1, 2, and 4 from a sin gle 355 // Extract multiple pixels with bit depths of 1, 2, and 4 from a sin gle
357 // byte into separate bytes (useful for paletted and grayscale image s). 356 // byte into separate bytes (useful for paletted and grayscale image s).
358 if (bitDepth < 8) { 357 if (bitDepth < 8) {
359 // TODO: Should we use SkSwizzler here? 358 // TODO: Should we use SkSwizzler here?
360 png_set_packing(png_ptr); 359 png_set_packing(png_ptr);
361 } 360 }
362 361
363 color = SkEncodedInfo::kPalette_Color; 362 colorType = kIndex_8_SkColorType;
364 // Set the alpha depending on if a transparency chunk exists. 363 // Set the alpha type depending on if a transparency chunk exists.
365 alpha = png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS) ? 364 alphaType = png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS) ?
366 SkEncodedInfo::kUnpremul_Alpha : SkEncodedInfo::kOpaque_Alph a; 365 kUnpremul_SkAlphaType : kOpaque_SkAlphaType;
367 break; 366 break;
368 case PNG_COLOR_TYPE_RGB: 367 case PNG_COLOR_TYPE_RGB:
369 if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) { 368 if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {
370 // Convert to RGBA if transparency chunk exists. 369 // Convert to RGBA if transparency chunk exists.
371 png_set_tRNS_to_alpha(png_ptr); 370 png_set_tRNS_to_alpha(png_ptr);
372 color = SkEncodedInfo::kRGBA_Color; 371 alphaType = kUnpremul_SkAlphaType;
373 alpha = SkEncodedInfo::kBinary_Alpha;
374 } else { 372 } else {
375 color = SkEncodedInfo::kRGB_Color; 373 alphaType = kOpaque_SkAlphaType;
376 alpha = SkEncodedInfo::kOpaque_Alpha;
377 } 374 }
375 colorType = kN32_SkColorType;
378 break; 376 break;
379 case PNG_COLOR_TYPE_GRAY: 377 case PNG_COLOR_TYPE_GRAY:
380 // Expand grayscale images to the full 8 bits from 1, 2, or 4 bits/p ixel. 378 // Expand grayscale images to the full 8 bits from 1, 2, or 4 bits/p ixel.
381 if (bitDepth < 8) { 379 if (bitDepth < 8) {
382 // TODO: Should we use SkSwizzler here? 380 // TODO: Should we use SkSwizzler here?
383 png_set_expand_gray_1_2_4_to_8(png_ptr); 381 png_set_expand_gray_1_2_4_to_8(png_ptr);
384 } 382 }
385 383
386 if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) { 384 if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {
387 png_set_tRNS_to_alpha(png_ptr); 385 png_set_tRNS_to_alpha(png_ptr);
388 color = SkEncodedInfo::kGrayAlpha_Color; 386
389 alpha = SkEncodedInfo::kBinary_Alpha; 387 // We will recommend kN32 here since we do not support kGray
388 // with alpha.
389 colorType = kN32_SkColorType;
390 alphaType = kUnpremul_SkAlphaType;
390 } else { 391 } else {
391 color = SkEncodedInfo::kGray_Color; 392 colorType = kGray_8_SkColorType;
392 alpha = SkEncodedInfo::kOpaque_Alpha; 393 alphaType = kOpaque_SkAlphaType;
393 } 394 }
394 break; 395 break;
395 case PNG_COLOR_TYPE_GRAY_ALPHA: 396 case PNG_COLOR_TYPE_GRAY_ALPHA:
396 color = SkEncodedInfo::kGrayAlpha_Color; 397 // We will recommend kN32 here since we do not support anything
397 alpha = SkEncodedInfo::kUnpremul_Alpha; 398 // similar to GRAY_ALPHA.
399 colorType = kN32_SkColorType;
400 alphaType = kUnpremul_SkAlphaType;
398 break; 401 break;
399 case PNG_COLOR_TYPE_RGBA: 402 case PNG_COLOR_TYPE_RGBA:
400 color = SkEncodedInfo::kRGBA_Color; 403 colorType = kN32_SkColorType;
401 alpha = SkEncodedInfo::kUnpremul_Alpha; 404 alphaType = kUnpremul_SkAlphaType;
402 break; 405 break;
403 default: 406 default:
404 // All the color types have been covered above. 407 // All the color types have been covered above.
405 SkASSERT(false); 408 SkASSERT(false);
406 color = SkEncodedInfo::kRGBA_Color;
407 alpha = SkEncodedInfo::kUnpremul_Alpha;
408 } 409 }
409 410
410 int numberPasses = png_set_interlace_handling(png_ptr); 411 int numberPasses = png_set_interlace_handling(png_ptr);
411 if (numberPassesPtr) { 412 if (numberPassesPtr) {
412 *numberPassesPtr = numberPasses; 413 *numberPassesPtr = numberPasses;
413 } 414 }
414 415
415 if (info) { 416 SkColorProfileType profileType = kLinear_SkColorProfileType;
416 *info = SkEncodedInfo::Make(color, alpha, 8); 417 if (png_get_valid(png_ptr, info_ptr, PNG_INFO_sRGB)) {
418 profileType = kSRGB_SkColorProfileType;
417 } 419 }
418 if (width) { 420
419 *width = origWidth; 421 if (imageInfo) {
420 } 422 *imageInfo = SkImageInfo::Make(origWidth, origHeight, colorType, alphaTy pe, profileType);
421 if (height) {
422 *height = origHeight;
423 } 423 }
424 autoClean.release(); 424 autoClean.release();
425 if (png_ptrp) { 425 if (png_ptrp) {
426 *png_ptrp = png_ptr; 426 *png_ptrp = png_ptr;
427 } 427 }
428 if (info_ptrp) { 428 if (info_ptrp) {
429 *info_ptrp = info_ptr; 429 *info_ptrp = info_ptr;
430 } 430 }
431 431
432 return true; 432 return true;
433 } 433 }
434 434
435 SkPngCodec::SkPngCodec(int width, int height, const SkEncodedInfo& info, SkStrea m* stream, 435 SkPngCodec::SkPngCodec(const SkImageInfo& info, SkStream* stream, SkPngChunkRead er* chunkReader,
436 SkPngChunkReader* chunkReader, png_structp png_ptr, png_i nfop info_ptr, 436 png_structp png_ptr, png_infop info_ptr, int bitDepth, in t numberPasses,
437 int bitDepth, int numberPasses, sk_sp<SkColorSpace> color Space) 437 sk_sp<SkColorSpace> colorSpace)
438 : INHERITED(width, height, info, stream, colorSpace) 438 : INHERITED(info, stream, colorSpace)
439 , fPngChunkReader(SkSafeRef(chunkReader)) 439 , fPngChunkReader(SkSafeRef(chunkReader))
440 , fPng_ptr(png_ptr) 440 , fPng_ptr(png_ptr)
441 , fInfo_ptr(info_ptr) 441 , fInfo_ptr(info_ptr)
442 , fSrcConfig(SkSwizzler::kUnknown) 442 , fSrcConfig(SkSwizzler::kUnknown)
443 , fNumberPasses(numberPasses) 443 , fNumberPasses(numberPasses)
444 , fBitDepth(bitDepth) 444 , fBitDepth(bitDepth)
445 {} 445 {}
446 446
447 SkPngCodec::~SkPngCodec() { 447 SkPngCodec::~SkPngCodec() {
448 this->destroyReadStruct(); 448 this->destroyReadStruct();
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
531 // This sets fPng_ptr and fInfo_ptr to nullptr. If read_header 531 // This sets fPng_ptr and fInfo_ptr to nullptr. If read_header
532 // succeeds, they will be repopulated, and if it fails, they will 532 // succeeds, they will be repopulated, and if it fails, they will
533 // remain nullptr. Any future accesses to fPng_ptr and fInfo_ptr will 533 // remain nullptr. Any future accesses to fPng_ptr and fInfo_ptr will
534 // come through this function which will rewind and again attempt 534 // come through this function which will rewind and again attempt
535 // to reinitialize them. 535 // to reinitialize them.
536 this->destroyReadStruct(); 536 this->destroyReadStruct();
537 537
538 png_structp png_ptr; 538 png_structp png_ptr;
539 png_infop info_ptr; 539 png_infop info_ptr;
540 if (!read_header(this->stream(), fPngChunkReader.get(), &png_ptr, &info_ptr, 540 if (!read_header(this->stream(), fPngChunkReader.get(), &png_ptr, &info_ptr,
541 nullptr, nullptr, nullptr, nullptr, nullptr)) { 541 nullptr, nullptr, nullptr)) {
542 return false; 542 return false;
543 } 543 }
544 544
545 fPng_ptr = png_ptr; 545 fPng_ptr = png_ptr;
546 fInfo_ptr = info_ptr; 546 fInfo_ptr = info_ptr;
547 return true; 547 return true;
548 } 548 }
549 549
550 SkCodec::Result SkPngCodec::onGetPixels(const SkImageInfo& requestedInfo, void* dst, 550 SkCodec::Result SkPngCodec::onGetPixels(const SkImageInfo& requestedInfo, void* dst,
551 size_t dstRowBytes, const Options& optio ns, 551 size_t dstRowBytes, const Options& optio ns,
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
637 const SkPMColor* colorPtr = get_color_ptr(fColorTable.get()); 637 const SkPMColor* colorPtr = get_color_ptr(fColorTable.get());
638 if (colorPtr) { 638 if (colorPtr) {
639 return get_color_table_fill_value(colorType, colorPtr, 0); 639 return get_color_table_fill_value(colorType, colorPtr, 0);
640 } 640 }
641 return INHERITED::onGetFillValue(colorType); 641 return INHERITED::onGetFillValue(colorType);
642 } 642 }
643 643
644 // Subclass of SkPngCodec which supports scanline decoding 644 // Subclass of SkPngCodec which supports scanline decoding
645 class SkPngScanlineDecoder : public SkPngCodec { 645 class SkPngScanlineDecoder : public SkPngCodec {
646 public: 646 public:
647 SkPngScanlineDecoder(int width, int height, const SkEncodedInfo& info, SkStr eam* stream, 647 SkPngScanlineDecoder(const SkImageInfo& srcInfo, SkStream* stream,
648 SkPngChunkReader* chunkReader, png_structp png_ptr, png_infop info_p tr, int bitDepth, 648 SkPngChunkReader* chunkReader, png_structp png_ptr, png_infop info_p tr, int bitDepth,
649 sk_sp<SkColorSpace> colorSpace) 649 sk_sp<SkColorSpace> colorSpace)
650 : INHERITED(width, height, info, stream, chunkReader, png_ptr, info_ptr, bitDepth, 1, 650 : INHERITED(srcInfo, stream, chunkReader, png_ptr, info_ptr, bitDepth, 1 , colorSpace)
651 colorSpace)
652 , fSrcRow(nullptr) 651 , fSrcRow(nullptr)
653 {} 652 {}
654 653
655 Result onStartScanlineDecode(const SkImageInfo& dstInfo, const Options& opti ons, 654 Result onStartScanlineDecode(const SkImageInfo& dstInfo, const Options& opti ons,
656 SkPMColor ctable[], int* ctableCount) override { 655 SkPMColor ctable[], int* ctableCount) override {
657 if (!conversion_possible(dstInfo, this->getInfo())) { 656 if (!conversion_possible(dstInfo, this->getInfo())) {
658 return kInvalidConversion; 657 return kInvalidConversion;
659 } 658 }
660 659
661 const Result result = this->initializeSwizzler(dstInfo, options, ctable, 660 const Result result = this->initializeSwizzler(dstInfo, options, ctable,
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
704 private: 703 private:
705 SkAutoTMalloc<uint8_t> fStorage; 704 SkAutoTMalloc<uint8_t> fStorage;
706 uint8_t* fSrcRow; 705 uint8_t* fSrcRow;
707 706
708 typedef SkPngCodec INHERITED; 707 typedef SkPngCodec INHERITED;
709 }; 708 };
710 709
711 710
712 class SkPngInterlacedScanlineDecoder : public SkPngCodec { 711 class SkPngInterlacedScanlineDecoder : public SkPngCodec {
713 public: 712 public:
714 SkPngInterlacedScanlineDecoder(int width, int height, const SkEncodedInfo& i nfo, 713 SkPngInterlacedScanlineDecoder(const SkImageInfo& srcInfo, SkStream* stream,
715 SkStream* stream, SkPngChunkReader* chunkReader, png_structp png_ptr , 714 SkPngChunkReader* chunkReader, png_structp png_ptr, png_infop info_p tr,
716 png_infop info_ptr, int bitDepth, int numberPasses, sk_sp<SkColorSpa ce> colorSpace) 715 int bitDepth, int numberPasses, sk_sp<SkColorSpace> colorSpace)
717 : INHERITED(width, height, info, stream, chunkReader, png_ptr, info_ptr, bitDepth, 716 : INHERITED(srcInfo, stream, chunkReader, png_ptr, info_ptr, bitDepth, n umberPasses,
718 numberPasses, colorSpace) 717 colorSpace)
719 , fHeight(-1) 718 , fHeight(-1)
720 , fCanSkipRewind(false) 719 , fCanSkipRewind(false)
721 { 720 {
722 SkASSERT(numberPasses != 1); 721 SkASSERT(numberPasses != 1);
723 } 722 }
724 723
725 Result onStartScanlineDecode(const SkImageInfo& dstInfo, const Options& opti ons, 724 Result onStartScanlineDecode(const SkImageInfo& dstInfo, const Options& opti ons,
726 SkPMColor ctable[], int* ctableCount) override { 725 SkPMColor ctable[], int* ctableCount) override {
727 if (!conversion_possible(dstInfo, this->getInfo())) { 726 if (!conversion_possible(dstInfo, this->getInfo())) {
728 return kInvalidConversion; 727 return kInvalidConversion;
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
830 // add another layer. 829 // add another layer.
831 bool fCanSkipRewind; 830 bool fCanSkipRewind;
832 831
833 typedef SkPngCodec INHERITED; 832 typedef SkPngCodec INHERITED;
834 }; 833 };
835 834
836 SkCodec* SkPngCodec::NewFromStream(SkStream* stream, SkPngChunkReader* chunkRead er) { 835 SkCodec* SkPngCodec::NewFromStream(SkStream* stream, SkPngChunkReader* chunkRead er) {
837 SkAutoTDelete<SkStream> streamDeleter(stream); 836 SkAutoTDelete<SkStream> streamDeleter(stream);
838 png_structp png_ptr; 837 png_structp png_ptr;
839 png_infop info_ptr; 838 png_infop info_ptr;
840 int width, height; 839 SkImageInfo imageInfo;
841 SkEncodedInfo imageInfo;
842 int bitDepth; 840 int bitDepth;
843 int numberPasses; 841 int numberPasses;
844 842
845 if (!read_header(stream, chunkReader, &png_ptr, &info_ptr, &width, &height, &imageInfo, 843 if (!read_header(stream, chunkReader, &png_ptr, &info_ptr, &imageInfo, &bitD epth,
846 &bitDepth, &numberPasses)) { 844 &numberPasses)) {
847 return nullptr; 845 return nullptr;
848 } 846 }
849 847
850 auto colorSpace = read_color_space(png_ptr, info_ptr); 848 auto colorSpace = read_color_space(png_ptr, info_ptr);
851 849
852 if (1 == numberPasses) { 850 if (1 == numberPasses) {
853 return new SkPngScanlineDecoder(width, height, imageInfo, streamDeleter. release(), 851 return new SkPngScanlineDecoder(imageInfo, streamDeleter.release(), chun kReader,
854 chunkReader, png_ptr, info_ptr, bitDepth , colorSpace); 852 png_ptr, info_ptr, bitDepth, colorSpace) ;
855 } 853 }
856 854
857 return new SkPngInterlacedScanlineDecoder(width, height, imageInfo, streamDe leter.release(), 855 return new SkPngInterlacedScanlineDecoder(imageInfo, streamDeleter.release() , chunkReader,
858 chunkReader, png_ptr, info_ptr, bi tDepth, 856 png_ptr, info_ptr, bitDepth, numbe rPasses,
859 numberPasses, colorSpace); 857 colorSpace);
860 } 858 }
OLDNEW
« no previous file with comments | « src/codec/SkPngCodec.h ('k') | src/codec/SkRawCodec.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698