[go: up one dir, main page]

Menu

[b3449b]: / pngsave.c  Maximize  Restore  History

Download this file

112 lines (89 with data), 2.8 kB

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
/*
* pngsave.c - save PNG file
*
* Copyright (C) 2009 Piotr Fusik and Adrian Matoga
*
* This file is part of FAIL (First Atari Image Library),
* see http://fail.sourceforge.net
*
* FAIL 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.
*
* FAIL 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 FAIL; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <stdlib.h>
#include <png.h>
#include "pngsave.h"
abool PNG_Save(const char *filename,
int width, int height, int colors,
const byte pixels[], const byte palette[])
{
FILE *fp;
png_structp png_ptr;
png_infop info_ptr;
png_byte bit_depth;
png_bytep *row_pointers;
int i, bpp = palette != NULL && colors <= 256 ? 1 : 3;
row_pointers = (png_bytep*)malloc(height * sizeof(png_bytep));
if (row_pointers == NULL)
return FALSE;
fp = fopen(filename, "wb");
if (fp == NULL)
return FALSE;
png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if (png_ptr == NULL) {
fclose(fp);
return FALSE;
}
info_ptr = png_create_info_struct(png_ptr);
if (info_ptr == NULL) {
fclose(fp);
png_destroy_write_struct(&png_ptr, png_infopp_NULL);
return FALSE;
}
/* Set error handling. */
if (setjmp(png_jmpbuf(png_ptr))) {
/* If we get here, we had a problem writing the file */
fclose(fp);
free(row_pointers);
png_destroy_write_struct(&png_ptr, &info_ptr);
return FALSE;
}
png_init_io(png_ptr, fp);
bit_depth = 8;
if (palette != NULL) {
if (colors <= 2)
bit_depth = 1;
else if (colors <= 4)
bit_depth = 2;
else if (colors <= 16)
bit_depth = 4;
}
png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth,
palette != NULL && colors <= 256 ?
PNG_COLOR_TYPE_PALETTE : PNG_COLOR_TYPE_RGB,
PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE,
PNG_FILTER_TYPE_BASE);
if (palette != NULL && colors <= 256)
png_set_PLTE(png_ptr, info_ptr, (png_colorp)palette, colors);
png_write_info(png_ptr, info_ptr);
if (bit_depth < 8)
png_set_packing(png_ptr);
for (i = 0; i < height; i++)
row_pointers[i] = (png_bytep)(pixels + i*width*bpp);
png_write_image(png_ptr, row_pointers);
free(row_pointers);
png_write_end(png_ptr, info_ptr);
png_destroy_write_struct(&png_ptr, &info_ptr);
fclose(fp);
return TRUE;
}