90 #define PROGNAME "wpng" 91 #define VERSION "2.00 of 2 June 2007" 92 #define APPNAME "Simple PGM/PPM/PAM to PNG Converter" 94 #if defined(__MSDOS__) || defined(__OS2__) 96 #elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__) 113 # define getch() _read_kbd(0, 1, 0) 118 # define getch() getkey() 123 # define FGETS(buf,len,stream) dos_kbd_gets(buf,len) 141 static int wpng_isvalid_latin1(
uch *
p,
int len);
142 static void wpng_cleanup(
void);
145 static char *dos_kbd_gets(
char *
buf,
int len);
154 int main(
int argc,
char **argv)
163 char *inname =
NULL, outname[256];
164 char *
p, pnmchar, pnmline[256];
165 char *bgstr, *textbuf =
NULL;
172 double CRT_exponent = 2.2;
173 double default_display_exponent;
174 double default_gamma = 0.0;
186 wpng_info.
gamma = 0.0;
200 LUT_exponent = 1.0 / 2.2;
206 LUT_exponent = 1.0 / 1.7;
209 tmpfile = fopen(
"/etc/config/system.glGammaVal",
"r");
213 fgets(tmpline, 80, tmpfile);
215 sgi_gamma = atof(tmpline);
217 LUT_exponent = 1.0 / sgi_gamma;
219 #elif defined(Macintosh) 220 LUT_exponent = 1.8 / 2.61;
230 default_display_exponent = LUT_exponent * CRT_exponent;
238 if ((p = getenv(
"SCREEN_GAMMA")) !=
NULL) {
245 if (default_gamma == 0.0)
246 default_gamma = 1.0 / default_display_exponent;
251 while (*++argv && !error) {
252 if (!strncmp(*argv,
"-i", 2)) {
254 }
else if (!strncmp(*argv,
"-time", 3)) {
257 }
else if (!strncmp(*argv,
"-text", 3)) {
259 }
else if (!strncmp(*argv,
"-gamma", 2)) {
263 wpng_info.
gamma = atof(*argv);
264 if (wpng_info.
gamma <= 0.0)
266 else if (wpng_info.
gamma > 1.01)
268 " warning: file gammas are usually less than 1.0\n");
270 }
else if (!strncmp(*argv,
"-bgcolor", 4)) {
275 if (strlen(bgstr) != 7 || bgstr[0] !=
'#')
280 sscanf(bgstr+1,
"%2x%2x%2x", &r, &g, &b);
303 ": must give input filename or provide image data via stdin\n");
308 setmode(fileno(stdin), O_BINARY);
309 setmode(fileno(stdout), O_BINARY);
311 if ((wpng_info.
infile = fdopen(fileno(stdin),
"rb")) ==
NULL) {
313 ": unable to reopen stdin in binary mode\n");
316 if ((wpng_info.
outfile = fdopen(fileno(stdout),
"wb")) ==
NULL) {
318 ": unable to reopen stdout in binary mode\n");
324 }
else if ((len = strlen(inname)) > 250) {
325 fprintf(stderr,
PROGNAME ": input filename is too long [%d chars]\n",
328 }
else if (!(wpng_info.
infile = fopen(inname,
"rb"))) {
329 fprintf(stderr,
PROGNAME ": can't open input file [%s]\n", inname);
334 fgets(pnmline, 256, wpng_info.
infile);
335 if (pnmline[0] !=
'P' || ((pnmchar = pnmline[1]) !=
'5' &&
336 pnmchar !=
'6' && pnmchar !=
'8'))
339 ": input file [%s] is not a binary PGM, PPM or PAM file\n",
347 fgets(pnmline, 256, wpng_info.
infile);
348 }
while (pnmline[0] ==
'#');
349 sscanf(pnmline,
"%ld %ld", &wpng_info.
width, &wpng_info.
height);
351 fgets(pnmline, 256, wpng_info.
infile);
352 }
while (pnmline[0] ==
'#');
353 sscanf(pnmline,
"%d", &maxval);
354 if (wpng_info.
width <= 0L || wpng_info.
height <= 0L ||
358 ": only positive width/height, maxval == 255 allowed \n");
365 if ((p = strrchr(inname,
'.')) ==
NULL ||
366 (p - inname) != (len - 4))
368 strcpy(outname, inname);
369 strcpy(outname+len,
".png");
372 strncpy(outname, inname, len);
373 strcpy(outname+len,
".png");
376 if ((wpng_info.
outfile = fopen(outname,
"rb")) !=
NULL) {
377 fprintf(stderr,
PROGNAME ": output file exists [%s]\n",
381 }
else if (!(wpng_info.
outfile = fopen(outname,
"wb"))) {
382 fprintf(stderr,
PROGNAME ": can't open output file [%s]\n",
405 "Usage: %s [-gamma exp] [-bgcolor bg] [-text] [-time] [-interlace] pnmfile\n" 406 "or: ... | %s [-gamma exp] [-bgcolor bg] [-text] [-time] [-interlace] | ...\n" 407 " exp \ttransfer-function exponent (``gamma'') of the image in\n" 408 "\t\t floating-point format (e.g., ``%.5f''); if image looks\n" 409 "\t\t correct on given display system, image gamma is equal to\n" 410 "\t\t inverse of display-system exponent, i.e., 1 / (LUT * CRT)\n" 411 "\t\t (where LUT = lookup-table exponent and CRT = CRT exponent;\n" 412 "\t\t first varies, second is usually 2.2, all are positive)\n" 413 " bg \tdesired background color for alpha-channel images, in\n" 414 "\t\t 7-character hex RGB format (e.g., ``#ff7700'' for orange:\n" 415 "\t\t same as HTML colors)\n" 416 " -text\tprompt interactively for text info (tEXt chunks)\n" 417 " -time\tinclude a tIME chunk (last modification time)\n" 418 " -interlace\twrite interlaced PNG image\n" 420 "pnmfile or stdin must be a binary PGM (`P5'), PPM (`P6') or (extremely\n" 421 "unofficial and unsupported!) PAM (`P8') file. Currently it is required\n" 422 "to have maxval == 255 (i.e., no scaling). If pnmfile is specified, it\n" 423 "is converted to the corresponding PNG file with the same base name but a\n" 424 "``.png'' extension; files read from stdin are converted and sent to stdout.\n" 425 "The conversion is progressive (low memory usage) unless interlacing is\n" 426 "requested; in that case the whole image will be buffered in memory and\n" 427 "written in one call.\n" 439 (keybd = fdopen(fileno(stderr),
"r")) !=
NULL &&
441 (textbuf = (
char *)
malloc((5 + 9)*75)) !=
NULL)
446 "Enter text info (no more than 72 characters per line);\n");
447 fprintf(stderr,
"to skip a field, hit the <Enter> key.\n");
453 fprintf(stderr,
" Title: ");
455 if (
FGETS(p, 74, keybd) && (len = strlen(p)) > 1) {
456 if (p[len-1] ==
'\n')
460 if ((result = wpng_isvalid_latin1((
uch *)p, len)) >= 0) {
461 fprintf(stderr,
" " PROGNAME " warning: character code" 462 " %u is %sdiscouraged by the PNG\n specification " 463 "[first occurrence was at character position #%d]\n",
464 (
unsigned)p[result], (p[result] == 27)?
"strongly " :
"",
467 #ifdef FORBID_LATIN1_CTRL 471 if (p[result] == 27) {
483 fprintf(stderr,
" Author: ");
485 if (
FGETS(p, 74, keybd) && (len = strlen(p)) > 1) {
486 if (p[len-1] ==
'\n')
490 if ((result = wpng_isvalid_latin1((
uch *)p, len)) >= 0) {
491 fprintf(stderr,
" " PROGNAME " warning: character code" 492 " %u is %sdiscouraged by the PNG\n specification " 493 "[first occurrence was at character position #%d]\n",
494 (
unsigned)p[result], (p[result] == 27)?
"strongly " :
"",
497 #ifdef FORBID_LATIN1_CTRL 501 if (p[result] == 27) {
513 fprintf(stderr,
" Description (up to 9 lines):\n");
514 for (i = 1; i < 10; ++
i) {
515 fprintf(stderr,
" [%d] ", i);
517 if (
FGETS(p, 74, keybd) && (len = strlen(p)) > 1)
522 if ((len = p - (textbuf + TEXT_DESC_OFFSET)) > 1) {
530 if ((result = wpng_isvalid_latin1((
uch *)p, len)) >= 0) {
531 fprintf(stderr,
" " PROGNAME " warning: character code" 532 " %u is %sdiscouraged by the PNG\n specification " 533 "[first occurrence was at character position #%d]\n",
534 (
unsigned)p[result], (p[result] == 27)?
"strongly " :
"",
537 #ifdef FORBID_LATIN1_CTRL 541 if (p[result] == 27) {
553 fprintf(stderr,
" Copyright: ");
555 if (
FGETS(p, 74, keybd) && (len = strlen(p)) > 1) {
556 if (p[len-1] ==
'\n')
560 if ((result = wpng_isvalid_latin1((
uch *)p, len)) >= 0) {
561 fprintf(stderr,
" " PROGNAME " warning: character code" 562 " %u is %sdiscouraged by the PNG\n specification " 563 "[first occurrence was at character position #%d]\n",
564 (
unsigned)p[result], (p[result] == 27)?
"strongly " :
"",
567 #ifdef FORBID_LATIN1_CTRL 571 if (p[result] == 27) {
583 fprintf(stderr,
" E-mail: ");
585 if (
FGETS(p, 74, keybd) && (len = strlen(p)) > 1) {
586 if (p[len-1] ==
'\n')
590 if ((result = wpng_isvalid_latin1((
uch *)p, len)) >= 0) {
591 fprintf(stderr,
" " PROGNAME " warning: character code" 592 " %u is %sdiscouraged by the PNG\n specification " 593 "[first occurrence was at character position #%d]\n",
594 (
unsigned)p[result], (p[result] == 27)?
"strongly " :
"",
597 #ifdef FORBID_LATIN1_CTRL 601 if (p[result] == 27) {
613 fprintf(stderr,
" URL: ");
615 if (
FGETS(p, 74, keybd) && (len = strlen(p)) > 1) {
616 if (p[len-1] ==
'\n')
620 if ((result = wpng_isvalid_latin1((
uch *)p, len)) >= 0) {
621 fprintf(stderr,
" " PROGNAME " warning: character code" 622 " %u is %sdiscouraged by the PNG\n specification " 623 "[first occurrence was at character position #%d]\n",
624 (
unsigned)p[result], (p[result] == 27)?
"strongly " :
"",
627 #ifdef FORBID_LATIN1_CTRL 631 if (p[result] == 27) {
645 fprintf(stderr,
PROGNAME ": unable to allocate memory for text\n");
657 ": libpng initialization problem (longjmp)\n");
660 fprintf(stderr,
PROGNAME ": insufficient memory\n");
664 ": internal logic error (unexpected PNM type)\n");
668 ": unknown writepng_init() error\n");
678 if (text && textbuf) {
689 rowbytes = wpng_info.
width;
690 else if (wpng_info.
pnmtype == 6)
691 rowbytes = wpng_info.
width * 3;
693 rowbytes = wpng_info.
width * 4;
699 fprintf(stderr,
"Encoding image data...\n");
705 ulg image_bytes = rowbytes * wpng_info.
height;
710 fprintf(stderr,
PROGNAME ": insufficient memory for image data\n");
715 for (i = 0; i < wpng_info.
height; ++
i)
718 if (bytes != image_bytes) {
719 fprintf(stderr,
PROGNAME ": expected %lu bytes, got %lu bytes\n",
721 fprintf(stderr,
" (continuing anyway)\n");
725 ": libpng problem (longjmp) while writing image data\n");
737 fprintf(stderr,
PROGNAME ": insufficient memory for row data\n");
743 for (j = wpng_info.
height; j > 0L; --j) {
745 if (bytes != rowbytes) {
747 ": expected %lu bytes, got %lu bytes (row %ld)\n", rowbytes,
748 bytes, wpng_info.
height-j);
754 ": libpng problem (longjmp) while writing row %ld\n",
766 fprintf(stderr,
PROGNAME ": error on final libpng call\n");
776 fprintf(stderr,
"Done.\n");
789 static int wpng_isvalid_latin1(
uch *
p,
int len)
793 for (i = 0; i <
len; ++
i) {
794 if (
p[i] == 10 || (
p[i] > 31 &&
p[i] < 127) ||
p[i] > 160)
796 if (result < 0 || (
p[result] != 27 &&
p[i] == 27))
807 static void wpng_cleanup(
void)
835 static char *dos_kbd_gets(
char *
buf,
int len)
840 buf[count++] = ch = getche();
841 }
while (ch !=
'\r' && count < len-1);
844 if (
buf[count] ==
'\r')
847 fprintf(stderr,
"\n");
int writepng_encode_image(mainprog_info *mainprog_ptr)
#define TEXT_AUTHOR_OFFSET
GLboolean GLboolean GLboolean b
GLenum GLuint GLenum GLsizei const GLchar * buf
int main(int argc, char **argv)
void writepng_cleanup(mainprog_info *mainprog_ptr)
GLdouble GLdouble GLdouble r
#define TEXT_TITLE_OFFSET
void writepng_version_info(void)
int writepng_encode_finish(mainprog_info *mainprog_ptr)
#define TEXT_EMAIL_OFFSET
int writepng_encode_row(mainprog_info *mainprog_ptr)
GLuint GLuint GLsizei count
int writepng_init(mainprog_info *mainprog_ptr)