mjk@tty3b.UUCP (Mike Kelly) (03/18/85)
Anyone with information on MacPaint document format, please post it or mail to me. Thanks. Mike Kelly AT&T Teletype P.S. Was there a Brown program a little while ago that printed MacPaint documents on the Imagen?
jwp@utah-cs.UUCP (John W Peterson) (03/20/85)
Here it is. (This came out on INFO-MAC several months ago). ----------- For those interested, here is a description of the format of MACpaint files. This format is the common interchange format for full-page bitmap images on the MACintosh. The first 512 bytes of the file are the header. The first four bytes comprise the version number, followed by 38*8 = 304 bytes of patterns. The remaining 204 bytes of the header are reserved for future expansion. If the version number is zero, the patterns are ignored. Hence, programs that wish to create files to be read into MACpaint can just write out 512 bytes of zero as the header. Following the header are 720 compressed scanlines of data which form the 576 wide by 720 tall bitmap. The bitmap is compressed as follows ; Any run of three or more equal bytes is compressed into a count byte and a single data byte. Runs of unequal bytes are passed on literally, preceded also by a count byte. I.E. <count byte> <data byte> count = -1..-127 --> replicate byte 2..128 times <count byte> <n data bytes> count = 0.. 127 --> copy 1..128 bytes uncompressed count = -128 ignored for backward compatibility That's it. A nice simple scheme. Thanks to Bill Atkinson for providing this info.
ix408@sdcc6.UUCP (Cris Rys) (03/21/85)
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
adm@cbneb.UUCP (03/22/85)
How can Macpaint tell the difference between a count byte and a data byte? Wayne Pollock, ...!{ihnp4}!cbnap!whp