$NetBSD: patch-png2,v 1.1 1999/06/13 16:23:53 hubertf Exp $

This patch is based on
http://www.mit.edu/afs/athena/contrib/graphics/src/xv/patches/png/xvpng.diff
It was edited to fit into the NetBSD Packages Collection! - HF

---------------------------------------------------------------------------

This is v1.2 of the PNG patch for xv.  This version adds a PNG dialog
so that the gamma, compression, interlacing, and filters can be selected
when saving PNG images.  The gamma dial needed floating point values, so
it required modifying the Dial widget, and subsequently affected all of
the popups that use a Dial (jpeg, ps, and color).

To add PNG support to xv, you need the xv-3.10a source code, libpng and zlib.

To apply the patch, go into the xv-3.10a directory and execute
patch -p1 < thisfile

The Makefile expects libpng and zlib to be already compiled.  The versions
I used were libpng-0.89 and zlib 1.0.2, but it should work with later
versions.  You will also have to modify the makefile to give the location
of libpng and zlib on your system.

Andreas Dilger <adilger@enel.ucalgary.ca>
http://www-mddsp.enel.ucalgary.ca/People/adilger/

Alexander Lehmann <lehmann@mathematik.th-darmstadt.de>
http://www.mathematik.th-darmstadt.de/~lehmann/

diff -c3 xv-3.10a/xvdial.c xvdial.c
*** xv-3.10a/xvdial.c	Tue Jan  3 14:20:31 1995
--- xvdial.c	Wed May 29 14:37:54 1996
***************
*** 41,60 ****
  
  
  /* local functions */
! static int  whereInDial     PARM((DIAL *, int, int));
! static void drawArrow       PARM((DIAL *));
! static void drawValStr      PARM((DIAL *));
! static void drawButt        PARM((DIAL *, int, int));
! static int  computeDialVal  PARM((DIAL *, int, int));
! static void dimDial         PARM((DIAL *));
  
  
  /***************************************************/
! void DCreate(dp, parent, x, y, w, h, minv, maxv, curv, page, 
  	          fg, bg, hi, lo, title, units)
  DIAL         *dp;
  Window        parent;
! int           x,y,w,h,minv,maxv,curv,page;
  unsigned long fg,bg,hi,lo;
  char         *title, *units;
  {
--- 41,61 ----
  
  
  /* local functions */
! static int    whereInDial     PARM((DIAL *, int, int));
! static void   drawArrow       PARM((DIAL *));
! static void   drawValStr      PARM((DIAL *));
! static void   drawButt        PARM((DIAL *, int, int));
! static double computeDialVal  PARM((DIAL *, int, int));
! static void   dimDial         PARM((DIAL *));
  
  
  /***************************************************/
! void DCreate(dp, parent, x, y, w, h, minv, maxv, curv, inc, page, 
  	          fg, bg, hi, lo, title, units)
  DIAL         *dp;
  Window        parent;
! int           x,y,w,h;
! double        minv,maxv,curv,inc,page;
  unsigned long fg,bg,hi,lo;
  char         *title, *units;
  {
***************
*** 98,115 ****
  				1,fg,bg);
    if (!dp->win) FatalError("can't create dial window");
  
!   DSetRange(dp, minv, maxv, curv, page);
    XSelectInput(theDisp, dp->win, ExposureMask | ButtonPressMask);
  }
  
  
  /***************************************************/
! void DSetRange(dp, minv, maxv, curv, page)
! DIAL *dp;
! int   minv, maxv, curv, page;
  {
    if (maxv<minv) maxv=minv;
!   dp->min = minv;    dp->max = maxv;    dp->page = page;
    dp->active =  (minv < maxv);
  
    DSetVal(dp, curv);
--- 99,116 ----
  				1,fg,bg);
    if (!dp->win) FatalError("can't create dial window");
  
!   DSetRange(dp, minv, maxv, curv, inc, page);
    XSelectInput(theDisp, dp->win, ExposureMask | ButtonPressMask);
  }
  
  
  /***************************************************/
! void DSetRange(dp, minv, maxv, curv, inc, page)
! DIAL   *dp;
! double  minv, maxv, curv, inc, page;
  {
    if (maxv<minv) maxv=minv;
!   dp->min = minv; dp->max = maxv; dp->inc = inc; dp->page = page;
    dp->active =  (minv < maxv);
  
    DSetVal(dp, curv);
***************
*** 118,125 ****
  
  /***************************************************/
  void DSetVal(dp, curv)
! DIAL *dp;
! int   curv;
  {
    RANGE(curv, dp->min, dp->max);   /* make sure curv is in-range */
  
--- 119,126 ----
  
  /***************************************************/
  void DSetVal(dp, curv)
! DIAL  *dp;
! double curv;
  {
    RANGE(curv, dp->min, dp->max);   /* make sure curv is in-range */
  
***************
*** 129,135 ****
    XSetForeground(theDisp, theGC, dp->bg); 
    drawArrow(dp);
  
!   dp->val = curv;
  
    /* draw new arrow and string */
    XSetForeground(theDisp, theGC, dp->fg);
--- 130,136 ----
    XSetForeground(theDisp, theGC, dp->bg); 
    drawArrow(dp);
  
!   dp->val = (double)((int)(curv / dp->inc + (curv > 0 ? 0.5 : -0.5))) * dp->inc;
  
    /* draw new arrow and string */
    XSetForeground(theDisp, theGC, dp->fg);
***************
*** 202,208 ****
  int mx,my;
  {
    Window       rW,cW;
!   int          rx,ry, x,y, ipos, pos, lit, i, origval;
    unsigned int mask;
  
    lit = 0;
--- 203,210 ----
  int mx,my;
  {
    Window       rW,cW;
!   int          rx, ry, x, y, ipos, pos, lit;
!   double       origval;
    unsigned int mask;
  
    lit = 0;
***************
*** 224,232 ****
    if (ipos != INDIAL) {
      drawButt(dp, ipos, 1);
      switch (ipos) {
!     case INCW1:  if (dp->val < dp->max) DSetVal(dp, dp->val+1); break;
      case INCW2:  if (dp->val < dp->max) DSetVal(dp, dp->val+dp->page); break;
!     case INCCW1: if (dp->val > dp->min) DSetVal(dp, dp->val-1); break;
      case INCCW2: if (dp->val > dp->min) DSetVal(dp, dp->val-dp->page); break;
      }
      if (dp->drawobj != NULL) (dp->drawobj)();  
--- 226,234 ----
    if (ipos != INDIAL) {
      drawButt(dp, ipos, 1);
      switch (ipos) {
!     case INCW1:  if (dp->val < dp->max) DSetVal(dp, dp->val+dp->inc);  break;
      case INCW2:  if (dp->val < dp->max) DSetVal(dp, dp->val+dp->page); break;
!     case INCCW1: if (dp->val > dp->min) DSetVal(dp, dp->val-dp->inc);  break;
      case INCCW2: if (dp->val > dp->min) DSetVal(dp, dp->val-dp->page); break;
      }
      if (dp->drawobj != NULL) (dp->drawobj)();  
***************
*** 235,242 ****
    }
  
    else { 
!     i = computeDialVal(dp, mx, my);
!     DSetVal(dp, i);
      if (dp->drawobj != NULL) (dp->drawobj)();  
    }
  
--- 237,245 ----
    }
  
    else { 
!     double v;
!     v = computeDialVal(dp, mx, my);
!     DSetVal(dp, v);
      if (dp->drawobj != NULL) (dp->drawobj)();  
    }
  
***************
*** 246,256 ****
      if (!(mask & Button1Mask)) break;    /* button released */
  
      if (ipos == INDIAL) {
!       int j;
!       i = computeDialVal(dp, x, y);
!       j = dp->val;
!       DSetVal(dp, i);
!       if (j != dp->val) {
  	/* track whatever dial controls */
  	if (dp->drawobj != NULL) (dp->drawobj)();  
        }
--- 249,259 ----
      if (!(mask & Button1Mask)) break;    /* button released */
  
      if (ipos == INDIAL) {
!       double v, w;
!       v = computeDialVal(dp, x, y);
!       w = dp->val;
!       DSetVal(dp, v);
!       if (w != dp->val) {
  	/* track whatever dial controls */
  	if (dp->drawobj != NULL) (dp->drawobj)();  
        }
***************
*** 266,276 ****
  
        if (lit) {
  	switch (ipos) {
! 	case INCW1:  if (dp->val < dp->max) DSetVal(dp, dp->val+1); 
  	             break;
  	case INCW2:  if (dp->val < dp->max) DSetVal(dp, dp->val+dp->page);
                       break;
! 	case INCCW1: if (dp->val > dp->min) DSetVal(dp, dp->val-1);
                       break;
  	case INCCW2: if (dp->val > dp->min) DSetVal(dp, dp->val-dp->page);
                       break;
--- 269,279 ----
  
        if (lit) {
  	switch (ipos) {
! 	case INCW1:  if (dp->val < dp->max) DSetVal(dp, dp->val+dp->inc); 
  	             break;
  	case INCW2:  if (dp->val < dp->max) DSetVal(dp, dp->val+dp->page);
                       break;
! 	case INCCW1: if (dp->val > dp->min) DSetVal(dp, dp->val-dp->inc);
                       break;
  	case INCCW2: if (dp->val > dp->min) DSetVal(dp, dp->val-dp->page);
                       break;
***************
*** 320,338 ****
  static void drawArrow(dp)
  DIAL *dp;
  {
!   int i, rad, cx, cy;
    XPoint arrow[4];
  
    rad = dp->rad;  cx = dp->cx;  cy = dp->cy;
  
    /* map pos (range minv..maxv) into degrees (range 240..-60) */
!   i = 240 + (-300 * (dp->val - dp->min)) / (dp->max - dp->min);
!   arrow[0].x = cx + (int) ((double) rad * .80 * cos(i * DEG2RAD));
!   arrow[0].y = cy - (int) ((double) rad * .80 * sin(i * DEG2RAD));
!   arrow[1].x = cx + (int) ((double) rad * .33 * cos((i+160) * DEG2RAD));
!   arrow[1].y = cy - (int) ((double) rad * .33 * sin((i+160) * DEG2RAD));
!   arrow[2].x = cx + (int) ((double) rad * .33 * cos((i-160) * DEG2RAD));
!   arrow[2].y = cy - (int) ((double) rad * .33 * sin((i-160) * DEG2RAD));
    arrow[3].x = arrow[0].x;
    arrow[3].y = arrow[0].y;
    XDrawLines(theDisp, dp->win, theGC, arrow, 4, CoordModeOrigin);
--- 323,342 ----
  static void drawArrow(dp)
  DIAL *dp;
  {
!   int rad, cx, cy;
!   double v;
    XPoint arrow[4];
  
    rad = dp->rad;  cx = dp->cx;  cy = dp->cy;
  
    /* map pos (range minv..maxv) into degrees (range 240..-60) */
!   v = 240 + (-300 * (dp->val - dp->min)) / (dp->max - dp->min);
!   arrow[0].x = cx + (int) ((double) rad * .80 * cos(v * DEG2RAD));
!   arrow[0].y = cy - (int) ((double) rad * .80 * sin(v * DEG2RAD));
!   arrow[1].x = cx + (int) ((double) rad * .33 * cos((v+160) * DEG2RAD));
!   arrow[1].y = cy - (int) ((double) rad * .33 * sin((v+160) * DEG2RAD));
!   arrow[2].x = cx + (int) ((double) rad * .33 * cos((v-160) * DEG2RAD));
!   arrow[2].y = cy - (int) ((double) rad * .33 * sin((v-160) * DEG2RAD));
    arrow[3].x = arrow[0].x;
    arrow[3].y = arrow[0].y;
    XDrawLines(theDisp, dp->win, theGC, arrow, 4, CoordModeOrigin);
***************
*** 343,365 ****
  static void drawValStr(dp)
  DIAL *dp;
  {
!   int  i, x1, x2;
    char foo[60], foo1[60];
  
    /* compute longest string necessary so we can right-align this thing */
!   sprintf(foo,"%d",dp->min);    x1 = strlen(foo);
!   sprintf(foo,"%d",dp->max);    x2 = strlen(foo);
    if (dp->min < 0 && dp->max > 0) x2++;   /* put '+' at beginning */
    i = x1;  if (x2>x1) i = x2;
    if (dp->units) i += strlen(dp->units);
  
!   if (dp->min < 0 && dp->max > 0) sprintf(foo,"%+d", dp->val);
!   else sprintf(foo,"%d", dp->val);
  
    if (dp->units) strcat(foo,dp->units);
    foo1[0] = '\0';
    if (strlen(foo) < (size_t) i) {
!     for (i = i - strlen(foo); i>0; i--) strcat(foo1," ");
    }
    strcat(foo1, foo);
  
--- 347,383 ----
  static void drawValStr(dp)
  DIAL *dp;
  {
!   int  tot, i, x1, x2;
    char foo[60], foo1[60];
  
    /* compute longest string necessary so we can right-align this thing */
!   sprintf(foo,"%d",(int)dp->min);    x1 = strlen(foo);
!   sprintf(foo,"%d",(int)dp->max);    x2 = strlen(foo);
    if (dp->min < 0 && dp->max > 0) x2++;   /* put '+' at beginning */
    i = x1;  if (x2>x1) i = x2;
    if (dp->units) i += strlen(dp->units);
  
!   sprintf(foo,"%g",dp->inc);   /* space for decimal values */
!   tot = i + strlen(foo) - 1;   /* Take away the 0 from the beginning */
! 
!   if (dp->min < 0.0 && dp->max > 0.0) sprintf(foo,"%+g", dp->val);
!   else sprintf(foo,"%g", dp->val);
! 
!   if (dp->inc < 1.0)
!   {
!     int j;
! 
!     if (dp->val == (double)((int)dp->val))
!       strcat(foo,".");
! 
!     for (j = strlen(foo); j < tot; j++)
!       strcat(foo,"0");
!   }
  
    if (dp->units) strcat(foo,dp->units);
    foo1[0] = '\0';
    if (strlen(foo) < (size_t) i) {
!     for (i-=strlen(foo);i>0;i--) strcat(foo1," ");
    }
    strcat(foo1, foo);
  
***************
*** 411,422 ****
  
  
  /***************************************************/
! static int computeDialVal(dp, x, y)
  DIAL *dp;
  int x, y;
  {
!   int dx, dy, val;
!   double angle;
  
    /* compute dx, dy (distance from cx, cy).  Note: +dy is *up* */
    dx = x - dp->cx;  dy = dp->cy - y;
--- 429,441 ----
  
  
  /***************************************************/
! static double computeDialVal(dp, x, y)
  DIAL *dp;
  int x, y;
  {
!   int dx, dy;
!  
!   double angle, val;
  
    /* compute dx, dy (distance from cx, cy).  Note: +dy is *up* */
    dx = x - dp->cx;  dy = dp->cy - y;
***************
*** 436,443 ****
    if (angle > 270.0) angle -= 360.0;
    if (angle < -90.0) angle += 360.0;
  
!   val = (int) ((dp->max - dp->min) * (240.0 - angle) / 300.0) + dp->min;
  
    return val;
  }
  
--- 455,464 ----
    if (angle > 270.0) angle -= 360.0;
    if (angle < -90.0) angle += 360.0;
  
!   val = ((dp->max - dp->min) * (240.0 - angle) / 300.0) + dp->min;
  
+   /* round value to be an even multiple of dp->inc */
+   val = (double)((int)(val / dp->inc + 0.5)) * dp->inc;
    return val;
  }
  
diff -c3 xv-3.10a/xvgam.c xvgam.c
*** xv-3.10a/xvgam.c	Fri Jan 13 12:51:14 1995
--- xvgam.c	Wed May 29 11:13:56 1996
***************
*** 265,275 ****
    BTCreate(&gbut[G_BRNDCOL], cmapF,  5 + 66 + 67 + 2, 189, 66, BUTTH, 
  	   "Random", infofg, infobg, hicol, locol);
  
!   DCreate(&rhDial, cmapF, 5, 215, 66, 100,   0,360,180, 5, 
  	  infofg, infobg, hicol, locol, "Hue", NULL);
!   DCreate(&gsDial, cmapF, 72, 215, 66, 100,  0,360,180, 5, 
  	  infofg, infobg, hicol, locol, "Sat.", NULL);
!   DCreate(&bvDial, cmapF, 139, 215, 66, 100,   0,360,180, 5, 
  	  infofg, infobg, hicol, locol, "Value", NULL);
  
    rhDial.drawobj = gsDial.drawobj = bvDial.drawobj = dragEditColor;
--- 265,275 ----
    BTCreate(&gbut[G_BRNDCOL], cmapF,  5 + 66 + 67 + 2, 189, 66, BUTTH, 
  	   "Random", infofg, infobg, hicol, locol);
  
!   DCreate(&rhDial, cmapF, 5, 215, 66, 100,   0.0, 360.0, 180.0, 1.0, 5.0, 
  	  infofg, infobg, hicol, locol, "Hue", NULL);
!   DCreate(&gsDial, cmapF, 72, 215, 66, 100,  0.0, 360.0, 180.0, 1.0, 5.0, 
  	  infofg, infobg, hicol, locol, "Sat.", NULL);
!   DCreate(&bvDial, cmapF, 139, 215, 66, 100, 0.0, 360.0, 180.0, 1.0, 5.0, 
  	  infofg, infobg, hicol, locol, "Value", NULL);
  
    rhDial.drawobj = gsDial.drawobj = bvDial.drawobj = dragEditColor;
***************
*** 359,365 ****
  
    srcHD.drawobj = dstHD.drawobj = whtHD.drawobj = dragHueDial;
  
!   DCreate(&satDial, hsvF, 100, 199, 100, 121, -100, 100, 0, 5, 
  	   infofg, infobg,hicol,locol, "Saturation", "%");
  
    hueRB = RBCreate(NULL, hsvF,  7, 153, "1", 
--- 359,365 ----
  
    srcHD.drawobj = dstHD.drawobj = whtHD.drawobj = dragHueDial;
  
!   DCreate(&satDial, hsvF, 100, 199, 100, 121, -100.0, 100.0, 0.0, 1.0, 5.0, 
  	   infofg, infobg,hicol,locol, "Saturation", "%");
  
    hueRB = RBCreate(NULL, hsvF,  7, 153, "1", 
***************
*** 722,728 ****
  
    if (whtHD.enabCB.val && whtHD.satval) hsvnonlinear++;
  
!   if (satDial.val != 0) hsvnonlinear++;
  
    /* check intensity graf */
    for (i=0; i<256 && intGraf.func[i]==i; i++);
--- 722,728 ----
  
    if (whtHD.enabCB.val && whtHD.satval) hsvnonlinear++;
  
!   if (satDial.val != 0.0) hsvnonlinear++;
  
    /* check intensity graf */
    for (i=0; i<256 && intGraf.func[i]==i; i++);
***************
*** 1291,1304 ****
      rgb2hsv(rcmap[editColor], gcmap[editColor], bcmap[editColor], &h, &s, &v);
      if (h<0) h = 0;
  
!     DSetVal(&rhDial, (int) h);
!     DSetVal(&gsDial, (int) (s*100));
!     DSetVal(&bvDial, (int) (v*100));
    }
    else {
!     DSetVal(&rhDial, rcmap[editColor]);
!     DSetVal(&gsDial, gcmap[editColor]);
!     DSetVal(&bvDial, bcmap[editColor]);
    }
  }
    
--- 1291,1304 ----
      rgb2hsv(rcmap[editColor], gcmap[editColor], bcmap[editColor], &h, &s, &v);
      if (h<0) h = 0;
  
!     DSetVal(&rhDial, h);
!     DSetVal(&gsDial, s*100);
!     DSetVal(&bvDial, v*100);
    }
    else {
!     DSetVal(&rhDial, (double)rcmap[editColor]);
!     DSetVal(&gsDial, (double)gcmap[editColor]);
!     DSetVal(&bvDial, (double)bcmap[editColor]);
    }
  }
    
***************
*** 1310,1325 ****
  
    if (hsvmode) {
      int rv, gv, bv;
!     hsv2rgb((double) rhDial.val, ((double) gsDial.val) / 100.0, 
! 	    ((double) bvDial.val) / 100.0, &rv, &gv, &bv);
      rcmap[editColor] = rv;
      gcmap[editColor] = gv;
      bcmap[editColor] = bv;
    }
    else {
!     rcmap[editColor] = rhDial.val;
!     gcmap[editColor] = gsDial.val;
!     bcmap[editColor] = bvDial.val;
    }
  }
  
--- 1310,1324 ----
  
    if (hsvmode) {
      int rv, gv, bv;
!     hsv2rgb(rhDial.val, gsDial.val / 100.0, bvDial.val / 100.0, &rv, &gv, &bv);
      rcmap[editColor] = rv;
      gcmap[editColor] = gv;
      bcmap[editColor] = bv;
    }
    else {
!     rcmap[editColor] = (int)rhDial.val;
!     gcmap[editColor] = (int)gsDial.val;
!     bcmap[editColor] = (int)bvDial.val;
    }
  }
  
***************
*** 1561,1569 ****
      gsDial.title = "Green";
      bvDial.title = "Blue";
  		   
!     DSetRange(&rhDial, 0, 255, rcmap[editColor], 16);
!     DSetRange(&gsDial, 0, 255, gcmap[editColor], 16);
!     DSetRange(&bvDial, 0, 255, bcmap[editColor], 16);
  
      XClearWindow(theDisp, rhDial.win);    DRedraw(&rhDial);
      XClearWindow(theDisp, gsDial.win);    DRedraw(&gsDial);
--- 1560,1568 ----
      gsDial.title = "Green";
      bvDial.title = "Blue";
  		   
!     DSetRange(&rhDial, 0.0, 255.0, (double)rcmap[editColor], 1.0, 16.0);
!     DSetRange(&gsDial, 0.0, 255.0, (double)gcmap[editColor], 1.0, 16.0);
!     DSetRange(&bvDial, 0.0, 255.0, (double)bcmap[editColor], 1.0, 16.0);
  
      XClearWindow(theDisp, rhDial.win);    DRedraw(&rhDial);
      XClearWindow(theDisp, gsDial.win);    DRedraw(&gsDial);
***************
*** 1581,1589 ****
  	    &h, &s, &v);
  
      if (h<0.0) h = 0.0;
!     DSetRange(&rhDial, 0, 360, (int) h, 5);
!     DSetRange(&gsDial, 0, 100, (int) (s*100), 5);
!     DSetRange(&bvDial, 0, 100, (int) (v*100), 5);
  
      XClearWindow(theDisp, rhDial.win);    DRedraw(&rhDial);
      XClearWindow(theDisp, gsDial.win);    DRedraw(&gsDial);
--- 1580,1588 ----
  	    &h, &s, &v);
  
      if (h<0.0) h = 0.0;
!     DSetRange(&rhDial, 0.0, 360.0,     h, 1.0, 5.0);
!     DSetRange(&gsDial, 0.0, 100.0, s*100, 1.0, 5.0);
!     DSetRange(&bvDial, 0.0, 100.0, v*100, 1.0, 5.0);
  
      XClearWindow(theDisp, rhDial.win);    DRedraw(&rhDial);
      XClearWindow(theDisp, gsDial.win);    DRedraw(&gsDial);
***************
*** 1891,1897 ****
      }
  
      /* apply satDial value to s */
!     s = s + ((double) satDial.val) / 100.0;
      if (s<0.0) s = 0.0;
      if (s>1.0) s = 1.0;
  
--- 1890,1896 ----
      }
  
      /* apply satDial value to s */
!     s = s + satDial.val / 100.0;
      if (s<0.0) s = 0.0;
      if (s>1.0) s = 1.0;
  
***************
*** 2007,2013 ****
  
    gs->hueRBnum = RBWhich(hueRB);
  
!   gs->satval = satDial.val;
    GetGrafState(&intGraf,&gs->istate);
    GetGrafState(&rGraf,  &gs->rstate);
    GetGrafState(&gGraf,  &gs->gstate);
--- 2006,2012 ----
  
    gs->hueRBnum = RBWhich(hueRB);
  
!   gs->satval = (int)satDial.val;
    GetGrafState(&intGraf,&gs->istate);
    GetGrafState(&rGraf,  &gs->rstate);
    GetGrafState(&gGraf,  &gs->gstate);
***************
*** 2064,2071 ****
      changed++;
    }
      
!   if (gs->satval != satDial.val) {
!     DSetVal(&satDial,gs->satval);
      changed++;
    }
  
--- 2063,2070 ----
      changed++;
    }
      
!   if (gs->satval != (int)satDial.val) {
!     DSetVal(&satDial,(double)gs->satval);
      changed++;
    }
  
***************
*** 3200,3206 ****
  
    if (whtHD.enabCB.val && whtHD.satval) hsvmod++;
  
!   if (satDial.val != 0) hsvmod++;
  
    /* check intensity graf */
    for (i=0; i<256; i++) {
--- 3199,3205 ----
  
    if (whtHD.enabCB.val && whtHD.satval) hsvmod++;
  
!   if (satDial.val != 0.0) hsvmod++;
  
    /* check intensity graf */
    for (i=0; i<256; i++) {
***************
*** 3284,3290 ****
        }
  
        /* apply satDial value to s */
!       s = s + satDial.val;
        if (s<  0) s =   0;
        if (s>100) s = 100;
  
--- 3283,3289 ----
        }
  
        /* apply satDial value to s */
!       s = s + (int)satDial.val;
        if (s<  0) s =   0;
        if (s>100) s = 100;
  
diff -c3 xv-3.10a/xvjpeg.c xvjpeg.c
*** xv-3.10a/xvjpeg.c	Thu Jan  5 01:17:13 1995
--- xvjpeg.c	Wed May 29 11:15:02 1996
***************
*** 87,96 ****
    
    XSelectInput(theDisp, jpegW, ExposureMask | ButtonPressMask | KeyPressMask);
    
!   DCreate(&qDial, jpegW, 10, 10, 80, 100, 1, 100, 75, 5, 
  	  infofg, infobg, hicol, locol, "Quality", "%");
    
!   DCreate(&smDial, jpegW, 120, 10, 80, 100, 0, 100, 0, 5, 
  	  infofg, infobg, hicol, locol, "Smoothing", "%");
    
    BTCreate(&jbut[J_BOK], jpegW, JWIDE-180-1, JHIGH-10-BUTTH-1, 80, BUTTH, 
--- 85,94 ----
    
    XSelectInput(theDisp, jpegW, ExposureMask | ButtonPressMask | KeyPressMask);
    
!   DCreate(&qDial, jpegW, 10, 10, 80, 100, 1.0, 100.0, 75.0, 1.0, 5.0, 
  	  infofg, infobg, hicol, locol, "Quality", "%");
    
!   DCreate(&smDial, jpegW, 120, 10, 80, 100, 0.0, 100.0, 0.0, 1.0, 5.0, 
  	  infofg, infobg, hicol, locol, "Smoothing", "%");
    
    BTCreate(&jbut[J_BOK], jpegW, JWIDE-180-1, JHIGH-10-BUTTH-1, 80, BUTTH, 
***************
*** 759,766 ****
  
  
    jpeg_set_defaults(&cinfo);
!   jpeg_set_quality(&cinfo, qDial.val, TRUE);
!   cinfo.smoothing_factor = smDial.val;
  
  
    jpeg_start_compress(&cinfo, TRUE);
--- 757,764 ----
  
  
    jpeg_set_defaults(&cinfo);
!   jpeg_set_quality(&cinfo, (int)qDial.val, TRUE);
!   cinfo.smoothing_factor = (int)smDial.val;
  
  
    jpeg_start_compress(&cinfo, TRUE);
***************
*** 769,775 ****
    /*** COMMENT HANDLING ***/
  
    sprintf(xvcmt, "%sXV %s  Quality = %d, Smoothing = %d\n",
! 	  CREATOR_STR, REVDATE, qDial.val, smDial.val);
    
    if (picComments) {   /* append XV comment */
      char *sp, *sp1;  int done;
--- 767,773 ----
    /*** COMMENT HANDLING ***/
  
    sprintf(xvcmt, "%sXV %s  Quality = %d, Smoothing = %d\n",
! 	  CREATOR_STR, REVDATE, (int)qDial.val, (int)smDial.val);
    
    if (picComments) {   /* append XV comment */
      char *sp, *sp1;  int done;
diff -c3 xv-3.10a/xvmisc.c xvmisc.c
*** xv-3.10a/xvmisc.c	Fri Jan 13 16:41:34 1995
--- xvmisc.c	Tue May 28 14:57:52 1996
***************
*** 520,525 ****
--- 520,529 ----
      if (tiffW) XDestroyWindow(theDisp, tiffW);
  #endif
  
+ #ifdef HAVE_PNG
+     if (pngW)  XDestroyWindow(theDisp, pngW);
+ #endif
+ 
      /* if NOT using stdcmap for images, free stdcmap */
      if (colorMapMode != CM_STDCMAP) { 
        int j;
***************
*** 715,720 ****
--- 719,728 ----
    
  #ifdef HAVE_TIFF
    if (tiffW) XDefineCursor(theDisp, tiffW, otherc);
+ #endif
+ 
+ #ifdef HAVE_PNG
+   if (pngW)  XDefineCursor(theDisp, pngW, otherc);
  #endif
  }
  
diff -c3 xv-3.10a/xvpopup.c xvpopup.c
*** xv-3.10a/xvpopup.c	Thu Jan 19 11:09:31 1995
--- xvpopup.c	Wed May 29 11:18:43 1996
***************
*** 200,213 ****
      
      if (!padHaveDooDads) {
        DCreate(&padWDial, popW, 16,      puhigh-16-100-1,75,100,
! 	      1, 2048, pWIDE, 10,
  	      infofg, infobg, hicol, locol, "Width", NULL);
        DCreate(&padHDial, popW, 16+1+75, puhigh-16-100-1,75,100,
! 	      1, 2048, pHIGH, 10,
  	      infofg, infobg, hicol, locol, "Height", NULL);
  
        DCreate(&padODial, popW, 16+1+75+75+9, puhigh-16-100-1,75,100,
! 	      0, 100, 100, 10,
  	      infofg, infobg, hicol, locol, "Opaque", NULL);
  
        MBCreate(&padMthdMB, popW, 100-2+44, 10, 140, 19, NULL,
--- 200,213 ----
      
      if (!padHaveDooDads) {
        DCreate(&padWDial, popW, 16,      puhigh-16-100-1,75,100,
! 	      1.0, 2048.0, (double)pWIDE, 1.0, 10.0,
  	      infofg, infobg, hicol, locol, "Width", NULL);
        DCreate(&padHDial, popW, 16+1+75, puhigh-16-100-1,75,100,
! 	      1.0, 2048.0, (double)pHIGH, 1.0, 10.0,
  	      infofg, infobg, hicol, locol, "Height", NULL);
  
        DCreate(&padODial, popW, 16+1+75+75+9, puhigh-16-100-1,75,100,
! 	      0.0, 100.0, 100.0, 1.0, 10.0,
  	      infofg, infobg, hicol, locol, "Opaque", NULL);
  
        MBCreate(&padMthdMB, popW, 100-2+44, 10, 140, 19, NULL,
***************
*** 258,266 ****
    else if (poptyp == ISPAD) {
      BTSetActive(&bts[0], (int) strlen(gsBuf));
      i = pWIDE * 3;  RANGE(i,2048,9999);  
!     DSetRange(&padWDial, 1, i, padWDial.val, 10);
      i = pHIGH * 3;  RANGE(i,2048,9999);  
!     DSetRange(&padHDial, 1, i, padHDial.val, 10);
  
      DSetActive(&padWDial, (padMode!=PAD_LOAD));  /* DSetRange activates dial */
      DSetActive(&padHDial, (padMode!=PAD_LOAD));
--- 258,266 ----
    else if (poptyp == ISPAD) {
      BTSetActive(&bts[0], (int) strlen(gsBuf));
      i = pWIDE * 3;  RANGE(i,2048,9999);  
!     DSetRange(&padWDial, 1.0, (double)i, padWDial.val, 1.0, 10.0);
      i = pHIGH * 3;  RANGE(i,2048,9999);  
!     DSetRange(&padHDial, 1.0, (double)i, padHDial.val, 1.0, 10.0);
  
      DSetActive(&padWDial, (padMode!=PAD_LOAD));  /* DSetRange activates dial */
      DSetActive(&padHDial, (padMode!=PAD_LOAD));
***************
*** 465,473 ****
    changedGSBuf();      /* careful!  popW doesn't exist yet! */
  
    if (padHaveDooDads) { 
!     oldW = padWDial.val;  
!     oldH = padHDial.val;
!     oldO = padODial.val;
    }
    else { oldW = pWIDE;  oldH = pHIGH;  oldO = 100; }
  
--- 465,473 ----
    changedGSBuf();      /* careful!  popW doesn't exist yet! */
  
    if (padHaveDooDads) { 
!     oldW = (int)padWDial.val;  
!     oldH = (int)padHDial.val;
!     oldO = (int)padODial.val;
    }
    else { oldW = pWIDE;  oldH = pHIGH;  oldO = 100; }
  
***************
*** 486,494 ****
    }
  
    if (rv == 1) {   /* cancelled:  restore normal values */
!     DSetVal(&padWDial, oldW);
!     DSetVal(&padHDial, oldH);
!     DSetVal(&padODial, oldO);
    }
  
    XUnmapWindow(theDisp, padWDial.win);
--- 486,494 ----
    }
  
    if (rv == 1) {   /* cancelled:  restore normal values */
!     DSetVal(&padWDial, (double)oldW);
!     DSetVal(&padHDial, (double)oldH);
!     DSetVal(&padODial, (double)oldO);
    }
  
    XUnmapWindow(theDisp, padWDial.win);
***************
*** 498,506 ****
    /* load up return values */
    *pMode   = padMode;  
    *pStr    = padBuf;  
!   *pWide   = padWDial.val;
!   *pHigh   = padHDial.val;
!   *pOpaque = padODial.val;
    *pOmode  = padOMode;
  
    return rv;
--- 498,506 ----
    /* load up return values */
    *pMode   = padMode;  
    *pStr    = padBuf;  
!   *pWide   = (int)padWDial.val;
!   *pHigh   = (int)padHDial.val;
!   *pOpaque = (int)padODial.val;
    *pOmode  = padOMode;
  
    return rv;
***************
*** 972,979 ****
    else if (popUp == ISPAD) {
      if (PTINRECT(x, y, padDButt.x, padDButt.y, padDButt.w, padDButt.h)) {
        if (BTTrack(&padDButt)) {
! 	DSetVal(&padWDial, pWIDE);
! 	DSetVal(&padHDial, pHIGH);
        }
      }
  
--- 970,977 ----
    else if (popUp == ISPAD) {
      if (PTINRECT(x, y, padDButt.x, padDButt.y, padDButt.w, padDButt.h)) {
        if (BTTrack(&padDButt)) {
! 	DSetVal(&padWDial, (double)pWIDE);
! 	DSetVal(&padHDial, (double)pHIGH);
        }
      }
  
diff -c3 xv-3.10a/xvps.c xvps.c
*** xv-3.10a/xvps.c	Thu Dec 22 15:34:42 1994
--- xvps.c	Wed May 29 11:04:28 1996
***************
*** 139,147 ****
    CBCreate(&encapsCB, psW, 240, 7, "preview", infofg, infobg, hicol, locol);
    CBCreate(&pscompCB, psW, 331, 7, "compress", infofg, infobg, hicol, locol);
  
!   DCreate(&xsDial, psW, 240, 30, 80, 100, 10, 800, 100, 5, 
  	  infofg, infobg, hicol, locol, "Width", "%");
!   DCreate(&ysDial, psW, 331, 30, 80, 100, 10, 800, 100, 5, 
  	  infofg, infobg, hicol, locol, "Height", "%");
    xsDial.drawobj = changedScale;
    ysDial.drawobj = changedScale;
--- 139,147 ----
    CBCreate(&encapsCB, psW, 240, 7, "preview", infofg, infobg, hicol, locol);
    CBCreate(&pscompCB, psW, 331, 7, "compress", infofg, infobg, hicol, locol);
  
!   DCreate(&xsDial, psW, 240, 30, 80, 100, 10.0, 800.0, 100.0, 0.5, 5.0, 
  	  infofg, infobg, hicol, locol, "Width", "%");
!   DCreate(&ysDial, psW, 331, 30, 80, 100, 10.0, 800.0, 100.0, 0.5, 5.0, 
  	  infofg, infobg, hicol, locol, "Height", "%");
    xsDial.drawobj = changedScale;
    ysDial.drawobj = changedScale;
***************
*** 236,245 ****
  
    if (rd_int("psres")) {             /* xv.psres:  default paper resolution */
      if (def_int >= 10 && def_int <= 720) {
!       int i = (int) ((PIX2INCH * 100) / def_int);
  
!       DSetVal(&xsDial, i);
!       DSetVal(&ysDial, i);
      }
    }
  
--- 236,245 ----
  
    if (rd_int("psres")) {             /* xv.psres:  default paper resolution */
      if (def_int >= 10 && def_int <= 720) {
!       double v = (PIX2INCH * 100) / def_int;
  
!       DSetVal(&xsDial, v);
!       DSetVal(&ysDial, v);
      }
    }
  
***************
*** 836,842 ****
    if (scx < scy) { sz_iny = h * scx; }
              else { sz_inx = w * scy; }
  
!   DSetVal(&xsDial, (int) ((100 * (sz_inx * PIX2INCH) / w) + .5));
    DSetVal(&ysDial, xsDial.val);
  
    sz_inx = (double) w / PIX2INCH * (xsDial.val / 100.0);  
--- 836,842 ----
    if (scx < scy) { sz_iny = h * scx; }
              else { sz_inx = w * scy; }
  
!   DSetVal(&xsDial, 100 * (sz_inx * PIX2INCH) / w);
    DSetVal(&ysDial, xsDial.val);
  
    sz_inx = (double) w / PIX2INCH * (xsDial.val / 100.0);  
