2
Copyright (C) 1997-2007 ZSNES Team ( zsKnight, _Demo_, pagefault, Nach )
5
http://sourceforge.net/projects/zsnes
6
https://zsnes.bountysource.com
8
This program is free software; you can redistribute it and/or
9
modify it under the terms of the GNU General Public License
10
version 2 as published by the Free Software Foundation.
12
This program is distributed in the hope that it will be useful,
13
but WITHOUT ANY WARRANTY; without even the implied warranty of
14
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
GNU General Public License for more details.
17
You should have received a copy of the GNU General Public License
18
along with this program; if not, write to the Free Software
19
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27
#include "../gblhdr.h"
15
#include <sys/types.h>
22
#include "../gblhdr.h"
25
extern unsigned int vidbuffer;
29
int Png_Dump(const char * filename, unsigned short width, unsigned short height, unsigned char * image_data, bool usebgr)
33
png_bytep * row_pointers;
34
/*Set scanline width for 32-bit color data*/
39
/*Try to open the file.*/
40
FILE *fp = fopen(filename, "wb");
49
/*Try to create png write struct, fail if we cannot.*/
50
png_ptr = png_create_write_struct
51
(PNG_LIBPNG_VER_STRING, NULL,/*(png_voidp)user_error_ptr,
52
user_error_fn*/NULL, NULL/*user_warning_fn*/);
56
/*set png I/O source.*/
57
png_init_io(png_ptr, fp);
59
/* set the zlib compression level */
60
png_set_compression_level(png_ptr,
63
/* set other zlib parameters */
64
png_set_compression_mem_level(png_ptr, 8);
65
png_set_compression_strategy(png_ptr,
67
png_set_compression_window_bits(png_ptr, 15);
68
png_set_compression_method(png_ptr, 8);
69
png_set_compression_buffer_size(png_ptr, 8192);
71
/*try to create info struct. Fail and delete existing structs if info struct cannot be created.*/
72
info_ptr = png_create_info_struct(png_ptr);
75
png_destroy_write_struct(&png_ptr,
81
/*set a lot of image info (code adapted from libpng documentation!)*/
82
png_set_IHDR(png_ptr, info_ptr, width, height,
83
8, PNG_COLOR_TYPE_RGB_ALPHA, PNG_INTERLACE_NONE,
84
PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
86
info_ptr->color_type=PNG_COLOR_TYPE_RGB_ALPHA;
88
/*Allocate an array of scanline pointers*/
89
row_pointers=(png_bytep*)malloc(height*sizeof(png_bytep));
90
for (i=0;i<height;i++)
92
#ifdef __UPSIDE_DOWN__
93
/*invert to normal image format.*/
94
row_pointers[i]=&image_data[scanline*(height-i-1)];
96
row_pointers[i]=&image_data[scanline*i];
100
/*tell the png library what to encode.*/
101
png_set_rows(png_ptr, info_ptr, row_pointers);
104
png_transforms|=PNG_TRANSFORM_BGR;
105
/*Write image to file*/
106
png_write_png(png_ptr, info_ptr, png_transforms, NULL);
111
/*Destroy PNG structs*/
112
png_destroy_write_struct(&png_ptr, &info_ptr);
114
/*clean up dynamically allocated RAM.*/
118
_CrtDumpMemoryLeaks();
123
char *generate_filename(void)
133
filename = (char *)malloc(14);
137
sprintf(filename, "Image%03d.png", i);
138
else sprintf(filename, "Imag%04d.png", i);
139
if(stat(filename, &buf)==-1)
145
tmp++; // the first char is the string length
146
// removes the path if there is one
147
while (*tmp!=0) tmp++;
148
while ((*tmp!='/') && (tmp!=&fnames)) tmp--;
150
// allocates enough memory to store the filename
151
filename = (char *)malloc(strlen(tmp)+10);
152
strcpy(filename, tmp);
154
tmp = filename+strlen(filename);
155
while (*tmp!='.') tmp--;
160
if (*tmp2 == ' ') *tmp2 = '_';
165
/*find first unused file*/
167
/*Note: this results in a 9999 image limit!*/
172
sprintf(tmp, "_%04d.png", i);
174
sprintf(tmp, " %04d.png", i);
176
if(stat(filename, &buf)==-1)
183
#define SNAP_HEIGHT 223
184
void Grab_PNG_Data(void)
187
bool is_bgr_data=true;
189
/*These are the variables used to perform the 32-bit conversion*/
191
unsigned short* pixel;
192
unsigned short conv_pixel;
193
/*Set scanline width for 32-bit color data: 4*256 = 1024*/
195
unsigned char *DIBits;
196
unsigned int * DBits;
198
filename = generate_filename();
200
/*Allocate image buffer for DIB data*/
201
DIBits=(unsigned char*)malloc(scanline*SNAP_HEIGHT);
203
/*Cast pointer to 32-bit data type*/
204
DBits=(unsigned int*) DIBits;
206
/*Use zsKnight's 16 to 32 bit color conversion*/
207
pixel=(unsigned short*)(vidbuffer);
208
for(i=0;i<SNAP_HEIGHT;i++)
213
conv_pixel=pixel[(i*288)+j+16];
214
DBits[i*256+j]=((conv_pixel&0xF800)<<8)|
215
((conv_pixel&0x07E0)<<5)|
216
((conv_pixel&0x001F)<<3)|0xFF000000;
220
/*compress and write the PNG*/
221
Png_Dump(filename, 256, SNAP_HEIGHT, DIBits, is_bgr_data);
227
_CrtDumpMemoryLeaks();
41
#include "../numconv.h"
44
#define MAX_PNGNAME_LEN 13
46
#define MAX_PNGNAME_LEN (strlen(ZSaveName)+11) //11 = _12345.png\0
49
char *generate_image_filename(const char *image_suffix)
51
char *filename = (char *)malloc(MAX_PNGNAME_LEN);
57
strcpy(filename, "img");
60
strcpy(filename, ZSaveName);
61
p = strrchr(filename, '.');
62
if (!p) { p = filename+strlen(filename); }
65
for (i = 0; i < 100000; i++)
67
sprintf(p, "%05d.%s", i, image_suffix);
68
if (access_dir(ZSnapPath, filename, F_OK))
82
extern unsigned short *vidbuffer;
83
extern unsigned short resolutn;
85
#define SNAP_HEIGHT resolutn
86
#define SNAP_WIDTH 256
87
#define PIXEL (vidbuffer[((y+1)*288) + x + 16])
92
int Png_Dump(const char *filename, unsigned short width, unsigned short height, unsigned char *image_data, bool usebgr)
94
FILE *fp = fopen_dir(ZSnapPath, filename, "wb");
97
//Try to create png write struct, fail if we cannot.
98
png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
103
//set png I/O source.
104
png_init_io(png_ptr, fp);
106
//set the zlib compression level
107
png_set_compression_level(png_ptr, Z_BEST_COMPRESSION);
109
//set other zlib parameters
110
png_set_compression_mem_level(png_ptr, 8);
111
png_set_compression_strategy(png_ptr, Z_DEFAULT_STRATEGY);
112
png_set_compression_window_bits(png_ptr, 15);
113
png_set_compression_method(png_ptr, 8);
114
png_set_compression_buffer_size(png_ptr, 8192);
116
//try to create info struct. Fail and delete existing structs if info struct cannot be created.
117
info_ptr = png_create_info_struct(png_ptr);
120
png_bytep *row_pointers;
122
//Set scanline width for 32-bit color data
123
unsigned int scanline = width*PIXEL_SIZE;
124
int png_transforms = 0;
128
//set a lot of image info (code adapted from libpng documentation!)
129
png_set_IHDR(png_ptr, info_ptr, width, height, 8,
130
PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE,
131
PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
132
info_ptr->color_type = PNG_COLOR_TYPE_RGB;
134
//Allocate an array of scanline pointers
135
row_pointers = (png_bytep*)malloc(height*sizeof(png_bytep));
136
for (i = 0; i < height; i++)
138
#ifdef __UPSIDE_DOWN__
139
//invert to normal image format.
140
row_pointers[i] = image_data + scanline*(height-i-1);
142
row_pointers[i] = image_data + scanline*i;
146
//tell the png library what to encode.
147
png_set_rows(png_ptr, info_ptr, row_pointers);
149
if (usebgr) { png_transforms|=PNG_TRANSFORM_BGR; }
150
//Write image to file
151
png_write_png(png_ptr, info_ptr, png_transforms, NULL);
154
//Destroy PNG structs
155
png_destroy_write_struct(&png_ptr, &info_ptr);
157
//clean up dynamically allocated RAM.
162
png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
171
char *filename = generate_image_filename("png");
174
unsigned char *DBits = (unsigned char *)malloc(SNAP_HEIGHT*SNAP_WIDTH*PIXEL_SIZE);
177
//These are the variables used to perform the 24-bit conversion
178
unsigned int y = SNAP_HEIGHT, x;
179
// We can fill the array in any order, so might as well optimize loops
182
for (x=SNAP_WIDTH ; x-- ;)
184
DBits[PIXEL_SIZE*(y*SNAP_WIDTH+x)] = (PIXEL&0xF800) >> 8;
185
DBits[PIXEL_SIZE*(y*SNAP_WIDTH+x)+1] = (PIXEL&0x07E0) >> 3;
186
DBits[PIXEL_SIZE*(y*SNAP_WIDTH+x)+2] = (PIXEL&0x001F) << 3;
189
//compress and write the PNG
190
Png_Dump(filename, SNAP_WIDTH, SNAP_HEIGHT, DBits, false);
201
char *filename = generate_image_filename("bmp");
204
FILE *fp = fopen_dir(ZSnapPath, filename, "wb");
207
const unsigned int header_size = 26;
208
const unsigned short width = SNAP_WIDTH;
209
const unsigned short height = SNAP_HEIGHT;
210
unsigned short y = height, x;
212
fputs("BM", fp); //Header
213
fwrite4(width*height*3+header_size, fp); //File size
214
fwrite4(0, fp); //Reserved
215
fwrite4(header_size, fp); //Offset to bitmap
216
fwrite4(12, fp); //Length of color explain field;
217
fwrite2(width, fp); //Width
218
fwrite2(height, fp); //Height
219
fwrite2(1, fp); //Planes
220
fwrite2(24, fp); //Bits per pixel
222
while (y--) //Have to write image upside down
224
for (x = 0; x < width; x++)
226
fwrite3(((PIXEL&0xF800) << 8) | ((PIXEL&0x07E0) << 5) | ((PIXEL&0x001F) << 3), fp);
235
void Grab_BMP_Data_8()
237
char *filename = generate_image_filename("bmp");
240
FILE *fp = fopen_dir(ZSnapPath, filename, "wb");
243
const unsigned int colors = 256;
244
const unsigned int palette_size = colors*4;
245
const unsigned int header_size = palette_size+54;
246
const unsigned short width = SNAP_WIDTH;
247
const unsigned short height = SNAP_HEIGHT;
250
fputs("BM", fp); //Header
251
fwrite4(width*height+header_size, fp); //File size
252
fwrite4(0, fp); //Reserved
253
fwrite4(header_size, fp); //Offset to bitmap
254
fwrite4(40, fp); //Length of color explain field;
255
fwrite4(width, fp); //Width
256
fwrite4(height, fp); //Height
257
fwrite2(1, fp); //Planes
258
fwrite2(8, fp); //Bits per pixel
259
fwrite4(0, fp); //Compression Format
260
fwrite4(width*height, fp); //Bitmap data size
261
fwrite4(0, fp); //H-Res?
262
fwrite4(0, fp); //V-Res?
263
fwrite4(colors, fp); //Colors
264
fwrite4(colors, fp); //Important Colors
266
for (y = 0; y < colors; y++) //Write palette
268
unsigned char byte = 0;
269
fwrite((unsigned char *)vidbuffer+100000+y*3+3, 1, 1, fp);
270
fwrite((unsigned char *)vidbuffer+100000+y*3+2, 1, 1, fp);
271
fwrite((unsigned char *)vidbuffer+100000+y*3+1, 1, 1, fp);
272
fwrite(&byte, 1, 1, fp);
275
for (y = height; y-- ;) //Have to write image upside down
277
for (x = 0; x < width; x++)
279
fwrite((unsigned char *)vidbuffer+(y+1)*288+x+16, 1, 1, fp);