TweetFollow Us on Twitter

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 fit the destination bitmap’s rectangle. To call CopyBits from C, use this format:

Figure #6. Calling CopyBits from C

where “copymode” is one of the source transfer modes:

Figure #7. Source Transfer Modes

PackBits compacts a string of bytes by compressing runs of equal bytes. You call PackBits from C like so:

Figure #8. Calling PackBits from C

where “numbytes” is the number of bytes pointed to by “srcPtr.”

Initially, “dstPtr” should point to the first destination byte. The PackBits routine will move “dstPtr” to point to the next available byte. To find out how much space the original bytes were compacted into, you need to subtract the original location of “dstPtr” from its current location.

Fig. #9 How PackBits moves “dstPtr”

About the Program

This program will demonstrate how to “cut” a part of an image into a MacPaint file. It is written for the Consulair Mac C system and Toolkit. You’ll probably need to change things a bit to make it work with other versions of C.

The program opens a single window and draws a few inverted rectangles in it. Then, a gray flashing rectangle will appear and follow the position of the cursor. Use the mouse to position this rectangle where you want, and then press the mouse button. The image inside the rectangle will be cut from the screen (using CopyBits) and transferred into a MacPaint file called “DummyFileName” (using repeated calls to PackBits).

The key routine, MakePaintFile, takes as input a C string containing a filename, and a pointer to a bitmap of arbitrary size. It then creates that file (if possible) on the active disk drive, sets the file signature and type to a MacPaint file type, and compresses that bitmap into the file using PackBits. If the bitmap is smaller than 576 by 720 (as will usually be the case), the bitmap is padded with white space. If the bitmap is larger than 576 by 720, the bitmap is clipped to 576 by 720.

/*
 * MakePaint.h
 *        a C routine to create a MacPaint file
 *        from a given bitmap
 *
 * (c) 1985 by Keith McGreggor for MacTutor
 *       
 */

#define WRITEONLY 7

MakePaintFile( myfilename, mybitmap )
char myfilename[63];
struct ABitMap *mybitmap;
{
 char dstbuf[511],srcbuf[511];
 char *srcPtr;
 char *dstPtr;
 char *mypointer;
 short i,j,dstBytes;
 FILE myfile;
 short t,b,vsize,hsize;
 
// attempt to create the file
 
 myfile = creat( myfilename, WRITEONLY );
 if (myfile != 0) {

// turn the file into a MacPaint file
// and write out a 512 byte header
// full of zeros (we’re not using any of
// our own patterns)

    SetFileSignature(myfilename,’MPNT’); 
    SetFileType(myfilename,’PNTG’);
    for (i = 0; i < 512; i++) fputc(0,myfile);

// figure out how big the bitmap is and set up
// a general pointer to the bit image

    mypointer = mybitmap->baseAddr;
    hsize = mybitmap->rowBytes;
    vsize = (mybitmap->bounds.bottom)
                        - (mybitmap->bounds.top);

// now, write out 720 rows of bytes

    for (j = 1; j <= 720; j++) {

// reinitialize source and destination pointers

 srcPtr = &srcbuf[0];
 dstPtr = &dstbuf[0];

// copy the next row of bytes into srcbuf[],
// clipping or expanding where necessary

 for (i = 0; i < 72; i++) {
        if ((i < hsize) && (j <= vsize)) {
      srcbuf[i] = *mypointer;
           mypointer++;
           }
            else srcbuf[i] = 0;  // 8 white bits
 }

// compress srcbuf[] into dstbuf[]

 #PackBits(&srcPtr,&dstPtr,72);

// figure out how much compression occurred 
// and write those bytes out to the file

 dstBytes= (short)(dstPtr-&dstbuf[0]);
 for (i = 0; i < dstBytes; i++)
                   fputc(dstbuf[i],myfile);
    }

// all 720 lines have been written, so
// close up everything and return

    close(myfile);
 }
}




 /*    CutToPaint.C
  *      A sample program to illustrate
  *      the use of PackBits and CopyBits
  *
  * (c) 1985 by Keith McGreggor for MacTutor
  */
  #Options -N
  #include “Stdio.h”
  #include “MacCdefs.h”
  #include “Window.h”
  #define TRUE 0xFF
  _#define BUTTONNOTPRESSED !#Button()
  #define GRAY &(QD->gray)
  
  // allocate the application’s window
  
  WindowPtr mywindow;
  Rect mywindowrect = { 40, 5, 300, 507 };
  
  // allocate the tracking variables
  
  Rect trackingrect{0,0,100,100};
  short globx,globy,incx,incy;
  
  // allocate a bitmap and bit image to
  // hold the cut bits
  
  struct ABitMap{
   char *baseAddr;
 short  rowbytes;
 Rect bounds;
 };
 
  struct ABitMap targetmap;
  char theactualbits[14][100];
  
  #include “MakePaint.h”
  /* ------------------------------------*/
  // draw some inverted rectangles
  // just to have something to “cut”
  
  DrawSomeStuff()
  {
  Rect temprect;
  short i;
  
  #MoveTo(10,240);
  #DrawString(“\020Press the button!”);
  for (i=0;i<200;i += 10) {
   #SetRect(&temprect,i+20,i+20,i+100,i+40);
 #InvertRect(&temprect);
 }
  }
  
  /*------------------------------------*/
  // Open a window for drawing
  // and do general housekeeping
  
  InitializeOurSystem()
  {
  #InitDialogs(0);
  mywindow = (WindowPtr)#NewWindow(0,  &mywindowrect,”\021A Window for 
bits”,  TRUE,0,-1,TRUE,0);
  #SetPort(mywindow);
  DrawSomeStuff();
  #FlushEvents(-1,0);
  #InitCursor();
  #PenSize(2,2);   // set up pen for
  #PenMode(patXor);  // drawing the
  #PenPat(GRAY);   // ghost rectange
  }

  /*------------------------------------*/
  // Draw the ghost rectangle
  
  DrawCurrentPosition()
  {
  #FrameRect(&trackingrect);
  }

  /*--------------------------------------*/
  // Find out where the mouse is and
  // update global variables
  
  GetNewMouse()
  {
  Point mypoint;
  
  #GetMouse(&mypoint);
  #GlobalToLocal(&mypoint);
  incx = mypoint.h-globx;
  incy = mypoint.v-globy;
  globx = mypoint.h;
  globy = mypoint.v;
  }

  /*------------------------------------*/
  // move the ghost rectange to track
  // the motion of the mouse
  
  UpdatePostion()
  {
  #OffsetRect(&trackingrect,incx,incy);
  }
  
  /*------------------------------------*/
  // First, move around a ghost rectange
  // until the button is pressed.
  // Then, create a bitmap and copy
  // whatever is inside the rectange to
  // the bitmap.
  
  CutARectangle()
  {
  globx = 0;
  globy = 0;
  while (BUTTONNOTPRESSED) {
   DrawCurrentPosition();
 GetNewMouse();
 DrawCurrentPosition();
 UpdatePosition();
  }
  #FlushEvents(-1,0);
  #LocalToGlobal(&trackingrect.topleft);
  #LocalToGlobal(&trackingrect.botRight);
  targetmap.baseAddr = &theactualbits[0][0];
  targetmap.rowBytes = 14;
  targetmap.bounds.left = 0;
  targetmap.bounds.top = 0;
  targetmap.bounds.right = trackingrect.right-trackingrect.left;
  targetmap.bounds.bottom = trackingrect.bottom-   trackingrect.top;
  
  // mywindow -> portBits is the Macintosh screen bit image
  
  #CopyBits(&(mywindow->portBits), &targetmap,
   &trackingrect,
 &(targetmap.bounds),
 srcCopy,
 0);
  }
  
  /*------------------------------------*/
  // call makepaintfile to save the
  // bitmap away as a macpaint file
  // named “dummyfilename”
  // (note: see MakePaint.h listing)
  
  SaveItAway()
  {
  MakePaintFile(“DummyFileName”,&targetmap);
  }
  
  /*----------------------------------*/
  // Our main program
  
  main()
  {
   InitializeOurSystem();
 CutARectangle();
 SaveItAway();
 #ExitToShell();
  }
 

Community Search:
MacTech Search:

Software Updates via MacUpdate

FileZilla 3.27.1 - Fast and reliable FTP...
FileZilla (ported from Windows) is a fast and reliable FTP client and server with lots of useful features and an intuitive interface. Version 3.27.1: Fixed Vulnerabilities: Change client... Read more
Merlin Project 4.2.7 - $289.00
Merlin Project is the leading professional project management software for OS X. If you plan complex projects on your Mac, you won’t get far with a simple list of tasks. Good planning raises... Read more
Dashlane 4.8.4 - Password manager and se...
Dashlane is an award-winning service that revolutionizes the online experience by replacing the drudgery of everyday transactional processes with convenient, automated simplicity - in other words,... Read more
f.lux 39.984 - Adjusts the color of your...
f.lux makes the color of your computer's display adapt to the time of day, warm at night and like sunlight during the day. Ever notice how people texting at night have that eerie blue glow? Or wake... Read more
Sketch 46.2 - Design app for UX/UI for i...
Sketch is an innovative and fresh look at vector drawing. Its intentionally minimalist design is based upon a drawing space of unlimited size and layers, free of palettes, panels, menus, windows, and... Read more
Microsoft Office 2016 15.37 - Popular pr...
Microsoft Office 2016 - Unmistakably Office, designed for Mac. The new versions of Word, Excel, PowerPoint, Outlook and OneNote provide the best of both worlds for Mac users - the familiar Office... Read more
Slack 2.7.1 - Collaborative communicatio...
Slack is a collaborative communication app that simplifies real-time messaging, archiving, and search for modern working teams. Version 2.7.1: You're nearly finished signing in when suddenly – bonk... Read more
Google Chrome 60.0.3112.101 - Modern and...
Google Chrome is a Web browser by Google, created to be a modern platform for Web pages and applications. It utilizes very fast loading of Web pages and has a V8 engine, which is a custom built... Read more
Sound Studio 4.8.10 - Robust audio recor...
Sound Studio lets you easily record and professionally edit audio on your Mac. Easily rip vinyls and digitize cassette tapes, or record lectures and voice memos. Prepare for live shows with live... Read more
Slack 2.7.1 - Collaborative communicatio...
Slack is a collaborative communication app that simplifies real-time messaging, archiving, and search for modern working teams. Version 2.7.1: You're nearly finished signing in when suddenly – bonk... Read more

Bottom of the 9th (Games)
Bottom of the 9th 1.0.1 Device: iOS iPhone Category: Games Price: $4.99, Version: 1.0.1 (iTunes) Description: Play the most exciting moment of baseball in this fast-paced dice and card game! | Read more »
The best apps for viewing the solar ecli...
If you somehow missed the news, many parts of the United States will be witness to a total solar eclipse on August 21 for the first time in over 90 years. It'll be possible to see the eclipse in at least some capacity throughout the continental U... | Read more »
The 5 best mobile survival games
Games like ARK: Survival Evolved and Conan Exiles have taken the world of gaming by storm. The market is now flooded with hardcore survival games that send players off into the game's world with nothing but maybe the clothes on their back. Never... | Read more »
Portal Walk (Games)
Portal Walk 1.0 Device: iOS Universal Category: Games Price: $1.99, Version: 1.0 (iTunes) Description: Portal Walk is adventure and relaxing platform game about Eugene. Eugene stuck between worlds and trying to find way back home.... | Read more »
Technobabylon (Games)
Technobabylon 1.0 Device: iOS Universal Category: Games Price: $4.99, Version: 1.0 (iTunes) Description: City of Newton, 2087. Genetic engineering is the norm, the addictive Trance has replaced almost any need for human interaction,... | Read more »
5 reasons why 2v2 is the best mode in Cl...
Supercell has been teasing fans with 2v2 windows that allow players to team up for limited periods of time. The Summer of 2v2 was just this past July, but players are already clamoring for more of that sweet, sweet team-based action. The fans have... | Read more »
The best deals on the App Store this wee...
It seems like the week's only just started, and yet here we are with a huge pile of discounted games to sort through. There are some real doozies on sale this week. We're talking some truly stellar titles. Let's take a look at four of the best... | Read more »
Cat Quest Guide - How to become a purrfe...
Cat Quest is an absolutely charming open-world RPG that's taken the gaming world quite by storm. This game about a world populated by furry kitty warriors is actually a full-length RPG with sturdy mechanics and a lovely little story. It's certainly... | Read more »
Silly Walks Guide - How to strut your st...
Silly Walks is an all new adventure game that lives up to its name. It sees you playing as a variety of snack foods as you teeter-totter your way to rescue your friends from the evil blender and his villainous minions. It's all very . . . well... | Read more »
The best mobile point-and-click adventur...
Nostalgia for classic point-and-click adventure games has reached an all-time high in recent years, and the rise of mobile games have provided a perfect platform for this old-school genre. This week we're going to take a look at some of the best... | Read more »

Price Scanner via MacPrices.net

New iOS 11 Productivity Features Welcome But...
The iOS community is in late summer holding mode awaiting the September arrival of the iPhone 8 and iOS 11. iOS 11 public betas have been available for months — number six was released this week —... Read more
Samsung Electronics Launches New Portable SSD...
Samsung Electronics America, Inc. has announced the launch of Samsung Portable SSD T5 – its newest portable solid state drive (PSSD) that raises the bar for the performance of external memory... Read more
TrendForce Reports YoY Gain of 3.6% for 2Q17...
Market research firm TrendForce reports that the global notebook shipments for this second quarter registered a sequential quarterly increase of 5.7% and a year-on-year increase of 3.6%, totaling 39.... Read more
Sale! 10-inch iPad Pros for $50 off MSRP, no...
B&H Photo has 10.5″ iPad Pros in stock today and on sale for $50 off MSRP. Each iPad includes free shipping, and B&H charges sales tax in NY & NJ only: – 10.5″ 64GB iPad Pro: $599, save $... Read more
Sale! 2017 13-inch Silver 2.3GHz MacBook Pro...
Amazon has new 2017 13″ 2.3GHz/128GB Silver MacBook Pro on sale today for $100 off MSRP including free shipping. Their price is the lowest available for this model from any reseller: – 13″ 2.3GHz/... Read more
WaterField Unveils Collaboratively-Designed,...
In collaboration with customers and seasoned travelers, San Francisco maker WaterField Designs set out to create the preeminent carry-on system to improve the experience of frequent fliers. The... Read more
Miya Notes Mac-Client for Google Keep (Launch...
MacPlus Software has announced te launch of Miya Notes for Google Keep 1.0, a powerful Mac-client for Google Keep. Millions of people use Google Keep on their phones and online, but a convenient Mac... Read more
Apple refurbished iMacs available starting at...
Apple has previous-generation Certified Refurbished 2015 21″ & 27″ iMacs available starting at $849. Apple’s one-year warranty is standard, and shipping is free. The following models are... Read more
2017 13-inch MacBook Airs on sale for $100 of...
B&H Photo new 2017 13″ MacBook Airs on sale today for $100 off MSRP, starting at $899: – 13″ 1.8GHz/128GB MacBook Air (MQD32LL/A): $899, $100 off MSRP – 13″ 1.8GHz/256GB MacBook Air (MQD42LL/A... Read more
12-inch MacBooks on sale for $100 off MSRP
Amazon has 2017 12″ Retina MacBooks on sale for $100 off MSRP. Shipping is free: 12″ 1.2GHz Space Gray MacBook: $1199.99 $100 off MSRP 12″ 1.2GHz Silver MacBook: $1198 $101 off MSRP 12″ 1.2GHz Gold... Read more

Jobs Board

*Apple* Customer Experience (ACE) Leader - A...
…management to deliver on business objectivesTraining partner store staff on Apple products, services, and merchandising guidelinesCoaching partner store staff on Read more
*Apple* Solutions Consultant (ASC) - Poole -...
Job Summary The people here at Apple don't just create products - they create the kind of wonder that's revolutionised entire industries. It's the diversity of those Read more
Business Development Manager, *Apple* iClou...
Job Summary Apple is seeking an entrepreneurial person to help grow the Apple iCloud business, a service that is integral to the Apple customer experience. Read more
Product Metrics Manager - *Apple* Media Pro...
Job Summary Apple is seeking a product manager responsible for overseeing the instrumentation and analysis of usage data, in order to make data driven product Read more
iOS Wallet & *Apple* Pay Engineer - App...
Job Summary The iOS Apple Pay & Wallet team is looking for talented,...now add credit and debit cards to Wallet using Apple Pay. You can use Apple Pay in Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.