Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
5131 clevermous 1
/*
2
	SDL_anim:  an animation library for SDL
3
	Copyright (C) 2001, 2002  Michael Leonhard
4
 
5
	This library is free software; you can redistribute it and/or
6
	modify it under the terms of the GNU Library General Public
7
	License as published by the Free Software Foundation; either
8
	version 2 of the License, or (at your option) any later version.
9
 
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
	Library General Public License for more details.
14
 
15
	You should have received a copy of the GNU Library General Public
16
	License along with this library; if not, write to the Free
17
	Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18
 
19
	Michael Leonhard
20
	mike@tamale.net
21
*/
22
 
23
#include 
24
#include 
25
#include 
26
 
27
/* deal with MSVC++ crappiness */
28
#ifdef WIN32
29
	#define snprintf _snprintf
30
	#endif
31
 
32
typedef struct inputstruct {
33
	FILE *file;
34
	char *name;
35
	png_structp read_ptr;
36
	png_infop read_info_ptr;
37
	};
38
 
39
int numfiles;
40
struct inputstruct *input;
41
 
42
int main( int argc, char *argv[] ) {
43
	int f, rowbytes;
44
	char buf[256];
45
	static FILE *fpout;  /* "static" prevents setjmp corruption */
46
	png_structp write_ptr;
47
	png_infop write_info_ptr, end_info_ptr;
48
	png_bytep row_buf, here;
49
	png_uint_32 y;
50
	png_textp text_ptr, new_text_ptr;
51
	int num_text;
52
 
53
	int interlace_type, compression_type, filter_type, bit_depth, color_type;
54
	int it, ct, ft, bd, clrt;
55
	png_uint_32 width, height, w, h;
56
 
57
	int duration;
58
 
59
	if( argc < 4 ) {
60
		printf( "makeanim v0.2\nusage: makeanim   \n" );
61
		printf( "example: makeanim 1500 a00.png a01.png a02.png a03.png a04.png a.anim\n" );
62
		return 1;
63
		}
64
 
65
	duration = atoi( argv[1] );
66
	if( duration < 1 ) {
67
		printf( "duration is incorrect\n" );
68
		return 1;
69
		}
70
 
71
	numfiles = argc - 3;
72
	input = (struct inputstruct *)malloc( sizeof( struct inputstruct ) * numfiles );
73
	if( !input ) return 1;
74
 
75
	for( f = 0; f < numfiles; f++ ) {
76
		input[f].name = argv[f + 2];
77
		printf( "opening file %d, \"%s\"\n", f, input[f].name );
78
 
79
		/* open the file handle */
80
		input[f].file = fopen( input[f].name, "rb" );
81
		if( input[f].file == NULL ) {
82
			printf( "fopen() failed\n" );
83
			return 1;
84
			}
85
 
86
		/* check if it's PNG */
87
		if( fread( buf, 1, 8, input[f].file ) != 8 ) {
88
			printf( "fread() failed for file \"%s\"\n", input[f].name );
89
			return 1;
90
			}
91
		if( png_sig_cmp( buf, (png_size_t)0, 8 ) ) {
92
			printf( "not a PNG file\n" );
93
			return 1;
94
			}
95
		fseek( input[f].file, 0, SEEK_SET );
96
 
97
		/* allocate read structure */
98
		input[f].read_ptr = png_create_read_struct( PNG_LIBPNG_VER_STRING, (png_voidp)NULL, (png_error_ptr)NULL, (png_error_ptr)NULL );
99
		if( input[f].read_ptr == NULL ) {
100
			printf( "png_create_read_struct() failed\n" );
101
			return 1;
102
			}
103
 
104
		/* allocate read info structure */
105
		input[f].read_info_ptr = png_create_info_struct( input[f].read_ptr );
106
		if( input[f].read_info_ptr == NULL ) {
107
			printf( "png_create_info_struct() failed\n" );
108
			return 1;
109
			}
110
 
111
 
112
		/* set error handler code */
113
		if( setjmp( input[f].read_ptr->jmpbuf ) ) {
114
			printf( "libpng read error\n" );
115
			return 1;
116
			}
117
 
118
		/* initialize stream */
119
		png_init_io( input[f].read_ptr, input[f].file );
120
		png_set_read_status_fn( input[f].read_ptr, NULL );
121
 
122
		/* read png info struct */
123
		png_read_info( input[f].read_ptr, input[f].read_info_ptr );
124
 
125
		/* get the info */
126
		if( !png_get_IHDR( input[f].read_ptr, input[f].read_info_ptr, &w, &h, &bd, &clrt, &it, &ct, &ft ) ) {
127
			printf( "png_get_IHDR() failed\n" );
128
			return 1;
129
			}
130
 
131
		/* save the info of the first frame */
132
		if( f == 0 ) {
133
			width = w;
134
			height = h;
135
			bit_depth = bd;
136
			color_type = clrt;
137
			interlace_type = it;
138
			compression_type = ct;
139
			filter_type = ft;
140
			}
141
		/* compare all other frames to first frame */
142
		else if( (w != width) ||
143
				(h != height) ||
144
				(bd != bit_depth) ||
145
				(clrt != color_type) ||
146
				(it != interlace_type) ||
147
				(ct != compression_type) ||
148
				(ft != filter_type) ) {
149
			if( w != width ) printf( "width is different\n" );
150
			if( h != height ) printf( "height  is different\n" );
151
			if( bd != bit_depth ) printf( "bit depth is different\n" );
152
			if( clrt != color_type ) printf( "color type is different\n" );
153
			if( it != interlace_type ) printf( "interlace type is different\n" );
154
			if( ct != compression_type ) printf( "compression type is different\n" );
155
			if( ft != filter_type ) printf( "filter type is different\n" );
156
			return 1;
157
			}
158
		}
159
 
160
	row_buf = (png_bytep)NULL;
161
 
162
	/* open output file */
163
	printf( "opening file \"%s\"\n", argv[numfiles + 2] );
164
	fpout = fopen( argv[numfiles + 2], "wb" );
165
	if( fpout == NULL ) {
166
		printf( "fopen() failed\n" );
167
		return 1;
168
		}
169
 
170
	/* allocate write structure */
171
	write_ptr = png_create_write_struct( PNG_LIBPNG_VER_STRING, (png_voidp)NULL, (png_error_ptr)NULL, (png_error_ptr)NULL );
172
 
173
	/* allocate info structures */
174
	write_info_ptr = png_create_info_struct( write_ptr );
175
	end_info_ptr = png_create_info_struct( write_ptr );
176
 
177
	/* error handling */
178
	if( setjmp( write_ptr->jmpbuf ) ) {
179
		printf( "libpng write error\n" );
180
		return 1;
181
		}
182
 
183
	/* initialize output stream */
184
	png_init_io( write_ptr, fpout );
185
	png_set_write_status_fn( write_ptr, NULL );
186
 
187
	/* set info */
188
	png_set_IHDR( write_ptr, write_info_ptr, width * numfiles, height, bit_depth, color_type, PNG_INTERLACE_NONE, compression_type, filter_type);
189
 
190
	/* image characteristics */
191
	{
192
		png_color_16p background;
193
		double white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y;
194
		double gamma;
195
		int intent;
196
		png_uint_16p hist;
197
		png_uint_32 offset_x, offset_y;
198
		int unit_type;
199
		png_charp purpose, units;
200
		png_charpp params;
201
		png_int_32 X0, X1;
202
		int type, nparams;
203
		png_uint_32 res_x, res_y;
204
		png_colorp palette;
205
		int num_palette;
206
		png_color_8p sig_bit;
207
		png_bytep trans;
208
		int num_trans;
209
		png_color_16p trans_values;
210
 
211
		/* background color */
212
		if( png_get_bKGD( input[0].read_ptr, input[0].read_info_ptr, &background ) ) {
213
			png_set_bKGD( write_ptr, write_info_ptr, background );
214
			}
215
 
216
		if( png_get_cHRM( input[0].read_ptr, input[0].read_info_ptr, &white_x, &white_y, &red_x, &red_y, &green_x, &green_y, &blue_x, &blue_y ) ) {
217
			png_set_cHRM( write_ptr, write_info_ptr, white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y );
218
			}
219
 
220
		/* gamma */
221
		if( png_get_gAMA( input[0].read_ptr, input[0].read_info_ptr, &gamma ) ) {
222
			png_set_gAMA( write_ptr, write_info_ptr, gamma );
223
			}
224
 
225
		/* rendering intent */
226
		if( png_get_sRGB( input[0].read_ptr, input[0].read_info_ptr, &intent ) ) {
227
			png_set_sRGB( write_ptr, write_info_ptr, intent );
228
			}
229
 
230
		/* Histogram */
231
		if( png_get_hIST( input[0].read_ptr, input[0].read_info_ptr, &hist ) ) {
232
			png_set_hIST( write_ptr, write_info_ptr, hist );
233
			}
234
 
235
		/* offsets */
236
		if( png_get_oFFs( input[0].read_ptr, input[0].read_info_ptr, &offset_x, &offset_y, &unit_type ) ) {
237
			png_set_oFFs( write_ptr, write_info_ptr, offset_x, offset_y, unit_type );
238
			}
239
 
240
		if( png_get_pCAL( input[0].read_ptr, input[0].read_info_ptr, &purpose, &X0, &X1, &type, &nparams, &units, ¶ms ) ) {
241
			png_set_pCAL( write_ptr, write_info_ptr, purpose, X0, X1, type, nparams, units, params );
242
			}
243
 
244
		/* pixel density */
245
		if( png_get_pHYs( input[0].read_ptr, input[0].read_info_ptr, &res_x, &res_y, &unit_type ) ) {
246
			png_set_pHYs( write_ptr, write_info_ptr, res_x, res_y, unit_type );
247
			}
248
 
249
		/* text chunks */
250
/*		if( png_get_text( input[0].read_ptr, input[0].read_info_ptr, &text_ptr, &num_text ) > 0 ) {
251
			printf( "Handling %d tEXt/zTXt chunks\n", num_text );
252
			png_set_text( write_ptr, write_info_ptr, text_ptr, num_text );
253
			}
254
*/
255
		/* palette */
256
		if( png_get_PLTE( input[0].read_ptr, input[0].read_info_ptr, &palette, &num_palette ) ) {
257
			png_set_PLTE( write_ptr, write_info_ptr, palette, num_palette );
258
			}
259
 
260
		/* significant bits */
261
		if( png_get_sBIT( input[0].read_ptr, input[0].read_info_ptr, &sig_bit ) ) {
262
			png_set_sBIT( write_ptr, write_info_ptr, sig_bit );
263
			}
264
 
265
		/* transparency */
266
		if( png_get_tRNS( input[0].read_ptr, input[0].read_info_ptr, &trans, &num_trans, &trans_values ) ) {
267
			png_set_tRNS( write_ptr, write_info_ptr, trans, num_trans, trans_values );
268
			}
269
		}
270
 
271
	/* text chunks */
272
	num_text = 0;
273
	if( !png_get_text( input[0].read_ptr, input[0].read_info_ptr, &text_ptr, &num_text ) ) num_text = 0;
274
	new_text_ptr = (struct png_text_struct *)malloc( sizeof( struct png_text_struct ) * num_text + 1 );
275
	if( !new_text_ptr ) {
276
		printf( "malloc() failed\n" );
277
		return 1;
278
		}
279
 
280
	memcpy( new_text_ptr, text_ptr, sizeof( struct png_text_struct ) * num_text );
281
 
282
	snprintf( buf, 255, "SDL_anim %d %d %d", duration, width, numfiles );
283
	buf[255] = 0;
284
	new_text_ptr[num_text].compression = PNG_TEXT_COMPRESSION_NONE;
285
	new_text_ptr[num_text].key = "format";
286
	new_text_ptr[num_text].text = buf;
287
	new_text_ptr[num_text].text_length = strlen( buf );
288
	num_text++;
289
	png_set_text( write_ptr, write_info_ptr, new_text_ptr, num_text );
290
 
291
	/* write info */
292
	png_write_info( write_ptr, write_info_ptr );
293
 
294
	/* allocate buffer */
295
	rowbytes = png_get_rowbytes( input[0].read_ptr, input[0].read_info_ptr );
296
	row_buf = (png_bytep)png_malloc( write_ptr, rowbytes * numfiles );
297
	if( row_buf == NULL ) {
298
		printf( "png_malloc() failed\n" );
299
		return 1;
300
		}
301
 
302
	/* copy raw data */
303
	for( y = 0; y < height; y++ ) {
304
		/* grab a scanline from each file */
305
		here = row_buf;
306
		for( f = 0; f < numfiles; f++ ) {
307
			png_read_rows( input[f].read_ptr, (png_bytepp)&here, (png_bytepp)NULL, 1 );
308
			here += rowbytes;
309
			}
310
		/* write the long scanline */
311
		png_write_rows( write_ptr, (png_bytepp)&row_buf, 1 );
312
		}
313
 
314
	/* end io */
315
	for( f = 0; f < numfiles; f++ ) png_read_end( input[f].read_ptr, end_info_ptr );
316
	png_write_end( write_ptr, end_info_ptr );
317
 
318
	/* cleanup */
319
	png_free( write_ptr, row_buf );
320
	for( f = 0; f < numfiles; f++ ) {
321
		png_destroy_read_struct( &input[f].read_ptr, &input[f].read_info_ptr, &end_info_ptr);
322
		fclose( input[f].file );
323
		}
324
	png_destroy_write_struct( &write_ptr, &write_info_ptr );
325
	fclose( fpout );
326
 
327
	return 0;
328
	}