TweetFollow Us on Twitter

File Package
Volume Number:1
Issue Number:7
Column Tag:MacPascal

Standard File Package, unpack & copy the bits

By Alan Wootton

Here is a program to view MacPaint documents from MacPascal (like “showpage”). I use the File Manager, the Standard File Package, the toolbox procedure UnPackBits, and QuickDraw’s CopyBits to display the image loaded in memory.

In MacTutor #5, Gary Palmer asked about loading MacPaint files in MacPascal. Well, I remembered once running across a description of MacPaint docs by Bill Atkinson. After some digging, I found the description in part of a mailing from tech support to developers dated Dec. 1983.

Atkinson explains that the resource fork is not used and that a 512 byte header precedes the packed bitmap data. The header is an array of patterns and some empty space. To simply view the picture we can ignore the header. The MacPaint ‘page’ is 720 lines of 72 bytes each. This is almost 51K and since we wish to load this into memory, a FatMac will probably be required. Atkinson gives a short routine to decode the data into a page. He uses UnpackBits, which is on page 7 of ToolBox Utilities.

Reading the data was a problem. I tried to use the file I/O routines provided with MacPascal. One must either read data byte-at-a-time, which takes forever, or, if you read large blocks, you can never get the last partially filled block. At this point I decided that Real Programmers use the low level File Manager routines. In other words PBOpen, PBRead, and then PBClose.

Another MacPascal shortcoming is the GetOldFile function. Once again, Real Programmers go straight past the limitations of the language and consult the bible (Inside Mac). We shall use the Standard File Package.

The Standard File Package

MacPascal’s function GetOldName will only select files of type TEXT. To select MacPaint docs it will be necessary to call the Standard File Package directly (OldPaintName in following program). On page 30 of Packages in “Inside Macintosh”, the procedure SFGetFile is described. To call it, use trap $A9EA, which is Pack3, and be sure to push a 2, the ‘selector’, on the stack last. You must type in the SFReply record on page 25. [For a complete description of SFReply, see the Assembly Column in this issue.] Since our type list will just be one type (PNTG) it will not be necessary to declare an array. Pass nil for filefilter and dlghook. There is an argument to pass a prompt string that Inside Mac says is historical only. I find that it works fine.

Low Level File Manager

The filecall interface in the following program simulates the PB calls of the File Manager. This is an example of the OS call I presented in MacTutor #6. [Please refer to issue #6 for details on calling OS routines from Pascal.] Before you can use the the PB routines, you must type the lengthy Parameter Block declarations. There are four variant parts to this record. I have only used the ioParam part here because that is all that was needed in this example. You should type the whole thing and save it somewhere for later use. Note that 8 bit types do not come out right, so one must take care that the declaration has the correct length. The routine descriptions (starting on page 31 of the File Manager) give a nice list of those parameters that must be set before calling (assembly programmers note: in some places ioRefNum is listed as 22, but the correct number is 24). You should carefully check that each parameter is set correctly before calling. The exception is ioCompletion, which can be ignored since we will be making synchronous calls. If ioNamePtr is not nil then the File Manager assumes that its value is the address of a string. This could badly mess up memory. In MacPascal, declared variables are cleared to 0’s so you can get away with this, but later, when you compile, nasty bugs pop up (this actually happened to me).

UnPackBits

UnPackBits is actually very simple. I have complicated things by not reading all the data into memory at once. The scheme used is to read 1024 bytes into memory (skipping the header) and when the first 512 bytes are used I slide the upper 512 bytes down and add 512 bytes onto the end. The program unpacks 72 bytes at a time for 720 lines. For faster operation you can unpack 4 lines at a time. Change 720 to 180 and 72 to 288.

After the page array is filled, it would be nice to take a look at it. Copybits is used to move the image onto the drawing window. The nice thing about copybits is that it will scale the image to fit. Simply setup a Quickdraw Bitmap record for page, set destrect to the desired size, and call copybits as shown. If you change 144 to 576 and 180 to 720 you can see the painting full size.

To write a MacPaint document (not done in this program) it is necessary to know the format of the header. The header is a 4 byte version number (default = 2) and then 38*8 = 304 bytes of patterns and then 204 unused bytes for a total of 512. However, Atkinson’s example writes 512 zeros for a header so I guess that would work. To pack the data you use the reverse of the unpack procedure. Things can be made simpler though because you can use one destination buffer and then write it out after every PackBits.

It is my contention that everything in Inside Mac can be demonstrated and used from MacPascal (except things like Vertical Retrace routines). If there is anything that you have trouble with and would like to see in MacTutor, write a letter to MacTutor and I will see if there isn’t a way to do it.


program Read_MacPaint_doc;{by Alan Wootton 4/85}
           { This program reads a MacPaint file and shows            
        the picture 1/4 size in Drawing }
 uses
  Quickdraw2;
 type
  ptr = ^integer;
  OStype = longint;

  SFReply = record { this is used by the standard file               
                           package, see Packages }
    good : integer;
    ftype : OSType;
    vrefNum : integer;
    version : integer;
    fname : string[63];
   end;

{ Parameter Block information contained in File Manager 
chapter of Inside Macintosh.  Note that MacPascal won’t do 8 bit fields 
right }

  ParamBlkPtr = ^ParamBlockRec;
  ParamBlockRec = record
{ data structure of File Manager }
    qLink : Ptr;
    qType : integer;
    ioTrap : integer;
    ioCmdAddr : ptr;
    ioCompletion : ptr;
    ioResult : integer;
    ioNamePtr : ^str255;
    ioVrefNum : integer;
{  case ParamBlkType of  ...  ioParam:  }
    ioRefNum : integer;
{       ioVersNum : byte;  }
    ioPermssn : integer;{ byte }
    ioMisc : ptr;
    ioBuffer : ptr;
    ioReqCount : longint;
    ioActCount : longint;
    ioPosMode : integer;
    ioPosOffset : longint;
   end;

  diskBlock = packed array[0..511] of char;

  paintPage = array[0..35, 0..719] of integer;
{  576*720 bitmap  = 72 bytes * 720 lines =  51,840           bytes }




 var
  reply : SFReply;{ used by OldPaintName, declared here              
                   to access vRefNum }
  filename : str255;
  fileblock : ParamBlockRec;
  buff : array[0..1] of diskblock;{ 1K }

  Page : paintPage;{ Huge variable, almost 52K  }

  srcPnt : ^diskBlock;
  destPnt : ^paintPage;

  lines, err : integer;

  curport : Grafptr;
  pageBits : bitmap;
  destRect : Rect;


{ common OS trap code, could be done with ‘Generic’ call}
{see MacTutor Vol. 1 No. 6 for assembly source code}
 function filecall (Pb : ParamBlkPtr;
         trap : integer) : integer;
  var
   access : array[0..12] of integer;
   d0, a0 : longint;
 begin
  stuffHex(@access, ‘2848548C41FA000C309F245F265F20522013FFFF224826804ED4’);
  a0 := ord(pb);
  inlineP($4E75, @d0, @a0, trap, @access);
  filecall := loword(d0);
 end;

{ The following File Manager calls work just like   }
{ those described in Inside Macintosh for the Lisa Pascal Workshop.  
}
{ Except that the async parameter is a dummy; all calls are sync }

 function PBOpen (Pb : ParamBlkPtr;
         async : boolean) : integer;
 begin
  PBOpen := filecall(pb, $A000);
 end;

 function PBClose (Pb : ParamBlkPtr;
         async : boolean) : integer;
 begin
  PBClose := filecall(pb, $A001);
 end;

 function PBRead (Pb : ParamBlkPtr;
         async : boolean) : integer;
 begin
  PBRead := filecall(pb, $A002);
 end;


{  same as OldFileName, only for MacPaint docs }
 function OldPaintName (prompt : str255) : str255;
  var
   where : point;
   typelist : longint;
 begin
  reply.good := 0;
  typelist := $504E5447;{ ‘PNTG’ }
  setPT(where, 100, 100);
  inlineP($A9EA, where, @prompt, nil, 1, @typelist, nil, @reply, 2);
{ $A9EA is pack3 ,  2 is SFGetFile, see Packages  }
  if reply.good <> 0 then
   OldPaintName := reply.Fname
  else
   OldPaintName := ‘’;
 end;


{  This procedure moves buff[1] down onto buff[0], adjusts srcPnt to 
point at it’s same data and tacks more data on end in buff[1].     }
 procedure Refill_Buffer;
 begin
  blockmove(@buff[1], @buff[0], 512);
  srcPnt := pointer(ord(srcPnt) - 512);
  fileBlock.ioBuffer := @buff[1];
  fileBlock.ioReqCount := 512;
  fileBlock.ioPosMode := 0;
  err := PBRead(@fileBlock, false);{ fill buff[1] }
 end;


begin { main }
 ShowDrawing;
 fileName := OldPaintName(‘ Select Painting to examine’);
 while filename <> ‘’ do
  begin
   fileBlock.ioVrefNum := reply.vrefnum;
   fileBlock.ioNamePtr := @fileName;
   fileBlock.ioPermssn := 1;{ read only, version number              
                                   is in upper byte and is 0 }
   fileBlock.ioMisc := nil;
   if PBOpen(@fileBlock, false) = 0 then
    begin
     refill_buffer;{  first block is skipped }
     refill_buffer;{   fill 1 }
     refill_buffer;{ 1 onto 0, refill 1 }

     srcPnt := @buff[0];{ <-- pointer to start of data }
     destPnt := @Page;{ <----  pointer to Page bitmap }

{------> This is the part that actually decodes the packed MacPaint data 
<------}
{ $A8D0 is UnPackBits, see page 7 in Toolbox Utilities   }
{ srcPnt and destPnt are updated by UnPackBits so use @}
     for lines := 1 to 720 do{ 720 lines in paint doc }
      begin
       inlineP($A8D0, @srcPnt, @destPnt, 72);
                                     { UnPackBits for 72 bytes }
       if ord(srcpnt) >= ord(@buff[1]) then
        Refill_Buffer; { if src no longer in buff[0] }
      end;{ of 720 lines }

     if PBClose(@fileBlock, false) <> 0 then
      writeln(‘close error’);

{  now show drawing  in current port  (drawing window) }
     GetPort(curPort);

 
{  set up bitmap record }
    pagebits.baseaddr := pointer(ord(@page));
    pagebits.rowbytes := 72;
    setRect(pagebits.bounds, 0, 0, 576, 720);

     setRect(destRect, 0, 0, 144, 180);
{ 144,180 =1/4 normal, image will be squashed to fit }

     copyBits(pagebits, curport^.portbits, pagebits.bounds,          
           destRect, srcCopy, nil);
     moveto(4, 190);
     drawstring(‘Click to open another MacPainting’);
     repeat
     until button;

    end;{ if no Open error }
   fileName := OldPaintName(‘ Select another Painting ?’);
  end;{ if name<>’’ loop }
end.
 

Community Search:
MacTech Search:

Software Updates via MacUpdate

Adobe Creative Cloud 2.2.0.129 - Access...
Adobe Creative Cloud costs $49.99/month (or less if you're a previous Creative Suite customer). Creative Suite 6 is still available for purchase (without a monthly plan) if you prefer. Introducing... Read more
Tower 2.2.3 - Version control with Git m...
Tower is a powerful Git client for OS X that makes using Git easy and more efficient. Users benefit from its elegant and comprehensive interface and a feature set that lets them enjoy the full power... Read more
Apple Java 2015-001 - For OS X 10.7, 10....
Apple Java for OS X 2015-001 installs the legacy Java 6 runtime for OS X 10.11 El Capitan, OS X 10.10 Yosemite, OS X 10.9 Mavericks, OS X 10.8 Mountain Lion, and OS X 10.7 Lion. This package is... Read more
Adobe Muse CC 2015 2015.0.1 - Design and...
Muse CC 2015 is available as part of Adobe Creative Cloud for as little as $14.99/month (or $9.99/month if you're a previous Muse customer). Muse CS6 is still available for purchase (without a... Read more
Adobe Illustrator CC 2015 19.1.0 - Profe...
Illustrator CC 2015 is available as part of Adobe Creative Cloud for as little as $19.99/month (or $9.99/month if you're a previous Illustrator customer). Illustrator CS6 is still available for... Read more
Corel Painter 14.1.0.1105 - Digital art...
Corel Painter helps you create astonishing art in a variety of media. Paint with vivid oil paints, fluid water colors, and earthy charcoals. Corel Painter flawlessly recreates the tones and textures... Read more
Pacifist 3.5.4 - Install individual file...
Pacifist opens up .pkg installer packages, .dmg disk images, .zip, .tar. tar.gz, .tar.bz2, .pax, and .xar archives and more, and lets you extract or install individual files out of them. This is... Read more
Merlin Project 3.1.0.40305 - Project man...
Merlin Project is for those of you who are responsible for complex projects. Simple lists of tasks won't suffice. Good planning raises questions about the dependencies of activities on each other,... Read more
DM1 2.0 - Advanced drum machine. (Commer...
DM1 is an advanced Drum Machine. It turns your computer into a fun and creative beat making machine. Easy and fast to use, loaded with 86 superb electronic drum kits and beautiful hyper-realistic... Read more
Posterino 3.2.1 - Create posters, collag...
Posterino offers enhanced customization and flexibility including a variety of new, stylish templates featuring grids of identical or odd-sized image boxes. You can customize the size and shape of... Read more

Mazes of Karradash (Games)
Mazes of Karradash 1.0 Device: iOS Universal Category: Games Price: $1.99, Version: 1.0 (iTunes) Description: The city of Karradash is under attack: the monsters of the Shadow Realms are emerging from the depths.No adventurer is... | Read more »
Battle Golf is the Newest Game from the...
Wrassling was a pretty weird - and equally great - little wressling game. Now the developers, Folmer Kelly and Colin Lane, have turned their attention to a different sport: golfing. This is gonna be weird. [Read more] | Read more »
Qbert Rebooted has the App Store Going...
The weird little orange... whatever... is back, mostly thanks to that movie which shall remain nameless (you know the one). But anyway it's been "rebooted" and now you can play the fancy-looking Qbert Rebooted on iOS devices. [Read more] | Read more »
Giant Monsters Run Amok in The Sandbox...
So The Sandbox has just hit version number 1.99987 (seriously), and it's added a lot more stuff. Just like every other update, really. [Read more] | Read more »
Fish Pond Park (Games)
Fish Pond Park 1.0.0 Device: iOS Universal Category: Games Price: $2.99, Version: 1.0.0 (iTunes) Description: Nurture an idyllic slice of tourist's heaven into the top nature spot of the nation, furnishing it with a variety of... | Read more »
Look after Baby Buddy on your Apple Watc...
Parigami Gold is the new premium version of the match three puzzler that includes Apple Watch support and all new content. You won't simply be sliding tiles around on your wrist, the Apple Watch companion app is an all new mini-game in itself. You'... | Read more »
Swallow all of your opponents as the big...
Eat all of the opposition and become the largest ball in Battle of Balls now available in the App Store and Google Play. Battle of Balls pits you against other opponents in real time and challenges you to eat more balls and grow larger than all of... | Read more »
PAC-MAN Championship Edition DX (Games)
PAC-MAN Championship Edition DX 1.0.0 Device: iOS Universal Category: Games Price: $4.99, Version: 1.0.0 (iTunes) Description: It’s Your World. EAT IT! Get ready for more ghost chain gobbling and frantic action in PAC-MAN® CE-DX! The... | Read more »
incurve (Games)
incurve 1.0 Device: iOS Universal Category: Games Price: $.99, Version: 1.0 (iTunes) Description: Get ready for 2 different gravities Goal is to hit as many white dots on your way up.When you're touching the screen, the dots have a... | Read more »
Crossy Road has its Own Merch Store Now....
Do you like Crossy Road? I mean do you really like Crossy Road? Well then you're in luck! Hipster Whale has opened up a Crossy Road store, so you can show off your fandom via official T-shirts. [Read more] | Read more »

Price Scanner via MacPrices.net

Apple restocks refurbished Mac minis for up t...
The Apple Store has restocked Apple Certified Refurbished 2014 Mac minis, with models available starting at $419. Apple’s one-year warranty is included with each mini, and shipping is free: - 1.4GHz... Read more
13-inch 2.5GHz MacBook Pro on sale for $899,...
Best Buy has the 13″ 2.5GHz MacBook Pro available for $899.99 on their online store. Choose free shipping or free instant local store pickup (if available). Their price is $200 off MSRP. Price is... Read more
21-inch 2.9GHz iMac on sale for $1299, save $...
Best Buy has the 21″ 2.9GHz iMac on sale today for $1299.99 on their online store. Choose free shipping or free local store pickup (if available). Their price is $200 off MSRP, and it’s the lowest... Read more
Free Image Sizer 1.3 for iOS Offers Photo Edi...
Xi’An, China based G-Power has announced the release of Image Sizer 1.3 for the iPhone, iPad, and iPod touch, an important update to their free photo editing app. Image Sizer’s collection of easy to... Read more
Sale! 13″ 1.6GHz/128GB MacBook Air for $899,...
B&H Photo has the 13″ 1.6GHz/128GB MacBook Air on sale for $899 including free shipping plus NY tax only. Their price is $100 off MSRP, and it’s the lowest price available for this model. Read more
13-inch Retina MacBook Pros on sale for $100...
Best Buy has 13-inch Retina MacBook Pros on sale for $100 off MSRP on their online store. Choose free shipping or free local store pickup (if available). Prices are for online orders only, in-store... Read more
Will BMW’s i3 Electric Vehicle Be The Automo...
The German-language business journal Manager Magazin’s Michael Freitag reports that Apple and the German performance/luxury automaker Bayerishe Motoren Werke (BMW) are back at far-reaching... Read more
Sale! $250 off 15-inch Retina MacBook Pro, $2...
B&H Photo has lowered their price for the 15″ 2.2GHz Retina MacBook Pro to $1749, or $250 off MSRP. Shipping is free, and B&H charges NY sales tax only. They have the 27″ 3.3GHz 5K iMac on... Read more
Global Smartphone Market Posts 11.6% Year-Ove...
According to the latest preliminary data released from the International Data Corporation (IDC) Worldwide Quarterly Mobile Phone Tracker, smartphone vendors shipped a total of 337.2 million units... Read more
15-inch and 13-inch Retina MacBook Pros on sa...
B&H Photo has 15″ & 13″ Retina MacBook Pros on sale for up to $180 off MSRP. Shipping is free, and B&H charges NY sales tax only: - 15″ 2.2GHz Retina MacBook Pro: $1819 save $180 - 15″ 2.... Read more

Jobs Board

*Apple* Customer Experience (ACE) Leader - A...
…management to deliver on business objectives Training partner store staff on Apple products, services, and merchandising guidelines Coaching partner store staff on Read more
Project Manager - *Apple* Pay Security - Ap...
**Job Summary** The Apple Pay Security team is seeking a highly organized, results-driven Project Manager to drive the development of Apple Pay Security. If you are Read more
*Apple* TV Product Design Internship (Spring...
…the mechanical design effort associated with creating world-class products with the Apple TV PD Group. Responsibilities will include working closely with manufacturing, Read more
*Apple* Watch SW Application Project Manager...
**Job Summary** The Apple Watch software team is looking for an Application Engineering Project Manager to work on new projects for Apple . The successful candidate Read more
*Apple* Retail - Multiple Positions (US) - A...
Sales Specialist - Retail Customer Service and Sales Transform Apple Store visitors into loyal Apple customers. When customers enter the store, you're also the Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.