[comp.sys.mac.programmer] Reading/Printing MacPaint files

roger@caen.engin.umich.edu (Roger Roberto Espinosa) (09/21/88)

Hello, there.

I'm just starting to program my Mac, and got really excited when I found out that Lightspeed Pascal (which
I own) could save its graphics window as a MacPaint file. But...I couldn't find anything to read in a 
MacPaint file.  I don't understand QuickDraw enough to see how I would read the file back in.

(I tried to read in the MacPaint file as a file of grafport, but I can't seem to display it. I had this
same problem trying to save graphics using Kyan Pascal's double-hires tools for the Apple ][ (which was
an scaled-down QuickDraw scheme))

Could someone send me a way to read in the file using Lightspeed Pascal? And is there an easy way to
print graphics from Pascal (aside from actually directly sending graphics control codes to the ImageWriter.
I haven't actually gotten the printer yet, but why not kill two birds with one stone...)?

Thanks!
 Roger Espinosa
 (you can try to reply by mail, but I can guarantee nothing.)

beard@ux1.lbl.gov (Patrick C Beard) (10/02/88)

Here is a code fragment lifted from Technical Note #86.  I have used it
as a model several times and so it should help.  For more help, consult
the technical note.

{ ReadMPFile:
This is a small example program written in TML Pascal that demonstrates how 	to read MacPaint files.  As a final step, it takes the data that was read and  displays it on the screen to show that it worked. Caveat: This is not 	intended to be an example of good programming practice, in that the possible errors merely cause the program to exit. This is VERY uninformative, and there should be some sort of error handler to explain what happened.  For simplicity, and thus clarity, those types of things were del





iberately not included.  This example will not work on a 128K Macintosh, since memory allocation is done too simplistically.
}

PROGRAM ReadMPFile;

{$I 'HD:Pascal System:MemTypes.ipas'  }
{$I 'HD:Pascal System:QuickDraw.ipas' }
{$I 'HD:Pascal System:OSIntf.ipas' }
{$I 'HD:Pascal System:ToolIntf.ipas' }


CONST	DefaultVolume = 0;
			MaxFileSize = 51840; { maximum MacPaint file size, 720*72. }

VAR		srcPtr: 			Ptr;
			dstPtr: 			Ptr;
			saveDstPtr:		Ptr;
			srcFileName:		Str255;
			srcFile: 			INTEGER;
			srcSize: 			LONGINT;
			errCode:			INTEGER;
			scanLine:			INTEGER;
			aPort:				GrafPort;
			theBitMap:		BitMap;

BEGIN
	{ Initialize QuickDraw. }
	InitGraf(@thePort);

	{ Make a name of a file to read. }
	srcFileName := 'MP TestFile';

	{ Make a buffer that is the largest picture we can expect.  This
 		could be done in a more memory efficient manner. }
	srcPtr := NewPtr(MaxFileSize);
	IF srcPtr = NIL  THEN ExitToShell;
	
	{ Open the data file. }
	errCode := FSOpen(srcFileName,DefaultVolume,srcFile);
	IF errCode <> noErr  THEN ExitToShell;
	
	{ Skip the header. }
	srcSize := 512;
	errCode := FSRead(srcFile,srcSize,srcPtr);
	IF errCode <> noErr  THEN ExitToShell;

	{ Find out how big the file is, and figure out source size. }
	errCode := GetEOF(srcFile,srcSize);
	IF errCode <> noErr  THEN ExitToShell;
	srcSize := srcSize - 512;   { Remove the header from count. }
	
	{ Read the data into the buffer. The file mark is already past the header. }
	errCode := FSRead(srcFile,srcSize,srcPtr);
	IF errCode <> noErr THEN ExitToShell;

	{ Close the file we just read. }
	errCode := FSClose(srcFile);
	IF errCode <> noErr THEN ExitToShell;

	{ Create a buffer that will be used for the Destination BitMap.  This also 		has a maximum size possible, the same as the full MacPaint picture size. }
	dstPtr := NewPtr(MaxFileSize);
	IF dstPtr = NIL  THEN ExitToShell;
	saveDstPtr := dstPtr;

	{ Unpack each scanline into the buffer.  Note that 720 scanlines are 		guaranteed to be in the file.  (They may be blank lines)  In the 		UnPackBits call, the 72 is the count of bytes done when the file was 		created.  MacPaint does one scan line at a time when creating the file. }
	FOR scanLine := 1 to 720 DO
		BEGIN
    		UnPackBits(srcPtr,dstPtr,72);   {bumps both ptrs}
		END;

	{ The buffer has been fully unpacked. Create a port that we can draw into. }
	OpenPort(@aPort);

	{ Create a BitMap out of our saveDstPtr that can be copied to the screen. }
	theBitMap.baseAddr := saveDstPtr;
	theBitMap.rowBytes := 72;          { width of MacPaint picture }
	SetPt(theBitMap.bounds.topLeft, 0,0);
	SetPt(theBitMap.bounds.botRight, 72*8, 720); {maximum rectangle}

	{ Now use that BitMap and draw the piece of it to the screen.
		Only draw the piece that is full screen size (portRect). }
	CopyBits(theBitMap, aPort.portBits, aPort.portRect,
						aPort.portRect, srcCopy, NIL);

	{ That's it.  Now wait for the mouse button to leave.  Pause. }
	REPEAT
	UNTIL Button;
END.

Don't yell at me about the style and correctness of the code.  As I said,
I have used it as a model, but of course have improved its robustness
for my own use.  I write in LightSpeed C and would be willing to send
you code in C if you want.

Patrick Beard
Lawrence Berkeley Laboratory
beard@ux1.lbl.gov