From 7750982af6159d0bcb01336da915d93c88318886 Mon Sep 17 00:00:00 2001 From: David Capello Date: Tue, 16 Feb 2016 18:18:29 -0300 Subject: [PATCH] Support loading interlaced PNG files in png decoder (PngFormat::onLoad()) --- src/app/file/png_format.cpp | 186 +++++++++++++++++++----------------- 1 file changed, 96 insertions(+), 90 deletions(-) diff --git a/src/app/file/png_format.cpp b/src/app/file/png_format.cpp index 8c7e6c45e..d06ea2186 100644 --- a/src/app/file/png_format.cpp +++ b/src/app/file/png_format.cpp @@ -1,5 +1,5 @@ // Aseprite -// Copyright (C) 2001-2015 David Capello +// Copyright (C) 2001-2016 David Capello // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License version 2 as @@ -69,7 +69,7 @@ bool PngFormat::onLoad(FileOp* fop) int pass, number_passes; int num_palette; png_colorp palette; - png_bytep row_pointer; + png_bytepp rows_pointer; PixelFormat pixelFormat; FileHandle handle(open_file_with_exception(fop->filename(), "rb")); @@ -227,95 +227,13 @@ bool PngFormat::onLoad(FileOp* fop) } // Allocate the memory to hold the image using the fields of info_ptr. - row_pointer = (png_bytep)png_malloc(png_ptr, png_get_rowbytes(png_ptr, info_ptr)); + rows_pointer = (png_bytepp)png_malloc(png_ptr, sizeof(png_bytep) * height); + for (y = 0; y < height; y++) + rows_pointer[y] = (png_bytep)png_malloc(png_ptr, png_get_rowbytes(png_ptr, info_ptr)); + for (pass = 0; pass < number_passes; pass++) { for (y = 0; y < height; y++) { - // Read the line - png_read_row(png_ptr, row_pointer, (png_byte*)NULL); - - // RGB_ALPHA - if (png_get_color_type(png_ptr, info_ptr) == PNG_COLOR_TYPE_RGB_ALPHA) { - uint8_t* src_address = row_pointer; - uint32_t* dst_address = (uint32_t*)image->getPixelAddress(0, y); - unsigned int x, r, g, b, a; - - for (x=0; xgetPixelAddress(0, y); - unsigned int x, r, g, b, a; - - for (x=0; xred && - g == png_trans_color->green && - b == png_trans_color->blue) { - a = 0; - if (!fop->sequenceGetHasAlpha()) - fop->sequenceSetHasAlpha(true); - } - else - a = 255; - - *(dst_address++) = rgba(r, g, b, a); - } - } - // GRAY_ALPHA - else if (png_get_color_type(png_ptr, info_ptr) == PNG_COLOR_TYPE_GRAY_ALPHA) { - uint8_t* src_address = row_pointer; - uint16_t* dst_address = (uint16_t*)image->getPixelAddress(0, y); - unsigned int x, k, a; - - for (x=0; xgetPixelAddress(0, y); - unsigned int x, k, a; - - for (x=0; xgray) { - a = 0; - if (!fop->sequenceGetHasAlpha()) - fop->sequenceSetHasAlpha(true); - } - else - a = 255; - - *(dst_address++) = graya(k, a); - } - } - // PALETTE - else if (png_get_color_type(png_ptr, info_ptr) == PNG_COLOR_TYPE_PALETTE) { - uint8_t* src_address = row_pointer; - uint8_t* dst_address = (uint8_t*)image->getPixelAddress(0, y); - unsigned int x; - - for (x=0; xsetProgress( (double)((double)pass + (double)(y+1) / (double)(height)) @@ -325,7 +243,95 @@ bool PngFormat::onLoad(FileOp* fop) break; } } - png_free(png_ptr, row_pointer); + + // Convert rows_pointer into the doc::Image + for (y = 0; y < height; y++) { + // RGB_ALPHA + if (png_get_color_type(png_ptr, info_ptr) == PNG_COLOR_TYPE_RGB_ALPHA) { + uint8_t* src_address = rows_pointer[y]; + uint32_t* dst_address = (uint32_t*)image->getPixelAddress(0, y); + unsigned int x, r, g, b, a; + + for (x=0; xgetPixelAddress(0, y); + unsigned int x, r, g, b, a; + + for (x=0; xred && + g == png_trans_color->green && + b == png_trans_color->blue) { + a = 0; + if (!fop->sequenceGetHasAlpha()) + fop->sequenceSetHasAlpha(true); + } + else + a = 255; + + *(dst_address++) = rgba(r, g, b, a); + } + } + // GRAY_ALPHA + else if (png_get_color_type(png_ptr, info_ptr) == PNG_COLOR_TYPE_GRAY_ALPHA) { + uint8_t* src_address = rows_pointer[y]; + uint16_t* dst_address = (uint16_t*)image->getPixelAddress(0, y); + unsigned int x, k, a; + + for (x=0; xgetPixelAddress(0, y); + unsigned int x, k, a; + + for (x=0; xgray) { + a = 0; + if (!fop->sequenceGetHasAlpha()) + fop->sequenceSetHasAlpha(true); + } + else + a = 255; + + *(dst_address++) = graya(k, a); + } + } + // PALETTE + else if (png_get_color_type(png_ptr, info_ptr) == PNG_COLOR_TYPE_PALETTE) { + uint8_t* src_address = rows_pointer[y]; + uint8_t* dst_address = (uint8_t*)image->getPixelAddress(0, y); + unsigned int x; + + for (x=0; x