--- build/xvpng.c.orig 2019-10-16 08:48:00.603575631 +0900 +++ build/xvpng.c 2019-10-16 08:52:32.239838823 +0900 @@ -25,6 +25,7 @@ #ifdef HAVE_PNG +#include "zlib.h" #include "png.h" /*** Stuff for PNG Dialog box ***/ @@ -425,6 +426,16 @@ { png_struct *png_ptr; png_info *info_ptr; + struct { + /* IHDR */ + png_uint_32 width; + png_uint_32 height; + int bit_depth; + int color_type; + int interlace_type; + /* PLTE */ + int use_palette; + } info_tmp; png_color palette[256]; png_textp text; int unit_type; @@ -433,6 +444,7 @@ byte *p, *png_line; char software[256]; char *savecmnt = NULL; + int num_text, max_text; unsigned int xres, yres; int runit; @@ -447,7 +459,7 @@ FatalError("malloc failure in WritePNG"); } - if (setjmp(png_ptr->jmpbuf)) { + if (setjmp(png_jmpbuf(png_ptr))) { png_destroy_write_struct(&png_ptr, &info_ptr); return -1; } @@ -473,8 +485,8 @@ png_set_filter(png_ptr, 0, filter); } - info_ptr->width = w; - info_ptr->height = h; + info_tmp.width = w; + info_tmp.height = h; runit = rulist[RBWhich(RUnitRB)]; switch (runit) { @@ -493,45 +505,46 @@ } - info_ptr->interlace_type = interCB.val ? 1 : 0; + info_tmp.interlace_type = + interCB.val ? PNG_INTERLACE_ADAM7 : PNG_INTERLACE_NONE; if (colorType == F_FULLCOLOR || colorType == F_REDUCED) { if(ptype == PIC24) { linesize = 3*w; - info_ptr->color_type = PNG_COLOR_TYPE_RGB; - info_ptr->bit_depth = 8; + info_tmp.color_type = PNG_COLOR_TYPE_RGB; + info_tmp.bit_depth = 8; + info_tmp.use_palette = 0; } else { linesize = w; - info_ptr->color_type = PNG_COLOR_TYPE_PALETTE; + info_tmp.color_type = PNG_COLOR_TYPE_PALETTE; if(numcols <= 2) - info_ptr->bit_depth = 1; + info_tmp.bit_depth = 1; else if(numcols <= 4) - info_ptr->bit_depth = 2; + info_tmp.bit_depth = 2; else if(numcols <= 16) - info_ptr->bit_depth = 4; + info_tmp.bit_depth = 4; else - info_ptr->bit_depth = 8; + info_tmp.bit_depth = 8; for(i = 0; i < numcols; i++) { palette[i].red = rmap[i]; palette[i].green = gmap[i]; palette[i].blue = bmap[i]; } - info_ptr->num_palette = numcols; - info_ptr->palette = palette; - info_ptr->valid |= PNG_INFO_PLTE; + info_tmp.use_palette = 1; } } else if(colorType == F_GREYSCALE || colorType == F_BWDITHER) { - info_ptr->color_type = PNG_COLOR_TYPE_GRAY; + info_tmp.color_type = PNG_COLOR_TYPE_GRAY; + info_tmp.use_palette = 0; if(colorType == F_BWDITHER) { /* shouldn't happen */ if (ptype == PIC24) FatalError("PIC24 and B/W Stipple in WritePNG()"); - info_ptr->bit_depth = 1; + info_tmp.bit_depth = 1; if(MONO(rmap[0], gmap[0], bmap[0]) > MONO(rmap[1], gmap[1], bmap[1])) { remap[0] = 1; remap[1] = 0; @@ -545,7 +558,7 @@ else { if(ptype == PIC24) { linesize = w*3; - info_ptr->bit_depth = 8; + info_tmp.bit_depth = 8; } else { int low_presc; @@ -558,7 +571,7 @@ for(; i < 256; i++) remap[i]=0; - info_ptr->bit_depth = 8; + info_tmp.bit_depth = 8; /* Note that this fails most of the time because of gamma */ /* try to adjust to 4 bit prescision grayscale */ @@ -576,7 +589,7 @@ for(i = 0; i < numcols; i++) { remap[i] &= 0xf; } - info_ptr->bit_depth = 4; + info_tmp.bit_depth = 4; /* try to adjust to 2 bit prescision grayscale */ @@ -592,7 +605,7 @@ for(i = 0; i < numcols; i++) { remap[i] &= 3; } - info_ptr->bit_depth = 2; + info_tmp.bit_depth = 2; /* try to adjust to 1 bit prescision grayscale */ @@ -608,7 +621,7 @@ for(i = 0; i < numcols; i++) { remap[i] &= 1; } - info_ptr->bit_depth = 1; + info_tmp.bit_depth = 1; } } } @@ -617,6 +630,20 @@ else png_error(png_ptr, "Unknown colorstyle in WritePNG"); + png_set_IHDR(png_ptr, info_ptr, + info_tmp.width, info_tmp.height, + info_tmp.bit_depth, info_tmp.color_type, + info_tmp.interlace_type, PNG_COMPRESSION_TYPE_BASE, + PNG_FILTER_TYPE_BASE); + if (info_tmp.use_palette) { + /* + * info_ptr->num_palette = numcols; + * info_ptr->palette = palette; + * info_ptr->valid |= PNG_INFO_PLTE; + */ + png_set_PLTE(png_ptr, info_ptr, palette, numcols); + } + if ((text = (png_textp)malloc(sizeof(png_text)))) { sprintf(software, "XV %s", REVDATE); @@ -624,20 +651,28 @@ text->key = "Software"; text->text = software; text->text_length = strlen(text->text); + text->lang = NULL; - info_ptr->max_text = 1; - info_ptr->num_text = 1; - info_ptr->text = text; + /* + * info_ptr->max_text = 1; + * info_ptr->num_text = 1; + * info_ptr->text = text; + */ + png_set_text(png_ptr, info_ptr, text, 1); + num_text = max_text = 1; } Display_Gamma = gDial.val; /* Save the current gamma for loading */ - info_ptr->gamma = 1.0/gDial.val; - info_ptr->valid |= PNG_INFO_gAMA; + /* + * info_ptr->gamma = 1.0/gDial.val; + * info_ptr->valid |= PNG_INFO_gAMA; + */ + png_set_gAMA(png_ptr, info_ptr, 1.0/gDial.val); png_write_info(png_ptr, info_ptr); - if(info_ptr->bit_depth < 8) + if(info_tmp.bit_depth < 8) png_set_packing(png_ptr); pass=png_set_interlace_handling(png_ptr); @@ -649,7 +684,7 @@ int j; p = pic; for(j = 0; j < h; j++) { - if(info_ptr->color_type == PNG_COLOR_TYPE_GRAY) { + if(info_tmp.color_type == PNG_COLOR_TYPE_GRAY) { int k; for(k = 0; k < w; k++) png_line[k] = ptype==PIC24 ? MONO(p[k*3], p[k*3+1], p[k*3+2]) : @@ -674,24 +709,26 @@ strcpy(savecmnt, picComments); key = savecmnt; tp = text; - info_ptr->num_text = 0; + + png_free_data(png_ptr, info_ptr, PNG_FREE_TEXT, -1); + num_text = 0; comment = strchr(key, ':'); do { /* Allocate a larger structure for comments if necessary */ - if (info_ptr->num_text >= info_ptr->max_text) + if (num_text >= max_text) { if ((tp = - realloc(text, (info_ptr->num_text + 2)*sizeof(png_text))) == NULL) + realloc(text, (num_text + 2)*sizeof(png_text))) == NULL) { break; } else { text = tp; - tp = &text[info_ptr->num_text]; - info_ptr->max_text += 2; + tp = &text[num_text]; + max_text += 2; } } @@ -741,7 +778,7 @@ } tp->compression = tp->text_length > 640 ? 0 : -1; - info_ptr->num_text++; + num_text++; tp++; } } @@ -765,20 +802,24 @@ tp->text = key; tp->text_length = q - key; tp->compression = tp->text_length > 750 ? 0 : -1; - info_ptr->num_text++; + num_text++; key = NULL; } } while (key && *key); + png_set_text(png_ptr, info_ptr, text, num_text); } else { - info_ptr->num_text = 0; + png_free_data(png_ptr, info_ptr, PNG_FREE_TEXT, -1); } } - info_ptr->text = text; - png_convert_from_time_t(&(info_ptr->mod_time), time(NULL)); - info_ptr->valid |= PNG_INFO_tIME; + { + png_time mod_time; + + png_convert_from_time_t(&mod_time, time(NULL)); + png_set_tIME(png_ptr, info_ptr, &mod_time); + } png_write_end(png_ptr, info_ptr); fflush(fp); /* just in case we core-dump before finishing... */ @@ -786,8 +827,6 @@ if (text) { free(text); - /* must do this or png_destroy_write_struct() 0.97+ will free text again: */ - info_ptr->text = (png_textp)NULL; if (savecmnt) { free(savecmnt); @@ -820,6 +859,8 @@ int filesize; int pass; size_t commentsize; + png_textp text; + int num_text; fbasename = BaseName(fname); @@ -856,7 +897,7 @@ FatalError("malloc failure in LoadPNG"); } - if(setjmp(png_ptr->jmpbuf)) { + if(setjmp(png_jmpbuf(png_ptr))) { fclose(fp); png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL); if(!read_anything) { @@ -875,15 +916,15 @@ png_init_io(png_ptr, fp); png_read_info(png_ptr, info_ptr); - pinfo->w = pinfo->normw = info_ptr->width; - pinfo->h = pinfo->normh = info_ptr->height; + pinfo->w = pinfo->normw = png_get_image_width(png_ptr, info_ptr); + pinfo->h = pinfo->normh = png_get_image_height(png_ptr, info_ptr); pinfo->frmType = F_PNG; sprintf(pinfo->fullInfo, "PNG, %d bit ", - info_ptr->bit_depth * info_ptr->channels); + png_get_bit_depth(png_ptr,info_ptr) * png_get_channels(png_ptr, info_ptr)); - switch(info_ptr->color_type) { + switch(png_get_color_type(png_ptr, info_ptr)) { case PNG_COLOR_TYPE_PALETTE: strcat(pinfo->fullInfo, "palette color"); break; @@ -907,35 +948,42 @@ sprintf(pinfo->fullInfo + strlen(pinfo->fullInfo), ", %sinterlaced. (%d bytes)", - info_ptr->interlace_type ? "" : "non-", filesize); + png_get_interlace_type(png_ptr, info_ptr) ? "" : "non-", filesize); - sprintf(pinfo->shrtInfo, "%dx%d PNG", info_ptr->width, info_ptr->height); + sprintf(pinfo->shrtInfo, "%dx%d PNG", + png_get_image_width(png_ptr, info_ptr), + png_get_image_height(png_ptr, info_ptr)); - if (info_ptr->bit_depth < 8) + if (png_get_bit_depth(png_ptr, info_ptr) < 8) png_set_packing(png_ptr); - if (info_ptr->valid & PNG_INFO_gAMA) - png_set_gamma(png_ptr, Display_Gamma, info_ptr->gamma); + if (png_get_valid(png_ptr, info_ptr, PNG_INFO_gAMA)) { + double gamma; + png_get_gAMA(png_ptr, info_ptr, &gamma); + png_set_gamma(png_ptr, Display_Gamma, gamma); + } else png_set_gamma(png_ptr, Display_Gamma, 0.45); - if (info_ptr->valid & PNG_INFO_bKGD) - png_set_background(png_ptr, &info_ptr->background, + if (png_get_valid(png_ptr, info_ptr, PNG_INFO_bKGD)) { + png_color_16p background; + png_get_bKGD(png_ptr, info_ptr, &background); + png_set_background(png_ptr, background, PNG_BACKGROUND_GAMMA_FILE, 1, 1.0); - else { + } else { my_background.red = my_background.green = my_background.blue = my_background.gray = 0; png_set_background(png_ptr, &my_background, PNG_BACKGROUND_GAMMA_SCREEN, 0, Display_Gamma); } - if (info_ptr->bit_depth == 16) + if (png_get_bit_depth(png_ptr, info_ptr) == 16) png_set_strip_16(png_ptr); - if (info_ptr->color_type == PNG_COLOR_TYPE_GRAY || - info_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) + if (png_get_color_type(png_ptr, info_ptr) == PNG_COLOR_TYPE_GRAY || + png_get_color_type(png_ptr, info_ptr) == PNG_COLOR_TYPE_GRAY_ALPHA) { - if (info_ptr->bit_depth == 1) + if (png_get_bit_depth(png_ptr, info_ptr) == 1) pinfo->colType = F_BWDITHER; else pinfo->colType = F_GREYSCALE; @@ -946,24 +994,28 @@ png_read_update_info(png_ptr, info_ptr); - if(info_ptr->color_type == PNG_COLOR_TYPE_RGB || - info_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA) { + if(png_get_color_type(png_ptr, info_ptr) == PNG_COLOR_TYPE_RGB || + png_get_color_type(png_ptr, info_ptr) == PNG_COLOR_TYPE_RGB_ALPHA) { linesize = pinfo->w * 3; pinfo->colType = F_FULLCOLOR; pinfo->type = PIC24; } else { linesize = pinfo->w; pinfo->type = PIC8; - if(info_ptr->color_type == PNG_COLOR_TYPE_GRAY || - info_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) { + if(png_get_color_type(png_ptr, info_ptr) == PNG_COLOR_TYPE_GRAY || + png_get_color_type(png_ptr, info_ptr) == PNG_COLOR_TYPE_GRAY_ALPHA) { for(i = 0; i < 256; i++) pinfo->r[i] = pinfo->g[i] = pinfo->b[i] = i; } else { + png_colorp palette; + int num_palette; + + png_get_PLTE(png_ptr, info_ptr, &palette, &num_palette); pinfo->colType = F_FULLCOLOR; - for(i = 0; i < info_ptr->num_palette; i++) { - pinfo->r[i] = info_ptr->palette[i].red; - pinfo->g[i] = info_ptr->palette[i].green; - pinfo->b[i] = info_ptr->palette[i].blue; + for (i = 0; i < num_palette; i++) { + pinfo->r[i] = palette[i].red; + pinfo->g[i] = palette[i].green; + pinfo->b[i] = palette[i].blue; } } } @@ -973,7 +1025,17 @@ png_error(png_ptr, "can't allocate space for PNG image"); } - png_start_read_image(png_ptr); + /* + * In png 1.5 (or at least 1.5.1beta06) calling this after calling + * png_read_update_info() does nothing besides issue a misleading + * warning message. The png docs are not at all clear on what an + * application is *supposed* to do, so I'm not sure if this is a + * problem with xv or with libpng. However, for now I'll comment + * this out as according to the png source that should be harmless + * and we don't want to see the warning message every time someone + * opens a png. + */ + /*png_start_read_image(png_ptr);*/ for(i = 0; i < pass; i++) { byte *p = pinfo->pic; @@ -987,22 +1049,24 @@ png_read_end(png_ptr, info_ptr); - if(info_ptr->num_text > 0) { + png_get_text(png_ptr, info_ptr, &text, &num_text); + if(num_text > 0) { commentsize = 1; - for(i = 0; i < info_ptr->num_text; i++) - commentsize += strlen(info_ptr->text[i].key) + 1 + - info_ptr->text[i].text_length + 2; + for(i = 0; i < num_text; i++) + commentsize += strlen(text[i].key) + 1 + + text[i].text_length + 2; if((pinfo->comment = malloc(commentsize)) == NULL) { png_warning(png_ptr,"can't allocate comment string"); } else { pinfo->comment[0] = '\0'; - for(i = 0; i < info_ptr->num_text; i++) { - strcat(pinfo->comment, info_ptr->text[i].key); + for (i = 0; i < num_text; i++) { + strcat(pinfo->comment, text[i].key); strcat(pinfo->comment, "::"); - strcat(pinfo->comment, info_ptr->text[i].text); + if (text[i].text_length != 0) + strcat(pinfo->comment, text[i].text); strcat(pinfo->comment, "\n"); } } @@ -1045,7 +1109,7 @@ { SetISTR(ISTR_WARNING,"%s: libpng error: %s", fbasename, message); - longjmp(png_ptr->jmpbuf, 1); + longjmp(png_jmpbuf(png_ptr), 1); }