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