Errata for Programming Web Graphics

Global Errata Apparently there is some problem with the Active State port of Perl and named parameters using the CGI.pm module. An example:

p 39 in PWG:
print $query -> header(-type => 'image/png',
-expires => '1d'); # remove from cache tomorrow.

must instead use an anonymous hash as in
print $query -> header({'type' => 'image/png',
'expires' => '1d'}); # remove from cache tomorrow.

Can anyone shed some light on this?

Submitted by Ron Savage

page xii, booktech e-mail: missing ".com"

Chapter 1

pages 14-15, Figures 1-5 and 1-6:
the captions should note that the PNGs for which file sizes are given are 24-bit images; they would be comparable to or smaller than the GIFs if saved as 8-bit indexed images (e.g., use gif2png to convert and optionally pngcrush to optimize)
Submitted by Greg Roelofs

Chapter 2

On page 46:
binmode(STDIN); should be binmode(INFILE);

On page 48: Change if ((length($text) > 20 | ($text =~ / /) ) {
to
if ((length($text) > 20 || ($text =~ / /) ) {
Submitted by Ron Savage

Misconception on page 53:
Page 53 - Chap - 2:
The line at the top of the page reading:

$filesize = $filesize / 1000;

should read:

$filesize = $filesize / 1024;

I wish I could say I was following the International Electrotechnical Commission's new terminology (replacing kilobytes with kibobytes for units using powers of 2 instead of 10), but I wasn't.
Submitted by Faisal Nasim

On page 58
In comment line starting "# The right ear: ...."
Should be the upper left and lower right (not left)
Submitted by Bob Walters

In the references section:
URL for the Perl-Apache Integration Project should be http://perl.apache.org

Chapter 3

page 71, libjpeg platforms: should be "Most"; also, "IPG" should be "IJG"
Submitted by Greg Roelofs

page 74, zlib platforms: should be "Most"
Submitted by Greg Roelofs

Chapter 4

Code won't run on page 99:
"allocateColor" should be "colorAllocate"
this error occurs twice, in 2. and 3. of the "setBrush()" section
Submitted by Harmen Bussemaker

On page 99
Line 4. Change:
($whitest)
to
($mostestwhitest)
Submitted by Ron Savage

On page 100
3rd last line. 'INFILE' should read \*INFILE
Submitted by Ron Savage

On page 111: $image->rectangle(@boundingbox, red);
should be
$image->rectangle(@boundingbox, $red);
Submitted by Ron Savage

On page 128
Under 'base_rows, base_filename' should be 'base_rows'
Submitted by Ron Savage

On page 129: Under colormap[i], 'set' should be 'Set'.
Submitted by Ron Savage

Chapter 5

page 117, Table 5-1, line 1: "GraphDics": spurious D
Submitted by Greg Roelofs

page 117, Table 5-1, last line: "Multiple" should be "Multiple-image"
Submitted by Greg Roelofs

Chapter 6

No errata yet.

Chapter 7

Maurits Rijk has pointed out that the statement:

"As of this writing there is not a Gimp plug-in that will automatically generate an image map file in the manner of the WYSIWYG tools."
is no longer true because he has created one...
You can get it at http://home-2.consunet.nl/~cb007736/imagemap.html.

Chapter 8

No errata yet.

Chapter 9

No errata yet.

Chapter 10

A clarification: The counter script is actually not all that 'secure', but it suffices for the needs of a simple counter. The whole Java buzzword thing was just a joke.

Note that the following erratum is not actually a bug per se; the test case was executed with multi-image GIFs for the digits (0.gif, 1.gif, etc). GD does not handle multi-image GIFs very gracefully. In fact, it segfaults when it reads one (at least GD 1.19 does). The problem goes away when the multi-image GIFs are replaced by GIFis containing single images.

Code won't run on page 291:
The counter.pl script doesn't work. I get a Segmentation Fault whenever I try running it. I've ran it using a RH5.2 Linux with perl 5.004_05 and on a System V 4.0 with perl 5.005_3. I even copied it and BrokenImage.pm directly from your website here and ran it and it still won't go. The image files (0.gif..9.gif)are in a directory named "default", the countfile is countfile.txt layed out as described in the book (current count followed on the next line with allowed hosts).
Submitted by Jeremy Fowler

Chapter 11

On page 321
Two times it lists \Times-Roman instead of /Times-Roman.
Submitted by Ricardo Muggli

On page 336
under the font heading on the last line it says...
corresponds with the set of default Ghostscript fonts with have AFM files:
should say something like...
corresponds with the set of default Ghostscript fonts with AFM files:
Submitted by Ricardo Muggli

On page 337
first line has...
currently fonts currently supported by PostScript::Metrics
should be something like...
fonts currently supported by PostScript::Metrics
Submitted by Ricardo Muggli

Typo on page 353
under linetint and filltint it has...
with 1 as black and 0 as white.
it should be
with 1 as white and 0 as black
Submitted by Ricardo Muggli

Two Bugs in the PostScript::TextBlock module
From Susan Malveau:
I found two areas in the Write() subroutine of the TextBlock module that required a patch. They both have to do with proper word wrapping.
One problem was that words would not always line up against the left margin due to white space that remained attached to the font of a word when we'd gone over the limit and the word had to be pushed back for later processing. In this case, we would want to remove the leading white space. Below is the updated version of the code section that covers this.

        # If we've gone over, push the word back on
        # for later processing.
        #
        if ( ($wcount>$w) || ($word =~ s/\n//) ) {
            if ($word =~ /^ /) { $word =~ s/^[ ]+//; }
                # This line is the patch
                     unshift @words, $word;
                     last LINE;
        }
The other problem had to do with the section of code that determined if there were any remaining words that needed to be put back for later processing. The existing code does the logical check:

     if ($#words) {
          $element->{text} = join '', @words;
     }
but "$#words" returns the subscript of the last element in @words, NOT thenumber of elements. Instead, use the code:

     my $numWords = @words;
     if ($numWords) {
          $element->{text} = join '', @words;
     }
Hope you find these patches helpful.

(Dan Smeltz also caught the second bug).

In the references section:
Adobe used to make more technical notes available via their web site; now you must join the ADA (Adobe Developers Association) to obtain certain technical information. The URL for the Technical Notes has changed to:

Adobe's Technical Resources Page
http://partners.adobe.com/supportservice/devrelations/technotes.html

Appendix A

No errata yet.

Appendix B

No errata yet.