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