March 7, 1994

Summary:  This is a patch which dramatically improves xv-3.00 performance
displaying JPEG files on 8-bit color systems.

Note that as of this update, the author of this patch is no longer at
UCSB.  Please address any questions or comments to jim@tcp.com instead.
finger this account for more information.


=====


From alt.binaries.pictures.d Mon Jun 21 18:34:54 1993
Xref: ferkel.ucsb.edu alt.binaries.pictures.d:8931 alt.binaries.pictures.erotica.d:16399
Newsgroups: alt.binaries.pictures.d,alt.binaries.pictures.erotica.d,comp.windows.x.apps
Path: ferkel.ucsb.edu!pi-chan!jim
From: jim@ferkel.ucsb.edu (Jim Lick)
Subject: Re: XV-2.21 Better than XV-3.00 ??? Why ?
Message-ID: <jim.740700859@pi-chan>
Organization: University of California, Santa Barbara
References: <204j6fINN604@netserver.univ-lille1.fr> 	<RATINOX.93Jun21123917@denali.ccs.neu.edu> <TGL.93Jun21120621@netcom.netcom.com>
Date: Mon, 21 Jun 1993 22:14:19 GMT
Lines: 159

In <TGL.93Jun21120621@netcom.netcom.com> tgl@netcom.com (Tom Lane) writes:
>See the recent discussion of this point in comp.windows.x.apps.
>You need to lock xv 3.0 into 8-bit mode in order to get a decent
>display at all, and even then it's not quite as good as 2.21.

Attached is a patch which makes xv-3.00 display jpegs using the JPEG
quantizer instead of xv's when using xv in 8-bit mode.  Apply this
patch to generic xv-3.00 source and recompile.  Then run 'xv -force8'
or when running xv, pull down the '24/8 Bit' menu button and select
'8-bit mode' and 'Lock current mode'.  The 'quick' quantization then
refers to JPEG's 1 pass quantization.  'slow' refers to the 2 pass
quantization, and 'best' uses xv's 'best' quantizer.  'slow' is the
default and best choice.  This patch was written by me with some code
stolen out of xv-2.21a and should make xv-3.00 behave exactly as
xv-2.21a if you are locked into 8-bit mode.  This is not an official
patch.  It has been submitted to the xv author and may or may not
show up in a future release.  Despite these disclaimers, I believe
that this patch is an important one that all 8-bit xv-3.00 users
should consider adding.

Now for an explanation of the history of this.  The original xv JPEG
support was added back when the free IJG JPEG code came with only the
self-described "shoddy quantizer" which basically wasn't worth beans.
Thus initial support read in 24-bit color images from the JPEG code
and xv did all the work of quantizing down to 8-bit.  When the IJG JPEG
quantizer came out, it turned out to be much faster and much better
than any of the built in xv quantizers.  Eventually someone noticed
this and xv was changed so that the JPEG quantizer was used as default.
This was all a fairly logical approach in doing things since prior
to xv-3.00, xv dealt only with 8-bit images internally.  Any 24-bit
images read in had to be converted down to 8-bit before xv could do
anything with it.

xv-3.00 changes all this.  It now has very extensive 24-bit color support.
Unfortunately this complicates things a bit.  It's now desirable that
24-bit images shall be read in in 24-bit mode to take full advantage of
the new features.  Thus the JPEG routines were rewritten to read JPEGs
in in their full 24-bit glory.  However, this causes a boatload of
complications for users on 8-bit displays.  Quantization can take a good
bit of processing to do a good job.  However if you are working in
24-bit mode and are making changes to the image, xv has to re-quantize
the image for every change you make.  Thus in 24-bit mode on 8-bit displays
xv uses a quick and dirty conversion using a "std cmap".  The quality is
not that good though.  In 8-bit mode, xv uses the built in quantizers
to do the conversion.  This is significantly better, but the JPEG quantizer
is a lot better and a lot faster still.

Once I figured this out, I decided to add back code to make xv-3.00
work like xv-2.21a but I wanted to do it in such a way so that it didn't
break the 24-bit features.  This is why you still need to lock xv
into 8-bit mode to enable this code.  There still is not enough code
in xv-3.00 to protect users against making stupid mistakes like editing
a 24-bit image in 8-bit mode and then saving it to make 8-bit mode a
default, so I've left 24-bit mode the default so that users will have
to have some idea what they are doing to use it.  Perhaps a future
release of xv will change this although it will be pretty complicated
to sufficiently protect users from doing stupid things.

PS: As to the original question of why there is no colormap support, the
support is there, but you have to be in 8-bit mode to use it.  24-bit
mode has no colormap, so there's a good reason why you can't edit it.

--- jim@pi-chan.ucsb.edu --- Jim Lick --- jim@tcp.com --- jIngOrO@CaveMUCK ---
--:):-- perfect little dream the kind that hurts the most -- |\| | |/| --:(:--
--- CaveMUCK is back! --- Telnet to cave.tcp.com (128.95.10.106) port 2283 ---

-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: 2.2

mQCNAiu7/qMAAAEEAK4MXYJFNbpQFzHMWJU4/5ToVCZG+lqTkDAHtM4k1+aEeFx3
iukDvCy83us/b9OCFS1tOJelYH0yeHx8MFm6DrHMCdVyQdugFL7udF0ycZajV52d
VqBS73wlZjcdAZW5puPioGkc+fsmKgGomY0IR3XZDA6zVOY17SkJUnvij4etAAUR
tB5KaW0gTGljayA8amltQGZlcmtlbC51Y3NiLmVkdT4=
=Yayv
-----END PGP PUBLIC KEY BLOCK-----

-----CUT HERE-----
*** xvjpeg.c-dist	Thu Apr 22 18:32:29 1993
--- xvjpeg.c	Mon Jun  7 01:06:37 1993
***************
*** 532,538 ****
  
    else {
      cinfo->out_color_space = CS_RGB;
!     cinfo->quantize_colors = FALSE;   /* give 24-bit image to XV */
  
      SetISTR(ISTR_INFO,"Loading %ldx%ld Color JPEG (%ld bytes)...",
  	    cinfo->image_width, cinfo->image_height, filesize);
--- 532,580 ----
  
    else {
      cinfo->out_color_space = CS_RGB;
!     /* The following code is designed to get xv to more closely */
!     /* follow v2.21 behavior when dealing with 24-bit JPEG images */
!     /* when viewing in 8-bit mode.  What xv 2.21 did was to use the */
!     /* JPEG quantizer when decoding JPEG images since it is in */
!     /* general faster and better quality than what xv can do.  xv 3.00 */
!     /* on the other hand supports 24-bit modes now, so the code was */
!     /* redone to always ask the JPEG decoder for a 24-bit image. */
!     /* This is great on 24-bit displays or when you want to manipulate */
!     /* an image in 24-bit space.  However, I was unsatisfied with the */
!     /* behavior when xv 3.00 is used when locked into 8-bit mode.  It */
!     /* requests a 24-bit image and then quantizes it itself.  This uses */
!     /* up lots of memory, is slow, and the quality was somewhat less */
!     /* than what I expected.  Therefore I designed this patch to force */
!     /* xv to request JPEG to quantize the image when locked in 8-bit */
!     /* mode.  It uses the same method as xv 2.21 to decide on which */
!     /* quantizing method to ask for. - Jim Lick jim@pi-chan.ucsb.edu */
!     if(picType == PIC8 && conv24MB.flags[CONV24_LOCK] == 1 )
!     { /* if we're locked into 8-bit mode */
!       /* basically if CONV24_FAST, we use JPEG's one-pass quantizer. */
!       /* if CONV24_SLOW (default) we use JPEG's two-pass quantizer. */
!       /* if CONV24_BEST or other we ask for a 24-bit image and let */
!       /* xv do the rest. */
!       if (conv24 == CONV24_FAST || conv24 == CONV24_SLOW)
!       {
!         cinfo->quantize_colors = TRUE;
!         state824=1; /* tells xv that this image has been converted */
!           /* from 24-bit to 8-bit so it can warn the user if he tries */
!           /* to do something stupid. */
!         if (conv24 == CONV24_SLOW) cinfo->two_pass_quantize = TRUE;
!         else {
!           cinfo->two_pass_quantize = FALSE;
!           /* For the 1-pass quantizer it's best to use 256 colors and let */
!           /* the cmap sorter pick up any slack.  This produces essentially */
!           /* the same results as xv's usual fast quantizer, but it reduces */
!           /* swapping since no 24-bit copy of the image is needed. */
!           cinfo->desired_number_of_colors = 256;
!         }
!       } /* else it must be CONV24_BEST */
!       else cinfo->quantize_colors = FALSE;
!     }
!     else { /* otherwise gimme a 24-bit image */
!       cinfo->quantize_colors = FALSE;   /* give 24-bit image to XV */
!     }
  
      SetISTR(ISTR_INFO,"Loading %ldx%ld Color JPEG (%ld bytes)...",
  	    cinfo->image_width, cinfo->image_height, filesize);
***************
*** 550,556 ****
    Width  = cinfo->image_width;
    Height = cinfo->image_height;
  
!   if (cinfo->out_color_space == CS_GRAYSCALE) {
      pic8 = (byte *) malloc(Width * Height);
      if (!pic8) FatalError("Not enough memory for Image");
      CurImagePtr = pic8;
--- 592,602 ----
    Width  = cinfo->image_width;
    Height = cinfo->image_height;
  
!   /* The second part of the if re-added from xv 2.21 to enable the */
!   /* 8-bit mode quantizing code described elsewhere to work right */
!   /* - Jim Lick jim@pi-chan.ucsb.edu */
!   if (cinfo->out_color_space == CS_GRAYSCALE ||
!       cinfo->quantize_colors == TRUE) {
      pic8 = (byte *) malloc(Width * Height);
      if (!pic8) FatalError("Not enough memory for Image");
      CurImagePtr = pic8;

