Lines 31-36
Link Here
|
31 |
|
31 |
|
32 |
#ifdef HAVE_PNG |
32 |
#ifdef HAVE_PNG |
33 |
|
33 |
|
|
|
34 |
#include "zlib.h" |
34 |
#include "png.h" |
35 |
#include "png.h" |
35 |
|
36 |
|
36 |
/*** Stuff for PNG Dialog box ***/ |
37 |
/*** Stuff for PNG Dialog box ***/ |
Lines 99-112
Link Here
|
99 |
/* fread() returns 0 on error, so it is OK to store this in a png_size_t |
100 |
/* fread() returns 0 on error, so it is OK to store this in a png_size_t |
100 |
* instead of an int, which is what fread() actually returns. |
101 |
* instead of an int, which is what fread() actually returns. |
101 |
*/ |
102 |
*/ |
102 |
if (fread(data,1,length,(FILE *)png_ptr->io_ptr) != length) |
103 |
if (fread(data, 1, length, png_get_io_ptr(png_ptr)) != length) |
103 |
png_error(png_ptr, "Read Error"); |
104 |
png_error(png_ptr, "Read Error"); |
104 |
} |
105 |
} |
105 |
|
106 |
|
106 |
static void |
107 |
static void |
107 |
png_default_write_data(png_structp png_ptr, png_bytep data, png_size_t length) |
108 |
png_default_write_data(png_structp png_ptr, png_bytep data, png_size_t length) |
108 |
{ |
109 |
{ |
109 |
if (fwrite(data, 1, length, (FILE *)png_ptr->io_ptr) != length) |
110 |
if (fwrite(data, 1, length, png_get_io_ptr(png_ptr)) != length) |
110 |
png_error(png_ptr, "Write Error"); |
111 |
png_error(png_ptr, "Write Error"); |
111 |
} |
112 |
} |
112 |
#endif /* PNG_NO_STDIO */ |
113 |
#endif /* PNG_NO_STDIO */ |
Lines 441-446
Link Here
|
441 |
byte pc2nc[256]; /* for duplicated-color remapping (1st level) */ |
442 |
byte pc2nc[256]; /* for duplicated-color remapping (1st level) */ |
442 |
byte remap[256]; /* for bw/grayscale remapping (2nd level) */ |
443 |
byte remap[256]; /* for bw/grayscale remapping (2nd level) */ |
443 |
int i, j, numuniqcols=0, filter, linesize, pass; |
444 |
int i, j, numuniqcols=0, filter, linesize, pass; |
|
|
445 |
int bit_depth, color_type; |
444 |
byte *p, *png_line; |
446 |
byte *p, *png_line; |
445 |
char software[256]; |
447 |
char software[256]; |
446 |
char *savecmnt; |
448 |
char *savecmnt; |
Lines 458-464
Link Here
|
458 |
FatalError(software); |
460 |
FatalError(software); |
459 |
} |
461 |
} |
460 |
|
462 |
|
461 |
if (setjmp(png_ptr->jmpbuf)) { |
463 |
if (setjmp(png_jmpbuf(png_ptr))) { |
462 |
png_destroy_write_struct(&png_ptr, &info_ptr); |
464 |
png_destroy_write_struct(&png_ptr, &info_ptr); |
463 |
return -1; |
465 |
return -1; |
464 |
} |
466 |
} |
Lines 489-496
Link Here
|
489 |
png_set_filter(png_ptr, 0, filter); |
491 |
png_set_filter(png_ptr, 0, filter); |
490 |
} |
492 |
} |
491 |
|
493 |
|
492 |
info_ptr->width = w; |
|
|
493 |
info_ptr->height = h; |
494 |
if (w <= 0 || h <= 0) { |
494 |
if (w <= 0 || h <= 0) { |
495 |
SetISTR(ISTR_WARNING, "%s: image dimensions out of range (%dx%d)", |
495 |
SetISTR(ISTR_WARNING, "%s: image dimensions out of range (%dx%d)", |
496 |
fbasename, w, h); |
496 |
fbasename, w, h); |
Lines 498-505
Link Here
|
498 |
return -1; |
498 |
return -1; |
499 |
} |
499 |
} |
500 |
|
500 |
|
501 |
info_ptr->interlace_type = interCB.val ? 1 : 0; |
|
|
502 |
|
503 |
linesize = 0; /* quiet a compiler warning */ |
501 |
linesize = 0; /* quiet a compiler warning */ |
504 |
|
502 |
|
505 |
|
503 |
|
Lines 542-581
Link Here
|
542 |
png_destroy_write_struct(&png_ptr, &info_ptr); |
540 |
png_destroy_write_struct(&png_ptr, &info_ptr); |
543 |
return -1; |
541 |
return -1; |
544 |
} |
542 |
} |
545 |
info_ptr->color_type = PNG_COLOR_TYPE_RGB; |
543 |
color_type = PNG_COLOR_TYPE_RGB; |
546 |
info_ptr->bit_depth = 8; |
544 |
bit_depth = 8; |
547 |
} else /* ptype == PIC8 */ { |
545 |
} else /* ptype == PIC8 */ { |
548 |
linesize = w; |
546 |
linesize = w; |
549 |
info_ptr->color_type = PNG_COLOR_TYPE_PALETTE; |
547 |
color_type = PNG_COLOR_TYPE_PALETTE; |
550 |
if (numuniqcols <= 2) |
548 |
if (numuniqcols <= 2) |
551 |
info_ptr->bit_depth = 1; |
549 |
bit_depth = 1; |
552 |
else |
550 |
else |
553 |
if (numuniqcols <= 4) |
551 |
if (numuniqcols <= 4) |
554 |
info_ptr->bit_depth = 2; |
552 |
bit_depth = 2; |
555 |
else |
553 |
else |
556 |
if (numuniqcols <= 16) |
554 |
if (numuniqcols <= 16) |
557 |
info_ptr->bit_depth = 4; |
555 |
bit_depth = 4; |
558 |
else |
556 |
else |
559 |
info_ptr->bit_depth = 8; |
557 |
bit_depth = 8; |
560 |
|
558 |
|
561 |
for (i = 0; i < numuniqcols; i++) { |
559 |
for (i = 0; i < numuniqcols; i++) { |
562 |
palette[i].red = r1[i]; |
560 |
palette[i].red = r1[i]; |
563 |
palette[i].green = g1[i]; |
561 |
palette[i].green = g1[i]; |
564 |
palette[i].blue = b1[i]; |
562 |
palette[i].blue = b1[i]; |
565 |
} |
563 |
} |
566 |
info_ptr->num_palette = numuniqcols; |
564 |
png_set_PLTE(png_ptr, info_ptr, palette, numuniqcols); |
567 |
info_ptr->palette = palette; |
|
|
568 |
info_ptr->valid |= PNG_INFO_PLTE; |
565 |
info_ptr->valid |= PNG_INFO_PLTE; |
569 |
} |
566 |
} |
570 |
} |
567 |
} |
571 |
|
568 |
|
572 |
else if (colorType == F_GREYSCALE || colorType == F_BWDITHER) { |
569 |
else if (colorType == F_GREYSCALE || colorType == F_BWDITHER) { |
573 |
info_ptr->color_type = PNG_COLOR_TYPE_GRAY; |
570 |
color_type = PNG_COLOR_TYPE_GRAY; |
574 |
if (colorType == F_BWDITHER) { |
571 |
if (colorType == F_BWDITHER) { |
575 |
/* shouldn't happen */ |
572 |
/* shouldn't happen */ |
576 |
if (ptype == PIC24) FatalError("PIC24 and B/W Stipple in WritePNG()"); |
573 |
if (ptype == PIC24) FatalError("PIC24 and B/W Stipple in WritePNG()"); |
577 |
|
574 |
|
578 |
info_ptr->bit_depth = 1; |
575 |
bit_depth = 1; |
579 |
if (MONO(r1[0], g1[0], b1[0]) > MONO(r1[1], g1[1], b1[1])) { |
576 |
if (MONO(r1[0], g1[0], b1[0]) > MONO(r1[1], g1[1], b1[1])) { |
580 |
remap[0] = 1; |
577 |
remap[0] = 1; |
581 |
remap[1] = 0; |
578 |
remap[1] = 0; |
Lines 595-601
Link Here
|
595 |
png_destroy_write_struct(&png_ptr, &info_ptr); |
592 |
png_destroy_write_struct(&png_ptr, &info_ptr); |
596 |
return -1; |
593 |
return -1; |
597 |
} |
594 |
} |
598 |
info_ptr->bit_depth = 8; |
595 |
bit_depth = 8; |
599 |
} |
596 |
} |
600 |
else /* ptype == PIC8 */ { |
597 |
else /* ptype == PIC8 */ { |
601 |
int low_precision; |
598 |
int low_precision; |
Lines 617-623
Link Here
|
617 |
for (; i < 256; i++) |
614 |
for (; i < 256; i++) |
618 |
remap[i]=0; /* shouldn't be necessary, but... */ |
615 |
remap[i]=0; /* shouldn't be necessary, but... */ |
619 |
|
616 |
|
620 |
info_ptr->bit_depth = 8; |
617 |
bit_depth = 8; |
621 |
|
618 |
|
622 |
/* Note that this fails most of the time because of gamma */ |
619 |
/* Note that this fails most of the time because of gamma */ |
623 |
/* (and that would be a bug: GRR FIXME) */ |
620 |
/* (and that would be a bug: GRR FIXME) */ |
Lines 636-642
Link Here
|
636 |
for (i = 0; i < numuniqcols; i++) { |
633 |
for (i = 0; i < numuniqcols; i++) { |
637 |
remap[i] &= 0xf; |
634 |
remap[i] &= 0xf; |
638 |
} |
635 |
} |
639 |
info_ptr->bit_depth = 4; |
636 |
bit_depth = 4; |
640 |
|
637 |
|
641 |
/* try to adjust to 2-bit precision grayscale */ |
638 |
/* try to adjust to 2-bit precision grayscale */ |
642 |
|
639 |
|
Lines 652-658
Link Here
|
652 |
for (i = 0; i < numuniqcols; i++) { |
649 |
for (i = 0; i < numuniqcols; i++) { |
653 |
remap[i] &= 3; |
650 |
remap[i] &= 3; |
654 |
} |
651 |
} |
655 |
info_ptr->bit_depth = 2; |
652 |
bit_depth = 2; |
656 |
|
653 |
|
657 |
/* try to adjust to 1-bit precision grayscale */ |
654 |
/* try to adjust to 1-bit precision grayscale */ |
658 |
|
655 |
|
Lines 668-674
Link Here
|
668 |
for (i = 0; i < numuniqcols; i++) { |
665 |
for (i = 0; i < numuniqcols; i++) { |
669 |
remap[i] &= 1; |
666 |
remap[i] &= 1; |
670 |
} |
667 |
} |
671 |
info_ptr->bit_depth = 1; |
668 |
bit_depth = 1; |
672 |
} |
669 |
} |
673 |
} |
670 |
} |
674 |
} |
671 |
} |
Lines 677-682
Link Here
|
677 |
else |
674 |
else |
678 |
png_error(png_ptr, "Unknown colorstyle in WritePNG"); |
675 |
png_error(png_ptr, "Unknown colorstyle in WritePNG"); |
679 |
|
676 |
|
|
|
677 |
png_set_IHDR(png_ptr, info_ptr, w, h, bit_depth, color_type, |
678 |
interCB.val ? 1 : 0, 0, 0); |
679 |
|
680 |
if ((text = (png_textp)malloc(sizeof(png_text)))) { |
680 |
if ((text = (png_textp)malloc(sizeof(png_text)))) { |
681 |
sprintf(software, "XV %s", REVDATE); |
681 |
sprintf(software, "XV %s", REVDATE); |
682 |
|
682 |
|
Lines 686-704
Link Here
|
686 |
text->text_length = strlen(text->text); |
686 |
text->text_length = strlen(text->text); |
687 |
|
687 |
|
688 |
info_ptr->max_text = 1; |
688 |
info_ptr->max_text = 1; |
689 |
info_ptr->num_text = 1; |
689 |
png_set_text(png_ptr, info_ptr, text, 1); |
690 |
info_ptr->text = text; |
|
|
691 |
} |
690 |
} |
692 |
|
691 |
|
693 |
Display_Gamma = gDial.val; /* Save the current gamma for loading */ |
692 |
Display_Gamma = gDial.val; /* Save the current gamma for loading */ |
694 |
|
693 |
|
695 |
// GRR FIXME: add .Xdefaults option to omit writing gamma (size, cumulative errors when editing)--alternatively, modify save box to include "omit" checkbox |
694 |
// GRR FIXME: add .Xdefaults option to omit writing gamma (size, cumulative errors when editing)--alternatively, modify save box to include "omit" checkbox |
696 |
info_ptr->gamma = 1.0/gDial.val; |
695 |
png_set_gamma(png_ptr, 1.0/gDial.val, 0); |
697 |
info_ptr->valid |= PNG_INFO_gAMA; |
696 |
info_ptr->valid |= PNG_INFO_gAMA; |
698 |
|
697 |
|
699 |
png_write_info(png_ptr, info_ptr); |
698 |
png_write_info(png_ptr, info_ptr); |
700 |
|
699 |
|
701 |
if (info_ptr->bit_depth < 8) |
700 |
if (bit_depth < 8) |
702 |
png_set_packing(png_ptr); |
701 |
png_set_packing(png_ptr); |
703 |
|
702 |
|
704 |
pass=png_set_interlace_handling(png_ptr); |
703 |
pass=png_set_interlace_handling(png_ptr); |
Lines 711-723
Link Here
|
711 |
int j; |
710 |
int j; |
712 |
p = pic; |
711 |
p = pic; |
713 |
for (j = 0; j < h; ++j) { |
712 |
for (j = 0; j < h; ++j) { |
714 |
if (info_ptr->color_type == PNG_COLOR_TYPE_GRAY) { |
713 |
if (color_type == PNG_COLOR_TYPE_GRAY) { |
715 |
int k; |
714 |
int k; |
716 |
for (k = 0; k < w; ++k) |
715 |
for (k = 0; k < w; ++k) |
717 |
png_line[k] = ptype==PIC24 ? MONO(p[k*3], p[k*3+1], p[k*3+2]) : |
716 |
png_line[k] = ptype==PIC24 ? MONO(p[k*3], p[k*3+1], p[k*3+2]) : |
718 |
remap[pc2nc[p[k]]]; |
717 |
remap[pc2nc[p[k]]]; |
719 |
png_write_row(png_ptr, png_line); |
718 |
png_write_row(png_ptr, png_line); |
720 |
} else if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) { |
719 |
} else if (color_type == PNG_COLOR_TYPE_PALETTE) { |
721 |
int k; |
720 |
int k; |
722 |
for (k = 0; k < w; ++k) |
721 |
for (k = 0; k < w; ++k) |
723 |
png_line[k] = pc2nc[p[k]]; |
722 |
png_line[k] = pc2nc[p[k]]; |
Lines 921-927
Link Here
|
921 |
FatalError("malloc failure in LoadPNG"); |
920 |
FatalError("malloc failure in LoadPNG"); |
922 |
} |
921 |
} |
923 |
|
922 |
|
924 |
if (setjmp(png_ptr->jmpbuf)) { |
923 |
if (setjmp(png_jmpbuf(png_ptr))) { |
925 |
fclose(fp); |
924 |
fclose(fp); |
926 |
png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL); |
925 |
png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL); |
927 |
if (!read_anything) { |
926 |
if (!read_anything) { |
Lines 1143-1149
Link Here
|
1143 |
{ |
1142 |
{ |
1144 |
SetISTR(ISTR_WARNING,"%s: libpng error: %s", fbasename, message); |
1143 |
SetISTR(ISTR_WARNING,"%s: libpng error: %s", fbasename, message); |
1145 |
|
1144 |
|
1146 |
longjmp(png_ptr->jmpbuf, 1); |
1145 |
longjmp(png_jmpbuf(png_ptr), 1); |
1147 |
} |
1146 |
} |
1148 |
|
1147 |
|
1149 |
|
1148 |
|