[net.lang.st80] bug in the blue book's implementation of *bitblt*?

mwherman@watcgl.UUCP (Michael W. Herman) (07/12/85)

This article is directed to those of you who are using the
*bitblt* operator described in the book "Smalltalk-80: The Language
and its Implementation" (the "blue book") beit on a real Smalltalk 
machine or some other implementation that was faithfully derived from 
the Smalltalk code in the blue book.

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

I have been using Simon Kenyon's *layers* software for bitmap
graphics to implement the bitmap *rotate* operator described in
blue book.  I believe I may have found a bug in the Smalltalk code
for *bitblt* given in the section entitled "Simulation of Bitblt" 
on pp. 355-361 of the blue book.

First, let me say that I have modified Kenyon's C implementation so
that it is almost statement-for-statement equivalent to the bluebook 
implementation.  In particular, I have added the *clipRange* code which
was completely missing.  I have also corrected the code which calcualates
*sourceDelta* in the *calculateOffsets* code.

Secondly, the bug also shows up in another, independent implementation
written about a year ago in a third language running on 8088 hardware.

The bug that shows up in the version of *bitblt* I am now using is that
it does not properly copy a 16 bit wide rectangle covering the left half
of a 32x32 bit bitmap to a 16 bit wide rectangle covering the right half
of the same bitmap.  This is an operation that occurs as the 15th (last)
*bitblt* operation in the *rotate* loop given on pp. 409-410 of the blue
book and corresponds to the last operation in Figure 20.10 on p. 410.
I believe the problem lies mostly in *checkOverlap* but the fix probably
involves (possibly sweeping) changes to *calculateOffsets* and the
*copyLoop* code.

The following *layers* program performs the 3 bitblts given in Figure
20.10 of the blue book and illustrates the bug.  The bug shows up when
the last *bitblt* does not copy the left half of the bitmap to the right half.

For those unfamiliar with the semantics of Kenyon's *bitblt*, they are

bitblt( <S, the source bitmap>, <source rectangle in S>,
	<D, the destination bitmap>, <destination origin in D>,
	<halftone bitmap>, <operation> );

----------------------------------------------------------------------
#include <stdio.h>
#include <graphics/layers.h>

extern struct Bitmap* display;

main() {
	struct Bitmap* mask;
	struct Rectangle rect;
	struct Point dest_p;
	int quad;
	int width;

	width = 32;
	quad = width / 2;

	rect.origin.x = 0;
	rect.origin.y = 0;
	rect.corner.x = width;
	rect.corner.y = width;

	layers();

	mask = balloc( rect );

	/* set *mask* to all zeros */
	fastclear( mask );
	bitblt( mask, mask->rect, display, display->rect.origin, 0, S );

	/* set top-left quadrant of *mask* to ones */
	dest_p.x = -quad;
	dest_p.y = -quad;
	bitblt( 0, mask->rect, mask, dest_p, 0, ALL_ONES );
	bitblt( mask, mask->rect, display, display->rect.origin, 0, S );

	/* 13. make the *mask* half the size */
	dest_p.x = -quad / 2;
	dest_p.y = -quad / 2;
	bitblt( mask, mask->rect, mask, dest_p, 0, S_AND_D );
	bitblt( mask, mask->rect, display, display->rect.origin, 0, S );

	/* 14. bottom half of *mask* <- top half of *mask* */
	dest_p.x = 0;
	dest_p.y = quad;
	bitblt( mask, mask->rect, mask, dest_p, 0, S_OR_D );
	bitblt( mask, mask->rect, display, display->rect.origin, 0, S );

	/* 15. right half of *mask* <- left half of *mask*. this doesn't work */
	dest_p.x = quad;
	dest_p.y = 0;
	bitblt( mask, mask->rect, mask, dest_p, 0, S_OR_D );
	bitblt( mask, mask->rect, display, display->rect.origin, 0, S );
}
-------------------------------------------------------------------------------

I very much like to hear from anyone who can support or deny that this bug
exists in the blue book code.  If anyone has a fix or an errata sheet for 
pp. 355-361 of blue book, that would be fantastic!



Michael Herman
Computer Graphics Laboratory
Department of Computer Science
University of Waterloo
Waterloo, Ontario, Canada  N2L 3G1

UUCP:   {allegra,decvax,ihnp4,utcsri}!watmath!watcgl!mwherman
CSNET:  mwherman%watcgl@waterloo.CSNET
ARPA:   mwherman%watcgl%waterloo.CSNET@csnet-relay.ARPA