3
Copyright (C) 2001-2012 Mathew Eis <mathew@eisbox.net>
5
This library is free software; you can redistribute it and/or
6
modify it under the terms of the GNU Lesser General Public
7
License as published by the Free Software Foundation; either
8
version 2.1 of the License, or (at your option) any later version.
10
This library is distributed in the hope that it will be useful,
11
but WITHOUT ANY WARRANTY; without even the implied warranty of
12
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
Lesser General Public License for more details.
15
You should have received a copy of the GNU Lesser General Public
16
License along with this library; if not, write to the
17
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18
Boston, MA 02110-1301, USA.
27
#include "icns_internals.h"
31
typedef struct icns_png_io_ref {
37
static void icns_png_read_memory(png_structp png_ptr, png_bytep data, png_size_t length) {
38
icns_png_io_ref* _ref = (icns_png_io_ref*) png_get_io_ptr( png_ptr );
39
memcpy( data, (char*)_ref->data + _ref->offset, length );
40
_ref->offset += length;
43
int icns_png_to_image(icns_size_t dataSize, icns_byte_t *dataPtr, icns_image_t *imageOut)
45
int error = ICNS_STATUS_OK;
46
png_structp png_ptr = NULL;
47
png_infop info_ptr = NULL;
59
icns_print_err("icns_png_to_image: JP2 data is NULL!\n");
60
return ICNS_STATUS_NULL_PARAM;
65
icns_print_err("icns_png_to_image: Image out is NULL!\n");
66
return ICNS_STATUS_NULL_PARAM;
71
icns_print_err("icns_png_to_image: Invalid data size! (%d)\n",dataSize);
72
return ICNS_STATUS_INVALID_DATA;
76
printf("Decoding PNG image...\n");
79
png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
82
return ICNS_STATUS_NO_MEMORY;
85
info_ptr = png_create_info_struct(png_ptr);
87
if(info_ptr == NULL) {
88
png_destroy_read_struct(&png_ptr, NULL, NULL);
89
return ICNS_STATUS_NO_MEMORY;
92
if (setjmp(png_jmpbuf(png_ptr)))
94
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
95
return ICNS_STATUS_INVALID_DATA;
98
// set libpng to read from memory
99
icns_png_io_ref io_data = { dataPtr, dataSize, 0 };
100
png_set_read_fn(png_ptr, (void *)&io_data, &icns_png_read_memory);
102
png_read_info(png_ptr, info_ptr);
103
png_get_IHDR(png_ptr, info_ptr, &w, &h, &bit_depth, &color_type, NULL, NULL, NULL);
107
case PNG_COLOR_TYPE_RGB:
108
if (bit_depth == 16) {
109
png_set_strip_16(png_ptr);
113
png_set_add_alpha(png_ptr, 0xff, PNG_FILLER_AFTER);
116
case PNG_COLOR_TYPE_RGB_ALPHA:
117
if (bit_depth == 16) {
118
png_set_strip_16(png_ptr);
125
png_read_update_info(png_ptr, info_ptr);
127
rowsize = png_get_rowbytes(png_ptr, info_ptr);
128
rows = malloc (sizeof(png_bytep) * h);
130
imageOut->imageWidth = w;
131
imageOut->imageHeight = h;
132
imageOut->imageChannels = 4;
133
imageOut->imagePixelDepth = 8;
134
imageOut->imageDataSize = w * h * 4;
135
imageOut->imageData = malloc( rowsize * h + 8 );
137
if(imageOut->imageData == NULL) {
138
png_destroy_read_struct(&png_ptr, NULL, NULL);
140
return ICNS_STATUS_NO_MEMORY;
143
rows[0] = imageOut->imageData;
144
for (row = 1; row < h; row++) {
145
rows[row] = rows[row-1] + rowsize;
148
png_read_image(png_ptr, rows);
149
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
154
if(error == ICNS_STATUS_OK) {
155
printf(" decode result:\n");
156
printf(" width is: %d\n",imageOut->imageWidth);
157
printf(" height is: %d\n",imageOut->imageHeight);
158
printf(" channels are: %d\n",imageOut->imageChannels);
159
printf(" pixel depth is: %d\n",imageOut->imagePixelDepth);
160
printf(" data size is: %d\n",(int)imageOut->imageDataSize);
162
printf(" decode failed.\n");
170
int icns_image_to_png(icns_image_t *image, icns_size_t *dataSizeOut, icns_byte_t **dataPtrOut)
172
int error = ICNS_STATUS_OK;
176
icns_print_err("icns_image_to_png: Image is NULL!\n");
177
return ICNS_STATUS_NULL_PARAM;
180
if(dataSizeOut == NULL)
182
icns_print_err("icns_image_to_png: Data size NULL!\n");
183
return ICNS_STATUS_NULL_PARAM;
186
if(dataPtrOut == NULL)
188
icns_print_err("icns_image_to_png: Data ref is NULL!\n");
189
return ICNS_STATUS_NULL_PARAM;
193
printf("Encoding PNG image...\n");
197
// Verify that size is > 256x256 and 32-bit
198
// Then convert an icns_image to PNG data