Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
716 | lvd | 1 | #include "std.h" |
2 | |||
3 | #include "emul.h" |
||
4 | #include "vars.h" |
||
5 | #include "sshot_png.h" |
||
6 | |||
7 | typedef void (PNGAPI *png_write_end_ptr) PNGARG((png_structp png_ptr, |
||
8 | png_infop info_ptr)); |
||
9 | typedef void (PNGAPI *png_write_image_ptr) PNGARG((png_structp png_ptr, |
||
10 | png_bytepp image)); |
||
11 | typedef void (PNGAPI *png_set_bgr_ptr) PNGARG((png_structp png_ptr)); |
||
12 | typedef void (PNGAPI *png_write_info_ptr) PNGARG((png_structp png_ptr, |
||
13 | png_infop info_ptr)); |
||
14 | typedef void (PNGAPI *png_set_IHDR_ptr) PNGARG((png_structp png_ptr, |
||
15 | png_infop info_ptr, png_uint_32 width, png_uint_32 height, int bit_depth, |
||
16 | int color_type, int interlace_method, int compression_method, |
||
17 | int filter_method)); |
||
18 | typedef void (PNGAPI *png_set_write_fn_ptr) PNGARG((png_structp png_ptr, |
||
19 | png_voidp io_ptr, png_rw_ptr write_data_fn, png_flush_ptr output_flush_fn)); |
||
20 | typedef void (PNGAPI *png_destroy_write_struct_ptr) |
||
21 | PNGARG((png_structpp png_ptr_ptr, png_infopp info_ptr_ptr)); |
||
22 | typedef png_infop (PNGAPI *png_create_info_struct_ptr) |
||
23 | PNGARG((png_structp png_ptr)); |
||
24 | typedef void (PNGAPI *png_set_compression_level_ptr) PNGARG((png_structp png_ptr, |
||
25 | int level)); |
||
26 | typedef png_structp (PNGAPI *png_create_write_struct_ptr) |
||
27 | PNGARG((png_const_charp user_png_ver, png_voidp error_ptr, |
||
28 | png_error_ptr error_fn, png_error_ptr warn_fn)); |
||
29 | typedef void (PNGAPI *png_set_filter_ptr) PNGARG((png_structp png_ptr, int method, |
||
30 | int filters)); |
||
31 | |||
32 | png_error_ptr png_error_p = 0; |
||
33 | png_write_end_ptr png_write_end_p = 0; |
||
34 | png_write_image_ptr png_write_image_p = 0; |
||
35 | png_set_bgr_ptr png_set_bgr_p = 0; |
||
36 | png_write_info_ptr png_write_info_p = 0; |
||
37 | png_set_IHDR_ptr png_set_IHDR_p = 0; |
||
38 | png_set_write_fn_ptr png_set_write_fn_p = 0; |
||
39 | png_destroy_write_struct_ptr png_destroy_write_struct_p = 0; |
||
40 | png_create_info_struct_ptr png_create_info_struct_p = 0; |
||
41 | png_set_compression_level_ptr png_set_compression_level_p = 0; |
||
42 | png_create_write_struct_ptr png_create_write_struct_p = 0; |
||
43 | png_set_filter_ptr png_set_filter_p = 0; |
||
44 | |||
45 | static HMODULE PngDll = 0; |
||
46 | bool PngInit() |
||
47 | { |
||
48 | PngDll = LoadLibrary("libpng12.dll"); |
||
49 | if(!PngDll) |
||
50 | return false; |
||
51 | png_error_p = (png_error_ptr)GetProcAddress(PngDll, "png_error"); |
||
52 | if(!png_error_p) |
||
53 | return false; |
||
54 | png_write_end_p = (png_write_end_ptr)GetProcAddress(PngDll, "png_write_end"); |
||
55 | if(!png_write_end_p) |
||
56 | return false; |
||
57 | png_write_image_p = (png_write_image_ptr)GetProcAddress(PngDll, "png_write_image"); |
||
58 | if(!png_write_image_p) |
||
59 | return false; |
||
60 | png_set_bgr_p = (png_set_bgr_ptr)GetProcAddress(PngDll, "png_set_bgr"); |
||
61 | if(!png_set_bgr_p) |
||
62 | return false; |
||
63 | png_write_info_p = (png_write_info_ptr)GetProcAddress(PngDll, "png_write_info"); |
||
64 | if(!png_write_info_p) |
||
65 | return false; |
||
66 | png_set_IHDR_p = (png_set_IHDR_ptr)GetProcAddress(PngDll, "png_set_IHDR"); |
||
67 | if(!png_set_IHDR_p) |
||
68 | return false; |
||
69 | png_set_write_fn_p = (png_set_write_fn_ptr)GetProcAddress(PngDll, "png_set_write_fn"); |
||
70 | if(!png_set_write_fn_p) |
||
71 | return false; |
||
72 | png_destroy_write_struct_p = (png_destroy_write_struct_ptr)GetProcAddress(PngDll, "png_destroy_write_struct"); |
||
73 | if(!png_destroy_write_struct_p) |
||
74 | return false; |
||
75 | png_create_info_struct_p = (png_create_info_struct_ptr)GetProcAddress(PngDll, "png_create_info_struct"); |
||
76 | if(!png_create_info_struct_p) |
||
77 | return false; |
||
78 | png_set_compression_level_p = (png_set_compression_level_ptr)GetProcAddress(PngDll, "png_set_compression_level"); |
||
79 | if(!png_set_compression_level_p) |
||
80 | return false; |
||
81 | png_create_write_struct_p = (png_create_write_struct_ptr)GetProcAddress(PngDll, "png_create_write_struct"); |
||
82 | if(!png_create_write_struct_p) |
||
83 | return false; |
||
84 | png_set_filter_p = (png_set_filter_ptr)GetProcAddress(PngDll, "png_set_filter"); |
||
85 | if(!png_set_filter_p) |
||
86 | return false; |
||
87 | return true; |
||
88 | } |
||
89 | |||
90 | void PngDone() |
||
91 | { |
||
92 | if(PngDll) |
||
93 | FreeLibrary(PngDll); |
||
94 | } |
||
95 | |||
96 | static png_structp png_ptr = NULL; |
||
97 | static png_infop info_ptr = NULL; |
||
98 | |||
99 | static void |
||
100 | PNGAPI |
||
101 | png_write_data(png_structp png_ptr, png_bytep data, png_size_t length) |
||
102 | { |
||
103 | png_uint_32 check; |
||
104 | |||
105 | check = fwrite(data, 1, length, (FILE *)(png_ptr->io_ptr)); |
||
106 | if (check != length) |
||
107 | { |
||
108 | png_error_p(png_ptr, "Write Error"); |
||
109 | } |
||
110 | } |
||
111 | |||
112 | static void |
||
113 | PNGAPI |
||
114 | png_flush(png_structp png_ptr) |
||
115 | { |
||
116 | FILE *io_ptr; |
||
117 | io_ptr = (FILE *)CVT_PTR((png_ptr->io_ptr)); |
||
118 | if (io_ptr != NULL) |
||
119 | fflush(io_ptr); |
||
120 | } |
||
121 | |||
122 | BOOL PngSaveImage (FILE *pfFile, png_byte *pDiData, |
||
123 | int iWidth, int iHeight, png_color bkgColor) |
||
124 | { |
||
125 | const int ciBitDepth = 8; |
||
126 | const int ciChannels = 3; |
||
127 | |||
128 | png_uint_32 ulRowBytes; |
||
129 | static png_byte **ppbRowPointers = NULL; |
||
130 | int i; |
||
131 | |||
132 | // prepare the standard PNG structures |
||
133 | png_ptr = png_create_write_struct_p(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); |
||
134 | if (!png_ptr) |
||
135 | { |
||
136 | return FALSE; |
||
137 | } |
||
138 | |||
139 | png_set_filter_p(png_ptr, 0, PNG_NO_FILTERS); |
||
140 | |||
141 | png_set_compression_level_p(png_ptr, 4/*Z_BEST_COMPRESSION*/); |
||
142 | |||
143 | info_ptr = png_create_info_struct_p(png_ptr); |
||
144 | if (!info_ptr) |
||
145 | { |
||
146 | png_destroy_write_struct_p(&png_ptr, (png_infopp) NULL); |
||
147 | return FALSE; |
||
148 | } |
||
149 | |||
150 | // initialize the png structure |
||
151 | png_set_write_fn_p(png_ptr, (png_voidp)pfFile, png_write_data, png_flush); |
||
152 | |||
153 | // we're going to write a very simple 3x8 bit RGB image |
||
154 | png_set_IHDR_p(png_ptr, info_ptr, iWidth, iHeight, ciBitDepth, |
||
155 | PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, |
||
156 | PNG_FILTER_TYPE_BASE); |
||
157 | |||
158 | // write the file header information |
||
159 | png_write_info_p(png_ptr, info_ptr); |
||
160 | |||
161 | // swap the BGR pixels in the DiData structure to RGB |
||
162 | png_set_bgr_p(png_ptr); |
||
163 | |||
164 | // row_bytes is the width x number of channels |
||
165 | ulRowBytes = iWidth * ciChannels; |
||
166 | |||
167 | // we can allocate memory for an array of row-pointers |
||
168 | ppbRowPointers = (png_bytepp) malloc(iHeight * sizeof(png_bytep)); |
||
169 | |||
170 | // set the individual row-pointers to point at the correct offsets |
||
171 | for (i = 0; i < iHeight; i++) |
||
172 | ppbRowPointers[i] = pDiData + i * (((ulRowBytes + 3) >> 2) << 2); |
||
173 | |||
174 | // write out the entire image data in one call |
||
175 | png_write_image_p(png_ptr, ppbRowPointers); |
||
176 | |||
177 | // write the additional chunks to the PNG file (not really needed) |
||
178 | png_write_end_p(png_ptr, info_ptr); |
||
179 | |||
180 | // and we're done |
||
181 | free (ppbRowPointers); |
||
182 | ppbRowPointers = NULL; |
||
183 | |||
184 | // clean up after the write, and free any memory allocated |
||
185 | png_destroy_write_struct_p(&png_ptr, (png_infopp) NULL); |
||
186 | |||
187 | return TRUE; |
||
188 | } |