00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #include <cstdlib>
00034
00035 #include "png.h"
00036 #include "writepng.h"
00037
00038 using namespace std;
00039
00040
00041
00042 static void writepng_error_handler(png_structp png_ptr, png_const_charp msg);
00043
00044
00045
00046 void writepng_version_info(void)
00047 {
00048 fprintf(stderr, " Compiled with libpng %s; using libpng %s.\n",
00049 PNG_LIBPNG_VER_STRING, png_libpng_ver);
00050 fprintf(stderr, " Compiled with zlib %s; using zlib %s.\n",
00051 ZLIB_VERSION, zlib_version);
00052 }
00053
00054
00055
00056
00057
00058
00059
00060 int writepng_init(mainprog_info *mainprog_ptr)
00061 {
00062 png_structp png_ptr;
00063 png_infop info_ptr;
00064 int color_type, interlace_type;
00065
00066
00067
00068
00069 png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, mainprog_ptr,
00070 writepng_error_handler, NULL);
00071 if (!png_ptr)
00072 return 4;
00073
00074 info_ptr = png_create_info_struct(png_ptr);
00075 if (!info_ptr) {
00076 png_destroy_write_struct(&png_ptr, NULL);
00077 return 4;
00078 }
00079
00080
00081
00082
00083
00084
00085
00086 if (setjmp(mainprog_ptr->jmpbuf)) {
00087 png_destroy_write_struct(&png_ptr, &info_ptr);
00088 return 2;
00089 }
00090
00091
00092
00093
00094 png_init_io(png_ptr, mainprog_ptr->outfile);
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104 png_set_compression_level(png_ptr, Z_BEST_COMPRESSION);
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117 if (mainprog_ptr->pnmtype == 5)
00118 color_type = PNG_COLOR_TYPE_GRAY;
00119 else if (mainprog_ptr->pnmtype == 6)
00120 color_type = PNG_COLOR_TYPE_RGB;
00121 else if (mainprog_ptr->pnmtype == 8)
00122 color_type = PNG_COLOR_TYPE_RGB_ALPHA;
00123 else {
00124 png_destroy_write_struct(&png_ptr, &info_ptr);
00125 return 11;
00126 }
00127
00128 interlace_type = mainprog_ptr->interlaced? PNG_INTERLACE_ADAM7 :
00129 PNG_INTERLACE_NONE;
00130
00131 png_set_IHDR(png_ptr, info_ptr, mainprog_ptr->width, mainprog_ptr->height,
00132 mainprog_ptr->sample_depth, color_type, interlace_type,
00133 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
00134
00135 if (mainprog_ptr->gamma > 0.0)
00136 png_set_gAMA(png_ptr, info_ptr, mainprog_ptr->gamma);
00137
00138 if (mainprog_ptr->have_bg) {
00139 png_color_16 background;
00140
00141 background.red = mainprog_ptr->bg_red;
00142 background.green = mainprog_ptr->bg_green;
00143 background.blue = mainprog_ptr->bg_blue;
00144 png_set_bKGD(png_ptr, info_ptr, &background);
00145 }
00146
00147 if (mainprog_ptr->have_time) {
00148 png_time modtime;
00149
00150 png_convert_from_time_t(&modtime, mainprog_ptr->modtime);
00151 png_set_tIME(png_ptr, info_ptr, &modtime);
00152 }
00153
00154 if (mainprog_ptr->have_text) {
00155 png_text text[6];
00156 int num_text = 0;
00157
00158 if (mainprog_ptr->have_text & TEXT_TITLE) {
00159 text[num_text].compression = PNG_TEXT_COMPRESSION_NONE;
00160 text[num_text].key = "Title";
00161 text[num_text].text = mainprog_ptr->title;
00162 ++num_text;
00163 }
00164 if (mainprog_ptr->have_text & TEXT_AUTHOR) {
00165 text[num_text].compression = PNG_TEXT_COMPRESSION_NONE;
00166 text[num_text].key = "Author";
00167 text[num_text].text = mainprog_ptr->author;
00168 ++num_text;
00169 }
00170 if (mainprog_ptr->have_text & TEXT_DESC) {
00171 text[num_text].compression = PNG_TEXT_COMPRESSION_NONE;
00172 text[num_text].key = "Description";
00173 text[num_text].text = mainprog_ptr->desc;
00174 ++num_text;
00175 }
00176 if (mainprog_ptr->have_text & TEXT_COPY) {
00177 text[num_text].compression = PNG_TEXT_COMPRESSION_NONE;
00178 text[num_text].key = "Copyright";
00179 text[num_text].text = mainprog_ptr->copyright;
00180 ++num_text;
00181 }
00182 if (mainprog_ptr->have_text & TEXT_EMAIL) {
00183 text[num_text].compression = PNG_TEXT_COMPRESSION_NONE;
00184 text[num_text].key = "E-mail";
00185 text[num_text].text = mainprog_ptr->email;
00186 ++num_text;
00187 }
00188 if (mainprog_ptr->have_text & TEXT_URL) {
00189 text[num_text].compression = PNG_TEXT_COMPRESSION_NONE;
00190 text[num_text].key = "URL";
00191 text[num_text].text = mainprog_ptr->url;
00192 ++num_text;
00193 }
00194 png_set_text(png_ptr, info_ptr, text, num_text);
00195 }
00196
00197
00198
00199
00200 png_write_info(png_ptr, info_ptr);
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213 png_set_packing(png_ptr);
00214
00215
00216
00217
00218
00219 mainprog_ptr->png_ptr = png_ptr;
00220 mainprog_ptr->info_ptr = info_ptr;
00221
00222
00223
00224
00225 return 0;
00226 }
00227
00228
00229
00230
00231
00232
00233
00234 int writepng_encode_image(mainprog_info *mainprog_ptr)
00235 {
00236 png_structp png_ptr = (png_structp)mainprog_ptr->png_ptr;
00237 png_infop info_ptr = (png_infop)mainprog_ptr->info_ptr;
00238
00239
00240
00241
00242
00243 if (setjmp(mainprog_ptr->jmpbuf)) {
00244 png_destroy_write_struct(&png_ptr, &info_ptr);
00245 mainprog_ptr->png_ptr = NULL;
00246 mainprog_ptr->info_ptr = NULL;
00247 return 2;
00248 }
00249
00250
00251
00252
00253
00254 png_write_image(png_ptr, mainprog_ptr->row_pointers);
00255
00256
00257
00258
00259
00260
00261 png_write_end(png_ptr, NULL);
00262
00263 return 0;
00264 }
00265
00266
00267
00268
00269
00270
00271
00272 int writepng_encode_row(mainprog_info *mainprog_ptr)
00273 {
00274 png_structp png_ptr = (png_structp)mainprog_ptr->png_ptr;
00275 png_infop info_ptr = (png_infop)mainprog_ptr->info_ptr;
00276
00277
00278
00279
00280
00281 if (setjmp(mainprog_ptr->jmpbuf)) {
00282 png_destroy_write_struct(&png_ptr, &info_ptr);
00283 mainprog_ptr->png_ptr = NULL;
00284 mainprog_ptr->info_ptr = NULL;
00285 return 2;
00286 }
00287
00288
00289
00290
00291 png_write_row(png_ptr, mainprog_ptr->image_data);
00292
00293 return 0;
00294 }
00295
00296
00297
00298
00299
00300
00301
00302 int writepng_encode_finish(mainprog_info *mainprog_ptr)
00303 {
00304 png_structp png_ptr = (png_structp)mainprog_ptr->png_ptr;
00305 png_infop info_ptr = (png_infop)mainprog_ptr->info_ptr;
00306
00307
00308
00309
00310
00311 if (setjmp(mainprog_ptr->jmpbuf)) {
00312 png_destroy_write_struct(&png_ptr, &info_ptr);
00313 mainprog_ptr->png_ptr = NULL;
00314 mainprog_ptr->info_ptr = NULL;
00315 return 2;
00316 }
00317
00318
00319
00320
00321
00322 png_write_end(png_ptr, NULL);
00323
00324 return 0;
00325 }
00326
00327
00328
00329
00330
00331 void writepng_cleanup(mainprog_info *mainprog_ptr)
00332 {
00333 png_structp png_ptr = (png_structp)mainprog_ptr->png_ptr;
00334 png_infop info_ptr = (png_infop)mainprog_ptr->info_ptr;
00335
00336 if (png_ptr && info_ptr)
00337 png_destroy_write_struct(&png_ptr, &info_ptr);
00338 }
00339
00340
00341
00342
00343
00344 static void writepng_error_handler(png_structp png_ptr, png_const_charp msg)
00345 {
00346 mainprog_info *mainprog_ptr;
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357 fprintf(stderr, "writepng libpng error: %s\n", msg);
00358 fflush(stderr);
00359
00360 mainprog_ptr = (mainprog_info*) png_get_error_ptr(png_ptr);
00361 if (mainprog_ptr == NULL) {
00362 fprintf(stderr,
00363 "writepng severe error: jmpbuf not recoverable; terminating.\n");
00364 fflush(stderr);
00365 exit(99);
00366 }
00367
00368 longjmp(mainprog_ptr->jmpbuf, 1);
00369 }