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