Article View: alt.graphics.pixutils
Article #714More Patches for 'Xv'.
From: Matthew Stier - Sun Visualizatio...
Date: Fri, 08 Nov 1991 20:07
Date: Fri, 08 Nov 1991 20:07
983 lines
33137 bytes
33137 bytes
Here are some more patches to 'Xv' patchlevel 3.
These patches are the work of Tom Lane (Tom.Lane@G.GP.CS.CMU.edu). I've just
taken the liberty (at his suggestion) of packaging them in the same format
as the six other patches I've released.
These patches, like the other six, have been tested against the
'Xv' patchlevel 3 sources on export.lcs.mit.edu
(export.lcs.mit.edu:/contrib/xv.pl3.tar.Z).
Note 1: John Bradley (bradley@cis.upenn.edu) is the author of 'Xv'.
He will be releasing a new version of 'Xv' in a few weeks. These patches
are simply for those who want to improve on what is currently available.
Note 2: These patches, like the six previous ones are totally independent
of each other. No patch, amoungst this set of nine, requires any of the
others to be installed.
Note 3: Note 2 even applies to xv.patch.3f.jpeg. If you do not wish to
view jpeg (.jpg) files, or cannot obtain the jpeg source from uunet.uu.net,
(uunet.uu.net:/graphics/jpeg/jpegsrc.v1.tar.Z) do not apply the patch
'xv.patch.3f.jpeg'.
Note 4: I'm re-releasing the patch xv.patch.3d.bfc. Larry W. Virden
(lwv27@cas.org) caught a one charater bug in xvgam.c. (The function call
on line 623 should be to 'XvFreeColors()' not 'XFreeColors'.)
--
Matthew Lee Stier |
Sun Microsystems --- RTP, NC 27709-3447 | "Wisconsin Escapee"
Email: matthew.stier@East.Sun.COM |
Phone: (919) 469-8300 fax: (919) 460-8355 |
#!/bin/sh
# This is a shell archive (produced by shar 3.49)
# To extract the files from this archive, save it to a file, remove
# everything above the "!/bin/sh" line above, and type "sh file_name".
#
# made 11/08/1991 19:30 UTC by matthew@superdave
# Source directory /auto/home/matthew/src/X11/Xv
#
# existing files will NOT be overwritten unless -c is specified
#
# This shar contains:
# length mode name
# ------ ---------- ------------------------------------------
# 5972 -rw-r--r-- xv.patch.3d.bfc
# 3921 -rw-r--r-- xv.patch.3g.hpux
# 10009 -rw-r--r-- xv.patch.3h.24to8
# 7275 -rw-r--r-- xv.patch.3i.cs
#
# ============= xv.patch.3d.bfc ==============
if test -f 'xv.patch.3d.bfc' -a X"$1" != X"-c"; then
echo 'x - skipping xv.patch.3d.bfc (File already exists)'
else
echo 'x - extracting xv.patch.3d.bfc (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'xv.patch.3d.bfc' &&
This is a patch to get around the XFreeColors bug in some Xservers.
It simple causes an alternate ErrorHandler to be installed during the
'XFreeColors()' function call. The original error handler is reinstalled
after the function call, incase there are other problems.
X
Note: I'd like to put a check in 'XvErrorHandler()' to make sure it was
an X_FreeColors error, and have it report all other errors.
--
Matthew Lee Stier |
Sun Microsystems --- RTP, NC 27709-3447 | "Wisconsin Escapee"
Email: matthew.stier@East.Sun.COM |
Phone: (919) 469-8300 fax: (919) 460-8355 |
X
*** /dev/null Wed Nov 6 21:42:01 1991
--- README.3D.BFC Wed Nov 6 22:15:51 1991
***************
*** 0 ****
--- 1,13 ----
+ This is a patch to get around the XFreeColors bug in some Xservers.
+ It simple causes an alternate ErrorHandler to be installed during the
+ 'XFreeColors()' function call. The original error handler is reinstalled
+ after the function call, incase there are other problems.
+
+ Note: I'd like to put a check in 'XvErrorHandler()' to make sure it was
+ an X_FreeColors error, and have it report all other errors.
+ --
+ Matthew Lee Stier |
+ Sun Microsystems --- RTP, NC 27709-3447 | "Wisconsin Escapee"
+ Email: matthew.stier@East.Sun.COM |
+ Phone: (919) 469-8300 fax: (919) 460-8355 |
+
*** xvgam.c.orig Wed Nov 6 10:17:24 1991
--- xvgam.c Wed Nov 6 12:36:15 1991
***************
*** 620,640 ****
X LocalCmap = 0;
X }
X else {
! if (!brokeFreeCols) {
! for (i=0; i<nfcols; i++)
! XFreeColors(theDisp, theCmap, &freecols[i], 1, 0L);
! }
! else {
! for (i=0; i<nfcols; i++) {
! int j;
! for (j=0; j<i; j++) {
! if (freecols[i] == freecols[j]) /* already been freed once */
! break;
! }
! if (j==i) /* wasn't found in already-freed list */
! XFreeColors(theDisp, theCmap, &freecols[i], 1, 0L);
! }
! }
X
X if (nfcols) {
X XFlush(theDisp); /* just to make sure they're all freed right now... */
--- 620,626 ----
X LocalCmap = 0;
X }
X else {
! XvFreeColors(theDisp, theCmap, freecols, 1, 0L, nfcols);
X
X if (nfcols) {
X XFlush(theDisp); /* just to make sure they're all freed right now... */
*** docs/xv.man.orig Wed Nov 6 12:16:19 1991
--- docs/xv.man Wed Nov 6 12:16:36 1991
***************
*** 783,795 ****
X to 'abort' the current picture without waiting the full specified time by
X using the 'Next' command. (Resource name: <none>)
X .PP
- .IP \fB\-bfc\fP 12
- Toggles the 'color freeing behavior'. If you experience X Protocol Errors
- when applying gamma corrections, or when loading multiple images, try
- using this option. Normally, this option turns on some workarounds for
- broken X servers, but if \fIxv\fP was built with the workarounds ON by
- default, this option will turn them OFF. (Resource name:
- brokeFreeCols. Type: boolean)
X
X .SH SHORTCUTS
X Commands and their keyboard equivalents:
--- 783,788 ----
*** xv.c.orig Thu Nov 29 13:44:53 1990
--- xv.c Wed Nov 6 23:19:04 1991
***************
*** 99,99 ****
--- 99,100 ----
X static int rd_flag();
+ static int XvErrorHandler();
***************
*** 160,167 ****
X
- #ifdef BROKEFREECOLS
- brokeFreeCols = 1;
- #else
- brokeFreeCols = 0;
- #endif
-
X defaspect = normaspect = 1.0;
--- 161,162 ----
***************
*** 212,214 ****
X if (rd_int ("borderWidth")) bwidth = def_int;
- if (rd_flag("brokeFreeCols")) brokeFreeCols = def_int;
X if (rd_flag("centerPic")) centerpic = def_int;
--- 207,208 ----
***************
*** 296,300 ****
X
- else if (!strncmp(argv[i],"-bf",3)) /* brokeFreeCols */
- brokeFreeCols = !brokeFreeCols;
-
X else if (!strncmp(argv[i],"-bg",3)) /* background color */
--- 290,291 ----
***************
*** 962,977 ****
X }
- else if (!brokeFreeCols) {
- for (i=0; i<nfcols; i++)
- XFreeColors(theDisp, theCmap, &freecols[i], 1, 0L);
- }
X else {
! for (i=0; i<nfcols; i++) {
! int j;
! for (j=0; j<i; j++) {
! if (freecols[i] == freecols[j]) /* already been freed once */
! break;
! }
! if (j==i) /* wasn't found in already-freed list */
! XFreeColors(theDisp, theCmap, &freecols[i], 1, 0L);
! }
X }
--- 953,956 ----
X }
X else {
! XvFreeColors(theDisp, theCmap, freecols, 1, 0L, nfcols);
X }
***************
*** 2238,2240 ****
--- 2217,2246 ----
X else return 0;
X }
X
+ void XvFreeColors(display, colormap, pixels, npixels, planes, nfcols)
+ Display * display;
+ Colormap colormap;
+ unsigned long * pixels;
+ int npixels;
+ unsigned long planes;
+ int nfcols;
+ {
+ int i;
+
+ XSetErrorHandler(XvErrorHandler); /* Handle X_FreeColors error messages */
+ for (i=0; i<nfcols; i++)
+ XFreeColors(display, colormap, &pixels[i], npixels, planes);
+ XSync(theDisp, False); /* Sync the display so that there won't be */
+ XSetErrorHandler(0); /* problems restoring the default error handler */
+ }
+
+ static int XvErrorHandler(display, err)
+ Display *display;
+ XErrorEvent *err;
+ {
+ /*
+ * What should be done here? Probably a check for request code 88
+ * And a call to the default error handle under all other errors
+ */
+ }
+
*** xv.h.orig Thu Nov 29 13:45:35 1990
--- xv.h Wed Nov 6 23:21:21 1991
***************
*** 372,374 ****
X rwthistime, /* true if we DID use R/W color cells */
- brokeFreeCols, /* true if server has broken XFreeColors */
X fish, /* turn on annoying fish */
--- 372,373 ----
***************
*** 430,431 ****
--- 429,431 ----
X void MakeRootPic(void);
+ void XvFreeColors(Display*, Colormap, unsigned long*, int, unsigned long, int);
X
***************
*** 572,573 ****
--- 572,574 ----
X void MakeRootPic();
+ void XvFreeColors();
X
SHAR_EOF
chmod 0644 xv.patch.3d.bfc ||
echo 'restore of xv.patch.3d.bfc failed'
Wc_c="`wc -c < 'xv.patch.3d.bfc'`"
test 5972 -eq "$Wc_c" ||
echo 'xv.patch.3d.bfc: original size 5972, current size' "$Wc_c"
fi
# ============= xv.patch.3g.hpux ==============
if test -f 'xv.patch.3g.hpux' -a X"$1" != X"-c"; then
echo 'x - skipping xv.patch.3g.hpux (File already exists)'
else
echo 'x - extracting xv.patch.3g.hpux (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'xv.patch.3g.hpux' &&
*** /dev/null Fri Nov 8 12:42:01 1991
--- README.3G.HPUX Fri Nov 8 12:51:48 1991
***************
*** 0 ****
--- 1,32 ----
+ Date: Thu, 18 Jul 91 11:39:19 EDT
+ Subject: XV patches
+ From: Tom.Lane@G.GP.CS.CMU.edu
+ To: bradley@cis.upenn.edu
+
+ Hi,
+ I just spent some time bringing up XV patchlevel 3 on an HPUX machine.
+ (I was using the original release, which was quite useful despite its
+ tendency to coredump. The new version seems a lot solider, and has some
+ nice additional features --- thanks!) Attached are some diffs that you
+ may find useful. They fall into three classes:
+
+ 1. I had to make several changes to get the code to compile; for example,
+ there are still a couple of #ifdef SYSV's floating around, which should be
+ #ifdef SVR4. The changes given below for xv.c, xv.h, xvdir.c fix these.
+ With the patches as given, you must add -DHPUX to the UNIX macro in the
+ Makefile; it might be worth adding a note about that to Makefile.std.
+ At least in HPUX 7.0, "-lV3" is also needed in LIBS.
+ Note: there is still one remaining reference to SYSV, in xvdir.c. I left
+ that alone because HPUX has lstat(). You might want to make that code read
+ "(defined(SVR4) & !defined(HPUX))".
+ One particularly nasty bug is the missing */ in xv.h's definition of
+ RELEASE_SIG; in gcc, at least, this comments out the definition of PAUSE_SIG.
+
+ 2. (contents deleted, see patch xv.patch.3h.24to8)
+
+ 3. (contents deleted, see patch xv.patch.3i.cs)
+
+ Hope these patches are of use. I think xv is a great program.
+ tom lane
+ Internet: tgl@cs.cmu.edu BITNET: tgl%cs.cmu.edu@cmuccvma
+
*** old/xv.c Wed Jul 17 11:57:18 1991
--- xv.c Wed Jul 17 12:47:37 1991
***************
*** 121,127 ****
X /*** variable Initialization ***/
X /*****************************************************/
X
! #ifdef SYSV
X getcwd(initpath, sizeof(initpath));
X #else
X getwd(initpath);
--- 121,127 ----
X /*** variable Initialization ***/
X /*****************************************************/
X
! #ifdef SVR4
X getcwd(initpath, sizeof(initpath));
X #else
X getwd(initpath);
*** old/xv.h Thu Nov 29 13:45:35 1990
--- xv.h Thu Jul 18 10:47:56 1991
***************
*** 68,73 ****
--- 68,74 ----
X #ifndef sgi /* silicon graphics doesn't have timeb.h */
X #include <sys/timeb.h>
X #endif
+ #undef SIGCHLD
X #include <signal.h>
X #if defined(sco) && !defined(NOTIMER)
X #include <sys/itimer.h>
***************
*** 78,83 ****
--- 79,85 ----
X #endif
X
X #ifdef NEEDSDIR
+ #ifndef HPUX
X #ifdef sco
X #include <sys/ndir.h>
X #define lstat stat
***************
*** 86,91 ****
--- 88,94 ----
X #include <sys/dir.h>
X #endif /* ATT */
X #endif /* sco */
+ #endif /* not HPUX */
X #include <sys/param.h>
X #include <sys/stat.h>
X #ifdef DIRENT
***************
*** 100,106 ****
X /* signal macros */
X #ifdef SVR4
X #define HOLD_SIG sighold(SIGALRM) /* block ALRM sig from occurring */
! #define RELEASE_SIG sigrelse(SIGALRM) /*
X #define PAUSE_SIG sigpause(SIGALRM) /* sleep until ALRM signal */
X #else
X #define HOLD_SIG sigblock(sigmask(SIGALRM))
--- 103,109 ----
X /* signal macros */
X #ifdef SVR4
X #define HOLD_SIG sighold(SIGALRM) /* block ALRM sig from occurring */
! #define RELEASE_SIG sigrelse(SIGALRM) /* */
X #define PAUSE_SIG sigpause(SIGALRM) /* sleep until ALRM signal */
X #else
X #define HOLD_SIG sigblock(sigmask(SIGALRM))
X
*** old/xvdir.c Thu Nov 29 12:46:25 1990
--- xvdir.c Wed Jul 17 12:47:45 1991
***************
*** 336,342 ****
X
X numdirnames = 0;
X
! #ifdef SYSV
X getcwd(path, sizeof(path));
X #else
X getwd(path);
--- 336,342 ----
X
X numdirnames = 0;
X
! #ifdef SVR4
X getcwd(path, sizeof(path));
X #else
X getwd(path);
X
--
X tom lane
Internet: tgl@cs.cmu.edu BITNET: tgl%cs.cmu.edu@cmuccvma
SHAR_EOF
chmod 0644 xv.patch.3g.hpux ||
echo 'restore of xv.patch.3g.hpux failed'
Wc_c="`wc -c < 'xv.patch.3g.hpux'`"
test 3921 -eq "$Wc_c" ||
echo 'xv.patch.3g.hpux: original size 3921, current size' "$Wc_c"
fi
# ============= xv.patch.3h.24to8 ==============
if test -f 'xv.patch.3h.24to8' -a X"$1" != X"-c"; then
echo 'x - skipping xv.patch.3h.24to8 (File already exists)'
else
echo 'x - extracting xv.patch.3h.24to8 (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'xv.patch.3h.24to8' &&
*** /dev/null Fri Nov 8 12:42:01 1991
--- README.3H.24TO8 Fri Nov 8 12:53:24 1991
***************
*** 0 ****
--- 1,29 ----
+ Date: Thu, 18 Jul 91 11:39:19 EDT
+ Subject: XV patches
+ From: Tom.Lane@G.GP.CS.CMU.edu
+ To: bradley@cis.upenn.edu
+
+ Hi,
+ I just spent some time bringing up XV patchlevel 3 on an HPUX machine.
+ (I was using the original release, which was quite useful despite its
+ tendency to coredump. The new version seems a lot solider, and has some
+ nice additional features --- thanks!) Attached are some diffs that you
+ may find useful. They fall into three classes:
+
+ 1. (content deleted, see xv.patches.3g.hpux)
+
+ 2. Neither patchlevel 3 nor the original did real well on color conversion
+ in my opinion. In particular, "quick" 24-to-8-bit conversion consistently
+ produces a too-white image. With the new version installed, I got motivated
+ to look into this, and found that the code wasn't computing the errors for
+ F-S diffusion correctly. Furthermore, there are several places where
+ boundary conditions and roundoff are treated sloppily. The changes given
+ below for xv24to8.c fix this.
+
+ 3. (content deleted, see xv.patches.3i.????)
+
+ Hope these patches are of use. I think xv is a great program.
+ tom lane
+
+ Internet: tgl@cs.cmu.edu BITNET: tgl%cs.cmu.edu@cmuccvma
+
*** old/xv24to8.c Thu Nov 29 12:46:21 1990
--- xv24to8.c Wed Jul 17 20:14:25 1991
***************
*** 73,81 ****
X static int Quick24to8();
X static int QuickCheck();
X
! static byte tbl1[256], /* tables used in F-S Dithering */
X tbl3[256], /* contain i/16, 3i/16, 5i/16, 7i/16, */
! tbl5[256], /* (i=0-255) respectively */
X tbl7[256];
X
X
--- 73,81 ----
X static int Quick24to8();
X static int QuickCheck();
X
! static int tbl1[256], /* tables used in F-S Dithering */
X tbl3[256], /* contain i/16, 3i/16, 5i/16, 7i/16, */
! tbl5[256], /* (i=-128..127) respectively */
X tbl7[256];
X
X
***************
*** 508,516 ****
X byte *rp,*gp,*bp;
X /*******************************/
X {
! *rp = ((ptr->rmin + ptr->rmax) << (COLOR_DEPTH - B_DEPTH)) / 2;
! *gp = ((ptr->gmin + ptr->gmax) << (COLOR_DEPTH - B_DEPTH)) / 2;
! *bp = ((ptr->bmin + ptr->bmax) << (COLOR_DEPTH - B_DEPTH)) / 2;
X }
X
X
--- 508,517 ----
X byte *rp,*gp,*bp;
X /*******************************/
X {
! /* +1 ensures that color represents the middle of the box */
! *rp = ((ptr->rmin + ptr->rmax + 1) << (COLOR_DEPTH - B_DEPTH)) / 2;
! *gp = ((ptr->gmin + ptr->gmax + 1) << (COLOR_DEPTH - B_DEPTH)) / 2;
! *bp = ((ptr->bmin + ptr->bmax + 1) << (COLOR_DEPTH - B_DEPTH)) / 2;
X }
X
X
***************
*** 674,680 ****
X int *thisline, *nextline, *tmpptr;
X int r1, g1, b1, r2, g2, b2;
X int i, j, imax, jmax, oval;
! byte *inptr, *outptr, *tmpbptr;
X int lastline, lastpixel;
X
X imax = HIGH - 1;
--- 675,681 ----
X int *thisline, *nextline, *tmpptr;
X int r1, g1, b1, r2, g2, b2;
X int i, j, imax, jmax, oval;
! byte *inptr, *outptr;
X int lastline, lastpixel;
X
X imax = HIGH - 1;
***************
*** 694,701 ****
X outptr = (byte *) pic;
X
X /* get first line of picture */
! for (j=WIDE * 3, tmpptr=nextline, tmpbptr=inptr; j; j--)
! *tmpptr++ = (int) *tmpbptr++;
X
X for (i=0; i<HIGH; i++) {
X /* swap thisline and nextline */
--- 695,702 ----
X outptr = (byte *) pic;
X
X /* get first line of picture */
! for (j=WIDE * 3, tmpptr=nextline; j; j--)
! *tmpptr++ = (int) *inptr++;
X
X for (i=0; i<HIGH; i++) {
X /* swap thisline and nextline */
***************
*** 703,710 ****
X lastline = (i==imax);
X
X /* read in next line */
! for (j=WIDE * 3, tmpptr=nextline; j; j--)
! *tmpptr++ = (int) *inptr++;
X
X /* dither this line and put it into the output picture */
X thisptr = thisline; nextptr = nextline;
--- 704,712 ----
X lastline = (i==imax);
X
X /* read in next line */
! if (!lastline)
! for (j=WIDE * 3, tmpptr=nextline; j; j--)
! *tmpptr++ = (int) *inptr++;
X
X /* dither this line and put it into the output picture */
X thisptr = thisline; nextptr = nextline;
***************
*** 752,780 ****
X *outptr++ = oval;
X
X r1 -= r[oval]; g1 -= g[oval]; b1 -= b[oval];
- /* can't use tables because r1,g1,b1 go negative */
X
X if (!lastpixel) {
! thisptr[0] += (r1*7)/16;
! thisptr[1] += (g1*7)/16;
! thisptr[2] += (b1*7)/16;
X }
X
X if (!lastline) {
X if (j) {
! nextptr[-3] += (r1*3)/16;
! nextptr[-2] += (g1*3)/16;
! nextptr[-1] += (b1*3)/16;
X }
X
! nextptr[0] += (r1*5)/16;
! nextptr[1] += (g1*5)/16;
! nextptr[2] += (b1*5)/16;
X
X if (!lastpixel) {
! nextptr[3] += r1/16;
! nextptr[4] += g1/16;
! nextptr[5] += b1/16;
X }
X nextptr += 3;
X }
--- 754,785 ----
X *outptr++ = oval;
X
X r1 -= r[oval]; g1 -= g[oval]; b1 -= b[oval];
X
+ r1 += 128; /* make positive for table indexing */
+ g1 += 128;
+ b1 += 128;
+
X if (!lastpixel) {
! thisptr[0] += tbl7[r1];
! thisptr[1] += tbl7[g1];
! thisptr[2] += tbl7[b1];
X }
X
X if (!lastline) {
X if (j) {
! nextptr[-3] += tbl3[r1];
! nextptr[-2] += tbl3[g1];
! nextptr[-1] += tbl3[b1];
X }
X
! nextptr[0] += tbl5[r1];
! nextptr[1] += tbl5[g1];
! nextptr[2] += tbl5[b1];
X
X if (!lastpixel) {
! nextptr[3] += tbl1[r1];
! nextptr[4] += tbl1[g1];
! nextptr[5] += tbl1[b1];
X }
X nextptr += 3;
X }
***************
*** 807,822 ****
X byte *pp;
X int r1, g1, b1;
X int *thisline, *nextline, *thisptr, *nextptr, *tmpptr;
! int i, j, rerr, gerr, berr, pwide3;
X int imax, jmax;
X
X pp = pic; pwide3 = w * 3; imax = h-1; jmax = w-1;
X
! /* load up colormap, 3 bits R, 3 bits G, 2 bits B (RRRGGGBB) */
X for (i=0; i<256; i++) {
! r[i] = ((i&0xe0) * 255) / 0xe0;
! g[i] = ((i&0x1c) * 255) / 0x1c;
! b[i] = ((i&0x03) * 255) / 0x03;
X }
X
X thisline = (int *) malloc(pwide3 * sizeof(int));
--- 812,837 ----
X byte *pp;
X int r1, g1, b1;
X int *thisline, *nextline, *thisptr, *nextptr, *tmpptr;
! int i, j, val, pwide3;
X int imax, jmax;
X
X pp = pic; pwide3 = w * 3; imax = h-1; jmax = w-1;
X
! /* up to 256 colors: 3 bits R, 3 bits G, 2 bits B (RRRGGGBB) */
! #define RMASK 0xe0
! #define RSHIFT 0
! #define GMASK 0xe0
! #define GSHIFT 3
! #define BMASK 0xc0
! #define BSHIFT 6
!
! /* load up colormap */
! /* note that 0 and 255 of each color are always in the map; */
! /* intermediate values are evenly spaced. */
X for (i=0; i<256; i++) {
! r[i] = (((i<<RSHIFT) & RMASK) * 255 + RMASK/2) / RMASK;
! g[i] = (((i<<GSHIFT) & GMASK) * 255 + GMASK/2) / GMASK;
! b[i] = (((i<<BSHIFT) & BMASK) * 255 + BMASK/2) / BMASK;
X }
X
X thisline = (int *) malloc(pwide3 * sizeof(int));
***************
*** 840,869 ****
X r1 = *thisptr++; g1 = *thisptr++; b1 = *thisptr++;
X RANGE(r1,0,255); RANGE(g1,0,255); RANGE(b1,0,255);
X
! rerr = r1 & 0x1f; gerr = g1 & 0x1f; berr = b1 & 0x3f;
! *pp = (r1&0xe0) | ((g1>>3)&0x1c) | (b1>>6);
X
X if (j!=jmax) { /* adjust RIGHT pixel */
! thisptr[0] += tbl7[rerr];
! thisptr[1] += tbl7[gerr];
! thisptr[2] += tbl7[berr];
X }
X
X if (i!=imax) { /* do BOTTOM pixel */
! nextptr[0] += tbl5[rerr];
! nextptr[1] += tbl5[gerr];
! nextptr[2] += tbl5[berr];
X
X if (j>0) { /* do BOTTOM LEFT pixel */
! nextptr[-3] += tbl3[rerr];
! nextptr[-2] += tbl3[gerr];
! nextptr[-1] += tbl3[berr];
X }
X
X if (j!=jmax) { /* do BOTTOM RIGHT pixel */
! nextptr[3] += tbl1[rerr];
! nextptr[4] += tbl1[gerr];
! nextptr[5] += tbl1[berr];
X }
X nextptr += 3;
X }
--- 855,895 ----
X r1 = *thisptr++; g1 = *thisptr++; b1 = *thisptr++;
X RANGE(r1,0,255); RANGE(g1,0,255); RANGE(b1,0,255);
X
! /* choose actual pixel value */
! val = ((r1&RMASK)>>RSHIFT) | ((g1&GMASK)>>GSHIFT) | ((b1&BMASK)>>BSHIFT);
! *pp = val;
!
! /* compute color errors */
! r1 -= r[val];
! g1 -= g[val];
! b1 -= b[val];
!
! /* Add fractions of errors to adjacent pixels */
! r1 += 128; /* make positive for table indexing */
! g1 += 128;
! b1 += 128;
X
X if (j!=jmax) { /* adjust RIGHT pixel */
! thisptr[0] += tbl7[r1];
! thisptr[1] += tbl7[g1];
! thisptr[2] += tbl7[b1];
X }
X
X if (i!=imax) { /* do BOTTOM pixel */
! nextptr[0] += tbl5[r1];
! nextptr[1] += tbl5[g1];
! nextptr[2] += tbl5[b1];
X
X if (j>0) { /* do BOTTOM LEFT pixel */
! nextptr[-3] += tbl3[r1];
! nextptr[-2] += tbl3[g1];
! nextptr[-1] += tbl3[b1];
X }
X
X if (j!=jmax) { /* do BOTTOM RIGHT pixel */
! nextptr[3] += tbl1[r1];
! nextptr[4] += tbl1[g1];
! nextptr[5] += tbl1[b1];
X }
X nextptr += 3;
X }
***************
*** 880,890 ****
X /****************************/
X {
X int i;
! for (i=0; i<256; i++) { /* initialize Floyd-Steinberg division tables */
! tbl1[i] = i/16;
! tbl3[i] = (3*i)/16;
! tbl5[i] = (5*i)/16;
! tbl7[i] = (7*i)/16;
X }
X }
X
--- 906,926 ----
X /****************************/
X {
X int i;
!
! /* initialize Floyd-Steinberg division tables */
! /* make sure rounding is done correctly for negative values! */
!
! for (i = -128; i < 0; i++) {
! tbl1[i+128] = -((8 -i )/16);
! tbl3[i+128] = -((8 -3*i)/16);
! tbl5[i+128] = -((8 -5*i)/16);
! tbl7[i+128] = -((8 -7*i)/16);
! }
! for (i = 0; i < 128; i++) {
! tbl1[i+128] = (i +8)/16;
! tbl3[i+128] = (3*i+8)/16;
! tbl5[i+128] = (5*i+8)/16;
! tbl7[i+128] = (7*i+8)/16;
X }
X }
X
X
--
X tom lane
Internet: tgl@cs.cmu.edu BITNET: tgl%cs.cmu.edu@cmuccvma
SHAR_EOF
chmod 0644 xv.patch.3h.24to8 ||
echo 'restore of xv.patch.3h.24to8 failed'
Wc_c="`wc -c < 'xv.patch.3h.24to8'`"
test 10009 -eq "$Wc_c" ||
echo 'xv.patch.3h.24to8: original size 10009, current size' "$Wc_c"
fi
# ============= xv.patch.3i.cs ==============
if test -f 'xv.patch.3i.cs' -a X"$1" != X"-c"; then
echo 'x - skipping xv.patch.3i.cs (File already exists)'
else
echo 'x - extracting xv.patch.3i.cs (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'xv.patch.3i.cs' &&
*** /dev/null Fri Nov 8 12:42:01 1991
--- README.3I.CS Fri Nov 8 12:57:02 1991
***************
*** 0 ****
--- 1,41 ----
+ Date: Thu, 18 Jul 91 11:39:19 EDT
+ Subject: XV patches
+ From: Tom.Lane@G.GP.CS.CMU.edu
+ To: bradley@cis.upenn.edu
+
+ Hi,
+ I just spent some time bringing up XV patchlevel 3 on an HPUX machine.
+ (I was using the original release, which was quite useful despite its
+ tendency to coredump. The new version seems a lot solider, and has some
+ nice additional features --- thanks!) Attached are some diffs that you
+ may find useful. They fall into three classes:
+
+ 1. (contents deleted, see patch xv.patch.3g.hpux)
+
+ 2. (contents deleted, see patch xv.patch.3h.24to8)
+
+ 3. I was also unhappy with the results of color sorting in xvmisc.c.
+ (I have only a 64-color display, so effective color sorting is real
+ important for display of most GIFs.) I looked at your algorithm and
+ figured out a way to do a complete color-distance sort in O(n^2) time.
+ When I put this in, though, the results were worse! I eventually realized
+ that the old code effectively sorted by both color-distance (the first 32
+ entries) and population (the next 32). My revised code, included below,
+ chooses the next-most-populous color for slots 0,2,4,... and the
+ next-furthest-away color for slots 1,3,5,.... This seems to produce
+ somewhat better results than your code for a 64-color display, and it does
+ significantly better if fewer than 64 colors are available.
+ Incidentally, I also looked into using Euclidean-distance
+ (dx^2+dy^2+dz^2) in place of your taxicab-distance metric in xvmisc.c.
+ I found that this sometimes gave visually better results, but more often
+ gave worse results; in particular, subtle shade variations tend to get lost.
+ I don't know if you had experimented with this choice, but you seem to have
+ picked the right thing.
+ The results are still not as good as the original xgif's, but they are
+ better than before. You'd have to combine the functions of SortColormap and
+ AllocColors in order to do what xgif does.
+
+ Hope these patches are of use. I think xv is a great program.
+ tom lane
+ Internet: tgl@cs.cmu.edu BITNET: tgl%cs.cmu.edu@cmuccvma
+
*** old/xvmisc.c Thu Nov 29 13:53:22 1990
--- xvmisc.c Thu Jul 18 10:16:21 1991
***************
*** 200,223 ****
X /************************************************/
X
X typedef struct thing
! { byte r,g,b;
! int oldindex;
! int use; } CMAPENT;
X
X
- static int CMAPcompare(a,b)
- CMAPENT *a,*b;
- {
- return (b->use - a->use);
- }
-
-
X /***********************************/
X void SortColormap()
X {
X byte *p;
! int i, j, k, mdist, entry, mn, d, hist[256], trans[256];
! static CMAPENT c[256], c1[256], *cp, *cj, *ck;
X
X
X /* no point doing this if we're on a 1-bit display */
--- 200,218 ----
X /************************************************/
X
X typedef struct thing
! { byte r,g,b; /* actual value of color */
! int oldindex; /* its index in the old colormap */
! int use; /* # of pixels of this color */
! int mindist; /* min distance to a selected color */
! } CMAPENT;
X
X
X /***********************************/
X void SortColormap()
X {
X byte *p;
! int i, j, k, mdist, entry, d, hist[256], trans[256];
! CMAPENT c[256], c1[256], *cp, *cj, *ck;
X
X
X /* no point doing this if we're on a 1-bit display */
***************
*** 243,248 ****
--- 238,244 ----
X cp = &c[numcols++];
X cp->r = r[i]; cp->g = g[i]; cp->b = b[i];
X cp->use = hist[i]; cp->oldindex = i;
+ cp->mindist = 100000;
X }
X }
X
***************
*** 256,287 ****
X c[entry].use = 0; /* and mark it dealt with */
X
X
! /* sort rest of colormap, in order of decreasing 'distance' from already
! allocated elements.
!
! FURTHER MODIFICATION of algorithm. The algorithm's performance
! utterly goes to hell as numcols increases. (Probably on the order
! of O^3 performance). Since I don't see a clever way of rewriting
! the algorithm for O^2 performance (which'd be acceptable), I'm going
! to make a trade-off. I'll only run the algorithm for the first 32 colors
! (or so). It can do that Real Fast. Then I'll just stick the rest of
! the unsorted colors (if any), and tack them on the end, in order of
! amount of use. This should give similar picture quality, with
! much higher performance. */
X
! for (i=1; i<numcols && i<32; i++) {
! /* find the i'th most different color */
! entry = -1; mdist = -1;
X for (j=0, cj=c; j<numcols; j++,cj++) {
! if (cj->use) { /* this color has not been marked already */
! mn = 10000;
! for (k=0, ck=c1; k<i; k++,ck++) {
X d = abs(cj->r - ck->r) + abs(cj->g - ck->g) + abs(cj->b - ck->b);
! if (mn>d) mn=d;
X }
- /* mn = minimum distance from c[j] to already used colors */
- /* we want to select the unused color that has the greatest mn */
- if (mn > mdist) { mdist = mn; entry = j; }
X }
X }
X
--- 252,293 ----
X c[entry].use = 0; /* and mark it dealt with */
X
X
! /* sort rest of colormap. Half of the entries are allocated on the
! basis of distance from already allocated colors, and half on the
! basis of usage. (NB: 'taxicab' distance is used throughout this file.)
!
! To obtain O(n^2) performance, we keep each unselected color
! (in c[], with use>0) marked with the minimum distance to any of
! the selected colors (in c1[]). Each time we select a color, we
! can update the minimum distances in O(n) time. */
X
! for (i=1; i<numcols; i++) {
! /* First, update distances to the just-selected color */
! ck = &c1[i-1]; /* point to just-selected color */
X for (j=0, cj=c; j<numcols; j++,cj++) {
! if (cj->use) { /* can ignore already-selected colors */
X d = abs(cj->r - ck->r) + abs(cj->g - ck->g) + abs(cj->b - ck->b);
! if (cj->mindist > d) cj->mindist = d;
! }
! }
!
! if (i&1) {
! /* Now find the i'th most different color */
! /* we want to select the unused color that has the greatest mindist */
! entry = -1; mdist = -1;
! for (j=0, cj=c; j<numcols; j++,cj++) {
! if (cj->use) { /* this color has not been marked already */
! if (cj->mindist > mdist) { mdist = cj->mindist; entry = j; }
! }
! }
! } else {
! /* Now find the i'th most different color */
! /* we want to select the unused color that has the greatest usage */
! entry = -1; mdist = -1;
! for (j=0, cj=c; j<numcols; j++,cj++) {
! if (cj->use) { /* this color has not been marked already */
! if (cj->use > mdist) { mdist = cj->use; entry = j; }
X }
X }
X }
X
***************
*** 290,300 ****
X c[entry].use = 0;
X }
X
- /* tack rest of colors onto colormap in decreasing order of use */
- qsort((char *) c,numcols,sizeof(CMAPENT),CMAPcompare);
- memcpy(&c1[i], c, (numcols - i) * sizeof(CMAPENT));
-
-
X /* build translation table */
X for (i=0; i<numcols; i++) trans[ c1[i].oldindex ] = i;
X
--- 296,301 ----
--
X tom lane
Internet: tgl@cs.cmu.edu BITNET: tgl%cs.cmu.edu@cmuccvma
SHAR_EOF
chmod 0644 xv.patch.3i.cs ||
echo 'restore of xv.patch.3i.cs failed'
Wc_c="`wc -c < 'xv.patch.3i.cs'`"
test 7275 -eq "$Wc_c" ||
echo 'xv.patch.3i.cs: original size 7275, current size' "$Wc_c"
fi
exit 0
--
Matthew Lee Stier |
Sun Microsystems --- RTP, NC 27709-3447 | "Wisconsin Escapee"
Email: matthew.stier@East.Sun.COM |
Phone: (919) 469-8300 fax: (919) 460-8355 |
Technical Details
Message-ID:
<5481@southeast.East.Sun.COM>Path:
arc1-ca.pugleaf.net!wupost!uunet!sun-barr!cronkite.Central.Sun.COM!newstop!southeast!matthewShow Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!wupost!uunet!sun-barr!cronkite.Central.Sun.COM!newstop!southeast!matthew From: matthew@sunpix.East.Sun.COM (Matthew Stier - Sun Visualization Products) Newsgroups: alt.graphics.pixutils,alt.sources,alt.sources.patches Subject: More Patches for 'Xv'. Message-ID: <5481@southeast.East.Sun.COM> Date: 8 Nov 91 20:07:06 GMT Sender: news@East.Sun.COM Followup-To: alt.graphics.pixutils Organization: Sun Microsystems, Research Triangle Park, NC Lines: 983