/* * This file is part of the Scale2x project. * * Copyright (C) 2003 Andrea Mazzoleni * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "file.h" #include #include int file_write(const char* file, unsigned char* ptr, unsigned slice, unsigned pixel, unsigned width, unsigned height, int type, int channel, png_color* palette, unsigned palette_size) { png_struct* png_ptr; png_info* info_ptr; png_byte** row; unsigned i; int bit_depth; FILE* fp; row = malloc(sizeof(void*) * height); if (!row) { fprintf(stderr,"Low memory.\n"); goto err; } for(i=0;i 4) png_set_strip_16(png_ptr); /* normalize the pixel value after an expand */ if (pre_type != PNG_COLOR_TYPE_PALETTE) { if (png_get_sBIT(png_ptr, info_ptr, &sig_bit)) png_set_shift(png_ptr, sig_bit); } /* expand to 8 bit */ if (bit_depth < 8) png_set_packing(png_ptr); /* add alpha channel */ if (allow_only124 && pre_type == PNG_COLOR_TYPE_RGB) png_set_filler(png_ptr, 0xFF, PNG_FILLER_AFTER); png_read_update_info(png_ptr, info_ptr); bit_depth = png_get_bit_depth(png_ptr, info_ptr); *channel = png_get_channels(png_ptr, info_ptr); *width = png_get_image_width(png_ptr, info_ptr); *height = png_get_image_height(png_ptr, info_ptr); *type = png_get_color_type(png_ptr, info_ptr); if (*type == PNG_COLOR_TYPE_PALETTE) { png_get_PLTE(png_ptr, info_ptr, &pal, &size); *palette = malloc(sizeof(png_color) * size); if (!*palette) { fprintf(stderr,"Low memory.\n"); return -1; } *palette_size = size; for(i=0;i<*palette_size;++i) (*palette)[i] = pal[i]; } else { *palette = 0; *palette_size = 0; } *pixel = *channel * ((bit_depth + 7) / 8); if (*type == PNG_COLOR_TYPE_RGB && *channel == 4) *type = PNG_COLOR_TYPE_RGB_ALPHA; *slice = *width * *pixel; *ptr = malloc(*height * *slice); if (!*ptr) { fprintf(stderr,"Low memory.\n"); goto err_destroy; } row = malloc(sizeof(void*) * *height); if (!row) { fprintf(stderr,"Low memory.\n"); goto err_destroy; } for(i=0;i<*height;++i) { row[i] = *ptr + i * *slice; } png_read_image(png_ptr, row); png_read_end(png_ptr, 0); free(row); png_destroy_read_struct(&png_ptr, &info_ptr, 0); fclose(fp); return 0; err_destroy: free(*palette); free(*ptr); free(row); png_destroy_read_struct(&png_ptr, &info_ptr, 0); err_close: fclose(fp); err: return -1; }