Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Posting-Version: version B 2.10.2 9/18/84; site sdcc6.UUCP Path: utzoo!watmath!clyde!burl!ulysses!mhuxr!mhuxt!houxm!whuxl!whuxlm!harpo!decvax!ittvax!dcdwest!sdcsvax!sdcc3!sdcc6!ix408 From: ix408@sdcc6.UUCP (Cris Rys) Newsgroups: net.micro.mac Subject: Re: MacPaint Format? Message-ID: <1977@sdcc6.UUCP> Date: Thu, 21-Mar-85 00:51:39 EST Article-I.D.: sdcc6.1977 Posted: Thu Mar 21 00:51:39 1985 Date-Received: Sat, 23-Mar-85 00:33:18 EST References: <638@tty3b.UUCP> Organization: U.C. San Diego, Academic Computer Center Lines: 98 Here is the information requested on Macpaint documents. I got this information from Inside Macintosh. Macpaint documents use only the data fork of the file system; the resource fork is not used and may be ignored. The data fork contains a 512 byte header and then the compressed data representing a single bitmap of 576 pixels wide by 720 pixels tall. At 72 pixels per inch, this bitmap occupies the full 8 by 10 inch printable area of the imagewriter printer page. Header: The first 512 bytes of the document form a header with a 4 byte version number (default = 2), then 38*8 = 304 bytes of patterns, then 204 unused bytes reserved for future expansion. If the version number is zero, the rest of the header block is ignored and the default patterns are used, so programs generating Macpaint documents can simply write out 512 bytes of zero as the document header. Most programs which read Macpaint documents can simply skip over the header when reading. Bitmap: Following the header are 720 compressed scanlines of data which form the 576 wide by 720 tall bitmap. Without compression, this bitmap would occupy 51840 bytes and chew up disk space pretty fast; typical Macpaint documents compress to about 10k using PackBits procedure in the Macintosh ROM to compress runs of equal bytes within each scanline. The bitmap part of a Macpaint document is simply 720 times the output of PackBits with 72 bytes input. READING SAMPLE: program convert_pic; { I am not sure what libraries this program uses.} { UnPackBits IS in ROM, I'm not sure about ReadData} const srcBlocks = 2; {At least 2, bigger makes it faster} srcSize = 1024; {512 *srcBlocks} type diskBlock = packed array[1..512] of QDByte; var srcBuf : array[1..srcBlocks] of diskBlock; srcptr, dstptr : QDPtr; begin { skip the header } ReadData(srcfile, @srcBuf, 512); { prime srcBuf } ReadData(srcFile, @srcBuf, srcSize); { unpack each scanline into dstBits, reading more source as needed} srcPtr := @srcBuf; dstptr := dstBits.baseAddr; for scanline := 1 to 720 do begin Unpackbits(srcptr, desptr, 72); { bumps both ptrs } { time to read next chunk of packed source ? } if ord(srcptr) > ord(@srcbuf) + size - 512 then begin srcbuf[1] := srcBuf[srcblocks]; { move up last block } Readdata(srcfile, @srcbuf[2], srcsize - 512); srcptr := pointer(ord(srcptr) - srcsize + 512); end; end; end. WRITING SAMPLE: To write out a 576 by 720 bitmap which is contained in memory, the following fragment of code could be used: program write_pic; type diskBlock = packed array[1..512] of QDByte; var dstBuf : diskBlock; srcptr, dstptr : QDPtr; dstbytes : integer; begin {write header, all zeros} for i:= 1 to 512 do dstBuf[i]:=0; writedata(dstfile, @dstBuf, 512); {Compress each scanline and write it} srcptr := srcBits.baseAddr; for scanline := 1 to 720 do begin dstPtr:=@dstBuf; packbits(srcptr, desptr, 72); {bumps both ptrs} dstBytes:=ORD(dstPtr)-ORD(@dstBuf); {calc packed size} WriteData(dstFile,@dstbuf,dstBytes); {write packed data} end; end. Both of the two previous programs are only skeletons, but should work with minimal additions. Cris Rys