Received: from [207.176.88.85] by phillip.cerious.com (NTMail 3.03.0017/7.aaxh) with ESMTP id pcrews for <pcrews@cerious.com>; Fri, 28 Apr 2000 14:01:43 -0400
Received: from localhost (daemon@localhost)
	by gate7.olympiakos.com (8.9.3/8.9.3) with SMTP id NAA06492;
	Fri, 28 Apr 2000 13:40:17 -0400
Received: by gate7.olympiakos.com (bulk_mailer v1.9); Fri, 28 Apr 2000 13:38:43 -0400
Received: (from majordom@localhost)
	by gate7.olympiakos.com (8.9.3/8.9.3) id NAA06413
	for tiff-outgoing; Fri, 28 Apr 2000 13:38:43 -0400
X-Authentication-Warning: gate7.olympiakos.com: majordom set sender to owner-tiff@olympiakos.com using -f
Received: from mta6.snfc21.pbi.net (mta6.snfc21.pbi.net [206.13.28.240])
	by gate7.olympiakos.com (8.9.3/8.9.3) with ESMTP id NAA06410
	for <tiff@olympiakos.com>; Fri, 28 Apr 2000 13:38:40 -0400
Received: from adsl.pacbell.net ([216.103.51.136])
 by mta6.snfc21.pbi.net (Sun Internet Mail Server sims.3.5.2000.01.05.12.18.p9)
 with SMTP id <0FTQ00DPILT9M1@mta6.snfc21.pbi.net> for tiff@olympiakos.com;
 Fri, 28 Apr 2000 10:27:10 -0700 (PDT)
Date: Fri, 28 Apr 2000 10:27:54 -0700
From: Peter Montgomery <pjmonty@csi.com>
Subject: VC++ Release build causes problems
To: tiff@olympiakos.com
Message-id: <006801bfb137$2daa0ce0$883367d8@pacbell.net>
MIME-version: 1.0
X-Mailer: Microsoft Outlook Express 5.00.2919.6600
Content-type: text/plain; charset="iso-8859-1"
Content-transfer-encoding: 7bit
X-MSMail-Priority: Normal
X-MimeOLE: Produced By Microsoft MimeOLE V5.00.2919.6600
X-Priority: 3
Sender: owner-tiff@olympiakos.com

Okay, I did a binary search and destroy mission on the LZW code, using
the VC++ pragma pair...

#pragma optimize( "", off )
#pragma optimize( "", on )

...which allows you to turn optimization on and off at the function
level.  After a couple of minutes, I had narrowed the problem down to a
single function - "LZWSetupDecode( )".  Since I am using VC++ 5.0 (which
some have mentioned as having optimization bugs), and no one else seems
able to reproduce this bug, I guess the likely culprit is a compiler
problem.  Since it's such a tiny module, the potential problem area
seemed pretty likely.  This a piece of code from the problematic
fuction...

  /*
   * Pre-load the table.
   */
  for (code = 255; code >= 0; code--) {
   sp->dec_codetab[code].value = code;
   sp->dec_codetab[code].firstchar = code;
   sp->dec_codetab[code].length = 1;
   sp->dec_codetab[code].next = NULL;
  }

Instead of the more conventional...

  for (code = 0; code < 256; code++)

...the function steps backwards using ">=" as a the comparison.  I
decided to try and replace the code with the standard style loop.  The
result?  Now instead of pixel channels with a value of 0 becoming 255,
pixels with a value of 255 become 0!  Arrrrgh!  Okay, okay, I just need
to take adeep breath.  What else could Mr. Compiler be doing wrong?

A little more thinking turned up the culprit.  The variable "code" is
used as both a loop counter, an index into memory, and the value being
assigned.  I had a feeling that VC++ was converting "code" into an
unsigned char and using that insetad of the int that was requested.
However, the comparison was suffering from an off by one error since the
compairson was to 256, a value you can't fit into an unsigned char.  I
added a separate unsigned char varible which I used for setting the
values and directly incremented it in the loop.  Problem solved.
Suddenly the code worked perfectly even when optimized.  Just for
laughs, I returned the code to its previous form and this is what I
currently have...

added to variable list...
 unsigned char VCCCompilerFix;

  VCCCompilerFix = 255;
  for (code = 255; code >= 0; code--) {
   sp->dec_codetab[code].value = VCCCompilerFix;
   sp->dec_codetab[code].firstchar = VCCCompilerFix;
   sp->dec_codetab[code].length = 1;
   sp->dec_codetab[code].next = NULL;
   VCCCompilerFix--;
  }

Oddly enough, as one point I accidentally was starting "VCCCompilerFix"
at zero and incrementing while the "code" loop was starting at 255 and
decrementing and the library still decoded the images perfectly.  The
nice thing is that I now have a fix that works.  The drag is that the
stupid compiler put me through this is the first place.

    Thanks to everyone who pitched in!
    PeterM











