Index: src/codec/SkCodec_libpng.cpp |
diff --git a/src/codec/SkCodec_libpng.cpp b/src/codec/SkCodec_libpng.cpp |
index 4850235c0794ab591e8e16167d0409be214a313c..bc4f35f017c863ee566842bbd953300f86f24728 100644 |
--- a/src/codec/SkCodec_libpng.cpp |
+++ b/src/codec/SkCodec_libpng.cpp |
@@ -66,6 +66,14 @@ static void sk_read_fn(png_structp png_ptr, png_bytep data, |
} |
} |
+#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED |
+static int sk_read_user_chunk(png_structp png_ptr, png_unknown_chunkp chunk) { |
+ SkChunkReader* chunkReader = (SkChunkReader*)png_get_user_chunk_ptr(png_ptr); |
+ // peek() returning true means continue decoding |
+ return chunkReader->readChunk((const char*)chunk->name, chunk->data, chunk->size) ? 1 : -1; |
+} |
+#endif |
+ |
/////////////////////////////////////////////////////////////////////////////// |
// Helpers |
/////////////////////////////////////////////////////////////////////////////// |
@@ -201,7 +209,7 @@ bool SkPngCodec::IsPng(SkStream* stream) { |
return true; |
} |
-SkCodec* SkPngCodec::NewFromStream(SkStream* stream) { |
+SkCodec* SkPngCodec::NewFromStream(SkStream* stream, SkChunkReader* chunkReader) { |
// The image is known to be a PNG. Decode enough to know the SkImageInfo. |
png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, |
sk_error_fn, sk_warning_fn); |
@@ -226,10 +234,13 @@ SkCodec* SkPngCodec::NewFromStream(SkStream* stream) { |
png_set_read_fn(png_ptr, static_cast<void*>(stream), sk_read_fn); |
- // FIXME: This is where the old code hooks up the Peeker. Does it need to |
- // be set this early? (i.e. where are the user chunks? early in the stream, |
- // potentially?) |
- // If it does, we need to figure out a way to set it here. |
+#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED |
+ // hookup our chunkReader so we can see any user-chunks the caller may be interested in |
+ if (chunkReader) { |
+ png_set_keep_unknown_chunks(png_ptr, PNG_HANDLE_CHUNK_ALWAYS, (png_byte*)"", 0); |
+ png_set_read_user_chunk_fn(png_ptr, (png_voidp) chunkReader, sk_read_user_chunk); |
+ } |
+#endif |
// The call to png_read_info() gives us all of the information from the |
// PNG file before the first IDAT (image data chunk). |
@@ -327,15 +338,16 @@ SkCodec* SkPngCodec::NewFromStream(SkStream* stream) { |
SkImageInfo info = SkImageInfo::Make(origWidth, origHeight, skColorType, |
skAlphaType); |
- SkCodec* codec = SkNEW_ARGS(SkPngCodec, (info, stream, png_ptr, info_ptr)); |
+ SkCodec* codec = SkNEW_ARGS(SkPngCodec, (info, stream, chunkReader, png_ptr, info_ptr)); |
autoClean.detach(); |
return codec; |
} |
#define INVALID_NUMBER_PASSES -1 |
-SkPngCodec::SkPngCodec(const SkImageInfo& info, SkStream* stream, |
+SkPngCodec::SkPngCodec(const SkImageInfo& info, SkStream* stream, SkChunkReader* chunkReader, |
png_structp png_ptr, png_infop info_ptr) |
: INHERITED(info, stream) |
+ , fChunkReader(SkSafeRef(chunkReader)) |
, fPng_ptr(png_ptr) |
, fInfo_ptr(info_ptr) |
, fSrcConfig(SkSwizzler::kUnknown) |