1 /*
2 Copyright (C) 2009-2021 Parallel Realities
3 
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
8 
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12 
13 See the GNU General Public License for more details.
14 
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
18 */
19 
20 #include "../headers.h"
21 
22 #include "../init.h"
23 #include "graphics.h"
24 
25 #include <png.h>
26 
27 /*
28 SDL PNG saving routine taken from pygame - Python Game Library
29 */
30 
writeData(char * name,png_bytep * rows,int w,int h,int colourtype,int bitdepth)31 static void writeData(char *name, png_bytep *rows, int w, int h, int colourtype, int bitdepth)
32 {
33 	png_structp pngPtr;
34 	png_infop infoPtr;
35 	FILE *fp;
36 
37 	fp = fopen(name, "wb");
38 
39 	if (fp == NULL)
40 	{
41 		printf("Could not save %s\n", name);
42 
43 		cleanup(1);
44 	}
45 
46 	pngPtr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
47 
48 	if (pngPtr == NULL)
49 	{
50 		printf("Failed to create PNG structure");
51 
52 		cleanup(1);
53 	}
54 
55 	infoPtr = png_create_info_struct(pngPtr);
56 
57 	if (infoPtr == NULL)
58 	{
59 		printf("Failed to create PNG info");
60 
61 		cleanup(1);
62 	}
63 
64 	if (setjmp(png_jmpbuf(pngPtr)) != 0)
65 	{
66 		printf("PNG Jump point failed\n");
67 
68 		cleanup(1);
69 	}
70 
71 	png_init_io(pngPtr, fp);
72 
73 	png_set_IHDR(pngPtr, infoPtr, w, h, bitdepth, colourtype, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
74 
75 	png_write_info(pngPtr, infoPtr);
76 
77 	png_write_image(pngPtr, rows);
78 
79 	png_write_end(pngPtr, NULL);
80 
81 	png_destroy_write_struct(&pngPtr, &infoPtr);
82 
83 	fclose(fp);
84 }
85 
savePNG(SDL_Surface * surface,char * name)86 void savePNG(SDL_Surface *surface, char *name)
87 {
88 	unsigned char** ss_rows;
89 	int ss_size;
90 	int ss_w, ss_h;
91 	SDL_Surface *temp;
92 	SDL_Rect ss_rect;
93 	int i;
94 
95 	ss_rows = 0;
96 	ss_size = 0;
97 	temp = NULL;
98 
99 	ss_w = surface->w;
100 	ss_h = surface->h;
101 
102 	temp = createSurface(surface->w, surface->h, FALSE);
103 
104 	ss_rect.x = 0;
105 	ss_rect.y = 0;
106 	ss_rect.w = ss_w;
107 	ss_rect.h = ss_h;
108 
109 	SDL_BlitSurface(surface, &ss_rect, temp, NULL);
110 
111 	if (ss_size == 0)
112 	{
113 		ss_size = ss_h;
114 		ss_rows = malloc(sizeof (unsigned char*) * ss_size);
115 
116 		if (ss_rows == NULL)
117 		{
118 			printf("Ran out of memory when creating PNG rows\n");
119 
120 			cleanup(1);
121 		}
122 	}
123 
124 	for (i = 0; i < ss_h; i++)
125 	{
126 		ss_rows[i] = ((unsigned char*)temp->pixels) + i * temp->pitch;
127 	}
128 
129 	writeData(name, ss_rows, surface->w, surface->h, PNG_COLOR_TYPE_RGB_ALPHA, 8);
130 
131 	free(ss_rows);
132 
133 	SDL_FreeSurface(temp);
134 
135 	temp = NULL;
136 }
137