MacPaint files
Volume Number: 1
Issue Number: 7
Column Tag: C Workshop
MacPaint file format
By Keith McGreggor
The MacPaint file format is rapidly becoming the standard for transferring
graphic information from one application to another. This article will explain that
format and show you how to transfer your own images into MacPaint files.
A Little Bit of QuickDraw
The Macintosh’s screen is a bit image. That is, what appears on the screen is
actually a collection of consecutive bits in memory that the hardware in the Mac
interprets as screen dots (or pixels). If the value of one of these bits is 1, then the
pixel corresponding to it will be black. If the bit is 0, then the pixel will be white.
Figure #1. Bits represent pixels
The Mac screen is 512 pixels wide by 342 pixels tall. The bit image in memory
takes up 175,104 bits (or 21,888 bytes with 8 bits per byte). We can consider the
screen bit image as being 342 rows with 64 bytes per row. Due to the 68000
microprocessor in the Macintosh, every bit image must have an even number of bytes
per row, and the rows must begin and end on word boundaries.
In C, the easiest way to define a bit image is with an array of characters. For
example, if we wanted to define the Macintosh screen’s bit image, the definition would
be:
Figure #2. C definition of a bit image
Bit images are manipulated by Quick- Draw through the use of bitmaps. A bit-
map is a structure which points to a bit image and associates a coordinate system with
it. The definition of a bitmap is:
Figure #3. C definition of a bitmap
The baseAddr field points to the first byte (character) in the bit image. The
rowBytes field contains the number of bytes per row in the bit image. The rectangle
bounds provides the coordinate system for the bits. The top left corner of the rectangle
is aligned with the first bit of the bit image.
Since we can treat bit images in C as arrays of characters, we don’t always have
to display them immediately. You can easily create a picture in a bit image off-screen,
and later in your program “stamp” it onto the Mac’s screen.
The Macintosh’s ROM contains several QuickDraw calls that allow you to
manipulate bitmaps (on- or off-screen). We’ll look at two of these later in the
program.
MacPaint images are kept in the data fork of a MacPaint file. The file is
essentially a 512 byte header followed by a bit image that is 576 pixels wide by 720
pixels tall (or 72 bytes by 720 rows).
Figure #4. The MacPaint File Format
The 512 bytes of header contain version information, pattern definitions, and an
unused area for future expansion. If you change the contents of this section with care,
you can set up your own patterns. If the version number is zero, the default patterns
are used. If the number is not zero, then the patterns in the header are used.
Fig.#5.The Paint File Header Format
The MacPaint file bit image is considerably larger than the Macintosh screen’s
bit image. In fact, if you were to store a bit image 72 bytes by 720 rows directly onto
disk, each MacPaint file would take a minimum of 52K bytes! To make these files
smaller, each row of pixels has been compressed using the PackBits routine in the
Macintosh ROM. Using PackBits, the typical MacPaint file compresses down to around
10K bytes.
Dipping in the Bit Bucket
To make your program transfer an image into a MacPaint file, you need only to
copy the bitmap containing the image into the compressed MacPaint file format. To be
able to do this, you need to use two ROM routines, CopyBits and PackBits.
CopyBits transfers the contents of one bitmap into another. If you want, you can
specify a mask region in the destination bitmap to prevent CopyBits from destroying
the entire image. CopyBits will shrink or expand the contents of the source bitmap to