yuezonghe | 824eb0c | 2024-06-27 02:32:26 -0700 | [diff] [blame] | 1 | #include "common.h" |
| 2 | #include "bmphed.h" |
| 3 | |
| 4 | #define PNG2BMP_VERSION "1.62" |
| 5 | #define PNG2BMP_COPYRIGHT "Copyright" |
| 6 | |
| 7 | #define ZLIB_VERSION "1.2.3" |
| 8 | |
| 9 | char outnam[FILENAME_MAX]; |
| 10 | char outdir[FILENAME_MAX]; |
| 11 | int deletesrc = 0; |
| 12 | int copytime = 0; |
| 13 | |
| 14 | #define P2B_ALPHABMP_NONE 0 |
| 15 | #define P2B_ALPHABMP_ARGB 1 |
| 16 | #define P2B_ALPHABMP_BITFIELD 2 |
| 17 | |
| 18 | int alpha_format = P2B_ALPHABMP_NONE; |
| 19 | int expand_trans = 0; |
| 20 | |
| 21 | const char errlogfile[] = "./p2berror.log"; |
| 22 | |
| 23 | |
| 24 | const char wrn_mkdirfail[] = |
| 25 | "WARNING: Can not create directory - %s\n" |
| 26 | "WARNING: Output directory specified by '-%c' will be ignored.\n"; |
| 27 | |
| 28 | const char err_ropenfail[] = "SKIPPED: No such file or directory - %s\n"; |
| 29 | const char err_wopenfail[] = "SKIPPED: Cannot create - %s\n"; |
| 30 | const char err_outofmemory[] = "SKIPPED: Out of memory - %s\n"; |
| 31 | |
| 32 | const char err_writeerr[] = "SKIPPED: Write operation failed - %s\n"; |
| 33 | const char err_not_a_png[] = "SKIPPED: Not a PNG file - %s\n"; |
| 34 | |
| 35 | static BOOL read_png(char *, IMAGE *); |
| 36 | static int skip_macbinary(png_structp); |
| 37 | static void to4bpp(png_structp, png_row_infop, png_bytep); |
| 38 | static BOOL write_bmp(char *, IMAGE *); |
| 39 | static const char *write_rgb_bits(IMAGE *, FILE *); |
| 40 | static void mputdwl(void *, unsigned long); |
| 41 | static void mputwl(void *, unsigned int); |
| 42 | static void usage_exit(char *, int); |
| 43 | |
| 44 | #define ERROR_ABORT(s) do { errmsg = (s); goto error_abort; } while (0) |
| 45 | |
| 46 | static BOOL read_png(char *fn, IMAGE *img) |
| 47 | { |
| 48 | png_structp png_ptr; |
| 49 | png_infop info_ptr, end_info; |
| 50 | png_uint_32 width, height; |
| 51 | int bit_depth, color_type; |
| 52 | int xbit_depth, xcolor_type, xchannels; |
| 53 | const char *errmsg; |
| 54 | FILE *fp; |
| 55 | |
| 56 | imgbuf_init(img); |
| 57 | |
| 58 | if (fn == NULL) { |
| 59 | fn = " (stdin)"; |
| 60 | fp = binary_stdio(fileno(stdin)); |
| 61 | } else { |
| 62 | fp = fopen(fn, "rb"); |
| 63 | } |
| 64 | if (fp == NULL) ERROR_ABORT(err_ropenfail); |
| 65 | |
| 66 | set_status("Reading %.80s", basname(fn)); |
| 67 | |
| 68 | /* ------------------------------------------------------ */ |
| 69 | |
| 70 | png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, fn, |
| 71 | png_my_error, png_my_warning); |
| 72 | if (png_ptr == NULL) { |
| 73 | ERROR_ABORT(err_outofmemory); |
| 74 | } |
| 75 | info_ptr = png_create_info_struct(png_ptr); |
| 76 | end_info = png_create_info_struct(png_ptr); |
| 77 | if (info_ptr == NULL || end_info == NULL) { |
| 78 | png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); |
| 79 | ERROR_ABORT(err_outofmemory); |
| 80 | } |
| 81 | if (setjmp(png_jmpbuf(png_ptr))) { |
| 82 | /* If we get here, we had a problem writing the file */ |
| 83 | png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); |
| 84 | ERROR_ABORT(NULL); |
| 85 | } |
| 86 | png_init_io(png_ptr, fp); |
| 87 | png_set_sig_bytes(png_ptr, skip_macbinary(png_ptr)); |
| 88 | |
| 89 | /* ------------------------------------------------------ */ |
| 90 | |
| 91 | png_read_info(png_ptr, info_ptr); |
| 92 | |
| 93 | png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, |
| 94 | &color_type, NULL, NULL, NULL); |
| 95 | |
| 96 | /* ------------------------------------------------------ */ |
| 97 | |
| 98 | if (color_type & PNG_COLOR_MASK_ALPHA) { |
| 99 | if (alpha_format == P2B_ALPHABMP_NONE) { |
| 100 | png_set_strip_alpha(png_ptr); |
| 101 | color_type &= ~PNG_COLOR_MASK_ALPHA; |
| 102 | } |
| 103 | } else if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) { |
| 104 | if (alpha_format != P2B_ALPHABMP_NONE && expand_trans) { |
| 105 | png_set_tRNS_to_alpha(png_ptr); |
| 106 | color_type |= PNG_COLOR_MASK_ALPHA; |
| 107 | color_type &= ~PNG_COLOR_MASK_PALETTE; |
| 108 | } |
| 109 | } |
| 110 | if (color_type == PNG_COLOR_TYPE_GRAY_ALPHA) { |
| 111 | png_set_gray_to_rgb(png_ptr); |
| 112 | } |
| 113 | if (color_type == PNG_COLOR_TYPE_RGB || |
| 114 | color_type == PNG_COLOR_TYPE_RGB_ALPHA) { |
| 115 | png_set_bgr(png_ptr); |
| 116 | } |
| 117 | if (!(color_type & PNG_COLOR_MASK_ALPHA) && bit_depth == 2) { |
| 118 | png_set_user_transform_info(png_ptr, NULL, 4, 1); |
| 119 | png_set_read_user_transform_fn(png_ptr, to4bpp); |
| 120 | } |
| 121 | if (bit_depth == 16) |
| 122 | png_set_strip_16(png_ptr); |
| 123 | |
| 124 | png_read_update_info(png_ptr, info_ptr); |
| 125 | |
| 126 | /* ------------------------------------------------------ */ |
| 127 | |
| 128 | png_get_IHDR(png_ptr, info_ptr, &width, &height, &xbit_depth, |
| 129 | &xcolor_type, NULL, NULL, NULL); |
| 130 | xchannels = png_get_channels(png_ptr, info_ptr); |
| 131 | |
| 132 | img->width = (LONG)width; |
| 133 | img->height = (LONG)height; |
| 134 | img->pixdepth = (UINT)xbit_depth * xchannels; |
| 135 | img->palnum = (img->pixdepth <= 8) ? (1 << img->pixdepth) : 0; |
| 136 | img->topdown = FALSE; |
| 137 | img->alpha = (xcolor_type & PNG_COLOR_MASK_ALPHA) ? TRUE : FALSE; |
| 138 | |
| 139 | if (!imgbuf_alloc(img)) { |
| 140 | png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); |
| 141 | ERROR_ABORT(err_outofmemory); |
| 142 | } |
| 143 | |
| 144 | if (img->palnum > 0) { |
| 145 | if (xcolor_type == PNG_COLOR_TYPE_PALETTE) { |
| 146 | png_colorp palette; |
| 147 | int num_palette; |
| 148 | png_get_PLTE(png_ptr, info_ptr, &palette, &num_palette); |
| 149 | if (num_palette > (int)img->palnum) num_palette = img->palnum; |
| 150 | memset(img->palette, 0, img->palnum * sizeof(png_color)); |
| 151 | memcpy(img->palette, palette, num_palette * sizeof(png_color)); |
| 152 | } else { |
| 153 | int depth = (bit_depth == 16) ? 8 : bit_depth; |
| 154 | memset(img->palette, 0, img->palnum * sizeof(png_color)); |
| 155 | png_build_grayscale_palette(depth, img->palette); |
| 156 | } |
| 157 | } |
| 158 | |
| 159 | /* ------------------------------------------------------ */ |
| 160 | |
| 161 | png_set_read_status_fn(png_ptr, row_callback); |
| 162 | init_progress_meter(png_ptr, img->width, img->height); |
| 163 | |
| 164 | png_read_image(png_ptr, img->rowptr); |
| 165 | |
| 166 | png_read_end(png_ptr, end_info); |
| 167 | png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); |
| 168 | |
| 169 | /* ------------------------------------------------------ */ |
| 170 | |
| 171 | set_status("Read OK %.80s", basname(fn)); |
| 172 | |
| 173 | if (fp != stdin) fclose(fp); |
| 174 | |
| 175 | return TRUE; |
| 176 | |
| 177 | error_abort: /* error */ |
| 178 | if (errmsg != NULL) xxprintf(errmsg, fn); |
| 179 | if (fp != stdin && fp != NULL) fclose(fp); |
| 180 | imgbuf_free(img); |
| 181 | |
| 182 | return FALSE; |
| 183 | } |
| 184 | |
| 185 | static int skip_macbinary(png_structp png_ptr) |
| 186 | { |
| 187 | enum { PNG_BYTES_TO_CHECK = 8, MACBIN_SIZE = 128 }; |
| 188 | png_byte buf[MACBIN_SIZE]; |
| 189 | png_bytep sig; |
| 190 | png_size_t check; |
| 191 | png_FILE_p fp = (png_FILE_p)png_get_io_ptr(png_ptr); |
| 192 | |
| 193 | check = (png_size_t)fread(buf, 1, PNG_BYTES_TO_CHECK, fp); |
| 194 | if (check != PNG_BYTES_TO_CHECK) png_error(png_ptr, "Read Error"); |
| 195 | |
| 196 | if (png_sig_cmp(buf, 0, PNG_BYTES_TO_CHECK) == 0) |
| 197 | return PNG_BYTES_TO_CHECK; |
| 198 | |
| 199 | check = (png_size_t)fread(buf, 1, MACBIN_SIZE, fp); |
| 200 | if (check != MACBIN_SIZE) png_error(png_ptr, "Read Error"); |
| 201 | |
| 202 | sig = buf + MACBIN_SIZE - PNG_BYTES_TO_CHECK; |
| 203 | if (png_sig_cmp(sig, 0, PNG_BYTES_TO_CHECK) == 0) |
| 204 | return PNG_BYTES_TO_CHECK; |
| 205 | |
| 206 | xxprintf(err_not_a_png, (char *)png_get_error_ptr(png_ptr)); |
| 207 | longjmp(png_jmpbuf(png_ptr), 1); |
| 208 | |
| 209 | return 0; /* to quiet compiler warnings */ |
| 210 | } |
| 211 | |
| 212 | static void to4bpp(png_structp png_ptr, png_row_infop row_info, png_bytep data) |
| 213 | { |
| 214 | static const png_byte pix[] = { |
| 215 | 0x00, 0x01, 0x02, 0x03, 0x10, 0x11, 0x12, 0x13, |
| 216 | 0x20, 0x21, 0x22, 0x23, 0x30, 0x31, 0x32, 0x33, |
| 217 | }; |
| 218 | png_uint_32 rowb; |
| 219 | png_bytep p, q; |
| 220 | png_byte c; |
| 221 | |
| 222 | rowb = (row_info->width + 1) / 2; |
| 223 | q = data + rowb; |
| 224 | p = data + rowb / 2; |
| 225 | |
| 226 | if (rowb % 2 == 1) { |
| 227 | c = *p; |
| 228 | *(--q) = pix[c >> 4]; |
| 229 | } |
| 230 | while (p > data) { |
| 231 | c = *(--p); |
| 232 | *(--q) = pix[c & 0x0F]; |
| 233 | *(--q) = pix[c >> 4]; |
| 234 | } |
| 235 | row_info->bit_depth = 4; |
| 236 | row_info->pixel_depth = 4; |
| 237 | row_info->rowbytes = rowb; |
| 238 | } |
| 239 | |
| 240 | static BOOL write_bmp(char *fn, IMAGE *img) |
| 241 | { |
| 242 | BYTE bfh[FILEHED_SIZE + BMPV4HED_SIZE]; |
| 243 | BYTE *const bih = bfh + FILEHED_SIZE; |
| 244 | BYTE rgbq[RGBQUAD_SIZE]; |
| 245 | BOOL alpha_bitfield; |
| 246 | DWORD bihsize, offbits, filesize; |
| 247 | PALETTE *pal; |
| 248 | const char *errmsg; |
| 249 | FILE *fp; |
| 250 | UINT i; |
| 251 | |
| 252 | if (fn == NULL) { |
| 253 | fn = " (stdout)"; |
| 254 | fp = binary_stdio(fileno(stdout)); |
| 255 | } else { |
| 256 | fp = fopen(fn, "wb"); |
| 257 | } |
| 258 | if (fp == NULL) ERROR_ABORT(err_wopenfail); |
| 259 | |
| 260 | set_status("Writing %.80s", basname(fn)); |
| 261 | |
| 262 | /* ------------------------------------------------------ */ |
| 263 | |
| 264 | alpha_bitfield = (img->alpha && alpha_format == P2B_ALPHABMP_BITFIELD); |
| 265 | bihsize = (alpha_bitfield) ? BMPV4HED_SIZE : INFOHED_SIZE; |
| 266 | offbits = FILEHED_SIZE + bihsize + RGBQUAD_SIZE * img->palnum; |
| 267 | filesize = offbits + img->imgbytes; |
| 268 | |
| 269 | memset(bfh, 0, sizeof(bfh)); |
| 270 | |
| 271 | mputwl( bfh + BFH_WTYPE , BMP_SIGNATURE); |
| 272 | mputdwl(bfh + BFH_DSIZE , filesize); |
| 273 | mputdwl(bfh + BFH_DOFFBITS, offbits); |
| 274 | |
| 275 | mputdwl(bih + BIH_DSIZE , bihsize); |
| 276 | mputdwl(bih + BIH_LWIDTH , (DWORD)img->width); |
| 277 | mputdwl(bih + BIH_LHEIGHT , (DWORD)img->height); |
| 278 | mputwl( bih + BIH_WPLANES , 1); |
| 279 | mputwl( bih + BIH_WBITCOUNT , img->pixdepth); |
| 280 | mputdwl(bih + BIH_DSIZEIMAGE, img->imgbytes); |
| 281 | |
| 282 | if (alpha_bitfield) { |
| 283 | mputdwl(bih + BIH_DCOMPRESSION, BI_BITFIELDS); |
| 284 | mputdwl(bih + B4H_DALPHAMASK, 0xFF000000); |
| 285 | mputdwl(bih + B4H_DREDMASK , 0x00FF0000); |
| 286 | mputdwl(bih + B4H_DGREENMASK, 0x0000FF00); |
| 287 | mputdwl(bih + B4H_DBLUEMASK , 0x000000FF); |
| 288 | } |
| 289 | |
| 290 | if (fwrite(bfh, (FILEHED_SIZE + bihsize), 1, fp) != 1) |
| 291 | ERROR_ABORT(err_writeerr); |
| 292 | |
| 293 | /* ------------------------------------------------------ */ |
| 294 | |
| 295 | memset(rgbq, 0, sizeof(rgbq)); |
| 296 | |
| 297 | for (pal = img->palette, i = img->palnum; i > 0; i--, pal++) { |
| 298 | rgbq[RGBQ_RED] = pal->red; |
| 299 | rgbq[RGBQ_GREEN] = pal->green; |
| 300 | rgbq[RGBQ_BLUE] = pal->blue; |
| 301 | if (fwrite(rgbq, RGBQUAD_SIZE, 1, fp) != 1) |
| 302 | ERROR_ABORT(err_writeerr); |
| 303 | } |
| 304 | |
| 305 | /* ------------------------------------------------------ */ |
| 306 | |
| 307 | if ((errmsg = write_rgb_bits(img, fp)) != NULL) ERROR_ABORT(errmsg); |
| 308 | |
| 309 | /* ------------------------------------------------------ */ |
| 310 | |
| 311 | set_status("OK %.80s", basname(fn)); |
| 312 | feed_line(); |
| 313 | |
| 314 | fflush(fp); |
| 315 | if (fp != stdout) fclose(fp); |
| 316 | imgbuf_free(img); |
| 317 | |
| 318 | return TRUE; |
| 319 | |
| 320 | error_abort: /* error */ |
| 321 | xxprintf(errmsg, fn); |
| 322 | if (fp != stdout && fp != NULL) fclose(fp); |
| 323 | imgbuf_free(img); |
| 324 | |
| 325 | return FALSE; |
| 326 | } |
| 327 | |
| 328 | static const char *write_rgb_bits(IMAGE *img, FILE *fp) |
| 329 | { |
| 330 | DWORD wr = 16*1024*1024; |
| 331 | DWORD num = img->imgbytes; |
| 332 | BYTE *ptr = img->bmpbits; |
| 333 | |
| 334 | while (num > 0) { |
| 335 | if (wr > num) wr = num; |
| 336 | |
| 337 | if (fwrite(ptr, wr, 1, fp) != 1) |
| 338 | return err_writeerr; |
| 339 | |
| 340 | ptr += wr; num -= wr; |
| 341 | } |
| 342 | |
| 343 | return NULL; |
| 344 | } |
| 345 | |
| 346 | static void mputdwl(void *ptr, unsigned long val) |
| 347 | { |
| 348 | unsigned char *p = ptr; |
| 349 | |
| 350 | p[0] = (unsigned char)(val & 0xFF); |
| 351 | p[1] = (unsigned char)(val >> 8 & 0xFF); |
| 352 | p[2] = (unsigned char)(val >> 16 & 0xFF); |
| 353 | p[3] = (unsigned char)(val >> 24 & 0xFF); |
| 354 | } |
| 355 | |
| 356 | static void mputwl(void *ptr, unsigned int val) |
| 357 | { |
| 358 | unsigned char *p = ptr; |
| 359 | |
| 360 | p[0] = (unsigned char)(val & 0xFF); |
| 361 | p[1] = (unsigned char)(val >> 8 & 0xFF); |
| 362 | } |
| 363 | |
| 364 | static void usage_exit(char *argv0, int status) |
| 365 | { |
| 366 | static const char str_usage[] = |
| 367 | "png2bmp\n"; |
| 368 | |
| 369 | fprintf(stdout, str_usage, argv0, argv0, errlogfile); |
| 370 | |
| 371 | exit(status); |
| 372 | } |
| 373 | |
| 374 | int main(int argc, char *argv[]) |
| 375 | { |
| 376 | char outf[FILENAME_MAX]; |
| 377 | IMAGE image; |
| 378 | int opt; |
| 379 | char *arg; |
| 380 | char *p, c; |
| 381 | int r_stdin, w_stdout; |
| 382 | int failure = 0, success = 0; |
| 383 | |
| 384 | envargv(&argc, &argv, "B2P"); |
| 385 | |
| 386 | r_stdin = !isatty(fileno(stdin)); |
| 387 | w_stdout = !isatty(fileno(stdout)); |
| 388 | |
| 389 | while (parsearg(&opt, &arg, argc, argv, "DdOoFfPp")) { |
| 390 | switch (toupper(opt)) { |
| 391 | case 'E': deletesrc ^= 1; break; |
| 392 | case 'T': copytime ^= 1; break; |
| 393 | case 'Q': quietmode ^= 1; break; |
| 394 | case 'L': errorlog ^= 1; break; |
| 395 | |
| 396 | case 'X': |
| 397 | r_stdin = 0; |
| 398 | w_stdout = 0; |
| 399 | break; |
| 400 | |
| 401 | case 'A': |
| 402 | alpha_format = (alpha_format == P2B_ALPHABMP_ARGB) ? |
| 403 | P2B_ALPHABMP_NONE : P2B_ALPHABMP_ARGB; |
| 404 | break; |
| 405 | |
| 406 | case 'B': |
| 407 | alpha_format = (alpha_format == P2B_ALPHABMP_BITFIELD) ? |
| 408 | P2B_ALPHABMP_NONE : P2B_ALPHABMP_BITFIELD; |
| 409 | break; |
| 410 | |
| 411 | case 'R': |
| 412 | expand_trans ^= 1; |
| 413 | break; |
| 414 | |
| 415 | case 'F': |
| 416 | /* '-F' option of bmp2png (ignored on png2bmp) */ |
| 417 | break; |
| 418 | |
| 419 | case 'P': |
| 420 | /* '-P' option of bmp2png (ignored on png2bmp) */ |
| 421 | break; |
| 422 | |
| 423 | case 'D': /* output directory */ |
| 424 | if (*arg == '-') arg = NULL; |
| 425 | if (arg == NULL) { |
| 426 | outdir[0] = '\0'; |
| 427 | } else { |
| 428 | strcpy(outdir, arg); |
| 429 | addslash(outdir); |
| 430 | if (makedir(outdir) != 0) { |
| 431 | xxprintf(wrn_mkdirfail, outdir, 'D'); |
| 432 | outdir[0] = '\0'; |
| 433 | } |
| 434 | } |
| 435 | break; |
| 436 | |
| 437 | case 'O': /* output filename */ |
| 438 | if (arg == NULL) { |
| 439 | outnam[0] = '\0'; |
| 440 | } else { |
| 441 | strcpy(outnam, arg); |
| 442 | p = basname(outnam); |
| 443 | c = *p; *p = '\0'; |
| 444 | if (makedir(outnam) != 0) { |
| 445 | xxprintf(wrn_mkdirfail, outnam, 'O'); |
| 446 | outnam[0] = '\0'; |
| 447 | } else { |
| 448 | *p = c; |
| 449 | } |
| 450 | } |
| 451 | break; |
| 452 | |
| 453 | case 0x00: /* input file spec */ |
| 454 | if (outnam[0] != '\0') { |
| 455 | strcpy(outf, outnam); |
| 456 | outnam[0] = '\0'; |
| 457 | } else if (w_stdout) { |
| 458 | if (!read_png(arg, &image)) return 1; |
| 459 | if (!write_bmp(NULL, &image)) return 1; |
| 460 | if (deletesrc) remove(arg); |
| 461 | return 0; |
| 462 | } else { |
| 463 | if (outdir[0] != '\0') { |
| 464 | strcat(strcpy(outf, outdir), basname(arg)); |
| 465 | } else { |
| 466 | strcpy(outf, arg); |
| 467 | } |
| 468 | |
| 469 | strcpy(suffix(outf), ".bmp"); |
| 470 | } |
| 471 | /* ---------------------- */ |
| 472 | printf("png2bmp read_png 2222222\n"); |
| 473 | if (!read_png(arg, &image)) { |
| 474 | printf("png2bmp read_png arg image\n"); |
| 475 | failure++; |
| 476 | break; |
| 477 | } |
| 478 | renbak(outf); |
| 479 | printf("png2bmp read_png 3333333\n"); |
| 480 | if (!write_bmp(outf, &image)) { |
| 481 | printf("png2bmp read_png outf image\n"); |
| 482 | failure++; |
| 483 | break; |
| 484 | } |
| 485 | /* ---------------------- */ |
| 486 | if (copytime) cpyftime(arg, outf); |
| 487 | if (deletesrc) remove(arg); |
| 488 | /* ---------------------- */ |
| 489 | success++; |
| 490 | break; |
| 491 | |
| 492 | default: |
| 493 | ; /* Ignore unknown option */ |
| 494 | } |
| 495 | } |
| 496 | printf("png2bmp failure is %d, success is %d, r_stdin is %d, w_stdout is %d \n", failure, success, r_stdin, w_stdout); |
| 497 | if (failure == 0 && success == 0) { |
| 498 | if (!r_stdin) |
| 499 | { |
| 500 | printf("png2bmp usage_exit\n"); |
| 501 | usage_exit(argv[0], 255); |
| 502 | } |
| 503 | printf("png2bmp 111111111\n"); |
| 504 | if (!read_png(NULL, &image)) |
| 505 | { |
| 506 | printf("png2bmp read_png NULL\n"); |
| 507 | return 1; |
| 508 | } |
| 509 | if (outnam[0] != '\0') { |
| 510 | printf("png2bmp write_bmp outnam is %s\n", outnam); |
| 511 | renbak(outnam); |
| 512 | return !write_bmp(outnam, &image); |
| 513 | } else if (w_stdout) { |
| 514 | printf("png2bmp write_bmp w_stdout\n"); |
| 515 | return !write_bmp(NULL, &image); |
| 516 | } else { |
| 517 | printf("png2bmp write_bmp outf is %s\n", outf); |
| 518 | strcat(strcpy(outf, outdir), "___stdin.bmp"); |
| 519 | renbak(outf); |
| 520 | return !write_bmp(outf, &image); |
| 521 | } |
| 522 | } |
| 523 | printf("png2bmp end failure is %d\n", failure); |
| 524 | return (failure > 255) ? 255 : failure; |
| 525 | } |
| 526 | |