THE UNIVERSAL IFF LIBRARY FOR THE AMIGA VERSION 18.5 12-MAR-90 BY CHRISTIAN A. WEBER, ZURICH/SWITZERLAND (BIX: chw) THIS PROGRAM IS IN THE PUBLIC DOMAIN. IT MAY BE FREELY DISTRUBUTED, COPIED AND USED FOR COMMERCIAL OR NON-COMMERCIAL PURPOSES. IT MAY BE DISTRIBUTED WITH OR WITHOUT THIS DOCUMENTATION FILE. TO MAINTAIN COMPATIBILITY, YOU SHOULD NOT MAKE ANY CHANGES ON THE LIBRARY ITSELF. UPDATES WILL BE RELEASED BY THE AUTHOR. WHAT IFF FILES CAN BE HANDLED? ------------------------------ I wrote this library to provide an easy way for reading and writing simple IFF files, such as pictures, animations, sound samples etc. In order to keep things easy, the IFF parser is NOT recursive. This means that it cannot handle files which contain recursive FORM or CAT definitions (e.g. a FORM containing another FORM). This restriction is not as important as you might think, since over 95% of all currently existing IFF files are not recursive. If you really need a recursive IFF parser, you should use the original Electronic Arts code, or the iffparse.library by Stuart Ferguson and Leo L. Schwab, which will be part of WB 1.4. Note that the iff.library can deal with ANIM files, although they contain nested FORMs. This is done with a little trick, see 'AnimExample.c' for details. CHANGES FOR V18.5 ----------------- * OpenIFF() no longer trashes memory if a corrupt FORM (with some random bytes at the end of file, as generated by old DPaint) is loaded. * SHAM pictures (HAM with palette changes at each line) are now fully supported by ShowIFF. CHANGES FOR V18.4 ----------------- * The library now handles poorly written BODY chunks correctly (such as written by old DPaint versions). It can now deal with pictures with a height or depth of 0. CHANGES FOR V18.2 ----------------- * The type IFFFILE has been redefined from 'CPTR' to 'void *'. This allows you to use pointers to ULONG as your IFF file handles (which are easier to use, see AnimExample.c), and the compiler won't generate warnings if you pass these variables to the IFF library functions. * FindChunk() can be called with a chunk ID of 0. It then returns a pointer to the first byte after the end of the current FORM. This can be used by ANIM readers for jumping from FORM to FORM (see example program). CHANGES FOR V18.1 ----------------- * New function ModifyFrame(). This functions takes a bitmap and modifies its planes according to a supplied DLTA chunk. This allows you to easily display DPaint III and compatible animations. * GetViewModes() now correctly masks out the forbidden bits (SPRITES, VP_HIDE and genlock). This bug caused pictures with the VP_HIDE bit set not to be displayed at all! It is now safe to put the result of GetViewModes() directly to the NewScreen.ViewModes field, as it was supposed to. Note that GetViewModes() now returns the full 32 bit CAMG entry, so the prototype for GetViewModes() has changed from UWORD to ULONG. The upper 16 bits of the view modes are reserved for future use by CBM. * GetColorTab() now correctly masks out the lower 4 bits of the color bytes (These bits are used by some converted Sun rasterfiles). * The DecodePic() decruncher is more robust, it does not write past the end of the bitmap anymore (remember those nasty 81000007/9 gurus?) If you have pictures which can't be displayed, PLEASE let me know! * The library base format has changed. Since this structure was never documented, this should not cause any compatibility problems. It is very likely that this structure changes from release to release, so don't use it! * The name for IffError() in the Assembler include file has changed to IFFError() (IFF in caps) to be compatible with the C names. This requires a global search-and-replace operation on your asm source files. * The ShowIFF.c example program has been debugged. It should now handle Overscan pictures correctly (in V16.4, it sometimes switched to scrolling-mode if the picture was 480 rows high). The file scanner is no longer recursive, it uses ARP's 'ALL' features. ShowIFF now always returns the memory it allocates. * There is a new example program 'AnimExample.c'. It loads and displays a DPaint animation, the user can set the speed and number of loops. This example shows how to use the new ModifyFrame() routine. CHANGES FOR V17.x ----------------- This version never existed (the IFFLIB17.ZOO release contained iff.lib 16.4). To avoid confusion, the new version number is now 18. CHANGES FOR V16.4 ----------------- * The ShowIFF.c example program was completely rewritten. It now uses the ARP library for command line parsing and directory searching. A powerful WorkBench handler has been added which lets you display the pictures in a drawer or an entire disk by selecting the drawer or disk icon and acti- vating the ShowIFF icon with extended selection. If a picture is larger than the screen, you can use the mouse to scroll the screen. (I have some scanned pictures with a resolution of 2048x2048 pixels, which can be displayed with 1MB chip ram!) * The Play8SVX demo has been added. It plays sampled sounds from CLI and WorkBench. * Internal changes to the library code (I now use the DevPac assembler V2 by HiSoft instead of the Manx 3.6 assembler) CHANGES FOR V16.3 ----------------- * The BMHD property chunks can now be in any order (which worked for V16.1, but was broken in 16.2). CHANGES FOR V16.2 ----------------- * The SaveBitMap/SaveClip() routines sometimes generated a wrong CAMG chunk. This is fixed now. * There are no more decruncher overruns corrupting the memory list CHANGES FOR V16.1 ----------------- Since V15.3 I got lots of suggestions, so I made the following changes. Note that this version is fully downward-compatible to V15.3. * There was a bug in the DecodePic() routine which called the guru if the width of the picture was not a multiple of 16. It's fixed now. * The GetViewModes() routines now calculates the viewmodes correctly for all picture sizes, including Super-Overscan (produced by DigiView 3.0). * When you open an IFF file with the OpenIFF() call, memory is allocated and the file is read into that memory. Normally, all files are loaded into whatever memory is available, but '8SVX' files are always loaded to CHIP memory (the memory which is accessable by the Amiga's custom chips). This solution is good for playing IFF sounds, but it is not satisfactory for some other applications. The solution of this problem is quite easy: I added a new routine called 'NewOpenIFF', which allows you to specify the type of memory for the file. So if you want to load an IFF instrument into any RAM, the right command is: 'f=NewOpenIFF(filename,0L)' or 'f=OpenIFF(filename,MEMF_PUBLIC)'. You can use any memory attributes you want (PUBLIC,CHIP,FAST...). * The file 'iff.h' is now split into two files: 'iff.h', which contains the structure definitions and function declarations, and 'IffGlue.asm', which contains the C to Assembler interface routines. These routines are needed for the Manx C compilere V3.6. * The file 'IFFPragmas.h" is added to support the Lattice C compiler. It was taken from an usenet article by Lyle E. Levine. (Thanks!) * The demo file 'ShowIFF.c' now correctly handles overscan pictures. LIBRARY FUNCTION OVERVIEW ------------------------- Name Offset Description OpenIFF -30 Allocate memory for an IFF-file and load it CloseIFF -36 Finish access to an IFF-file and deallocate memory FindChunk -42 Find a specific chunk in an IFF file GetBMHD -48 Find the BitMapHeader of an ILBM file GetColorTab -54 Find CMAP chunk, convert it to an Amiga ColorTable DecodePic -60 Decode the BODY of an ILBM file into a BitMap SaveBitMap -66 Save the contents of a BitMap as an IFF-file SaveClip -72 Save a part of a BitMap as an IFF-file IFFError -78 Get detailed error descrpition if a routine fails GetViewModes -84 Get the Amiga-specific ViewModes NewOpenIFF -90 Allocate specific memory for an IFF-file and load it ModifyFrame -96 Modify an anim frame using a DLTA chunk (to be continued) DETAILED DESCRIPTION OF THE LIBRARY FUNCTIONS --------------------------------------------- (This documentation was translated from German to English in half an hour, so please be tolerant!) IFF/NewOpenIFF IFF/NewOpenIFF NAME NewOpenIFF -- allocate memory for an IFF-file and read it SYNOPSIS ifffile = NewOpenIFF(filename,memattr) D0 A0 D0 LIBRARY OFFSET -90 FUNCTION This function opens a file on a disk and looks whether it's an IFF file or not. If it is an IFF file, memory is allocated and the file is read into memory. The 'memattr' argument is taken to define the memory type. Normally memattr is set to 0 or MEMF_PUBLIC. If an error occurs, 0 is returned, and you can call IFFError() to get the error number. INPUTS filename - Pointer to a null-terminated string memattr - Memory requirements as used for Exec's AllocMem(), such as MEMF_CHIP, MEMF_PUBLIC ... (MEMF_CLEAR is not necessary) RESULT ifffile - 'FileHandle', points to the beginning of the IFF file ("FORM...."), Zero if unsuccessful. Call IFFError() to get the reason of the failure. SEE ALSO OpenIFF, CloseIFF, IFFError BUGS None known IFF/OpenIFF IFF/OpenIFF NAME OpenIFF -- allocate memory for an IFF-file and read it SYNOPSIS ifffile = OpenIFF(filename) D0 A0 LIBRARY OFFSET -90 FUNCTION This function does the same as the NewOpenIFF() routine above, except that you cannot specify the type of memory which is allocated for the file. Normally the type is 0 which means 'any memory', but if the IFF file type is '8SVX', the file is ALWAYS loaded into CHIP memory. If you wish to override these defaults, use NewOpenIFF() instead of OpenIFF(). INPUTS filename - Pointer to a null-terminated string RESULT ifffile - 'FileHandle', points to the beginning of the IFF file ("FORM...."), 0 if unsuccessful. Call IFFError() to get the reason of the failure. SEE ALSO NewOpenIFF, CloseIFF, IFFError BUGS None IFF/CloseIFF IFF/CloseIFF NAME CloseIFF -- finish access to an IFF-file and deallocate memory SYNOPSIS CloseIFF(ifffile) A1 LIBRARY OFFSET -36 FUNCTION Returns the memory previously allocated by OpenIFF(). INPUTS ifffile - IFF file pointer, from OpenIFF() RESULT none SEE ALSO OpenIFF BUGS If A1 contains garbage, an 81000005 Guru will visit you... IFF/FindChunk IFF/FindChunk NAME FindChunk -- find an IFF-chunk SYNOPSIS chunk = FindChunk(ifffile,chunkname) D0 A1 D0 LIBRARY OFFSET -42 FUNCTION Find a specific chunk in an IFF file INPUTS ifffile - pointer to a FORM, normally the result of OpenIFF() chunkname - 4 characters packed ASCII ('BODY', 'VHDR' ...) if chunkname is 0, FindChunk() returns a pointer to the first byte after the end of the current FORM. This can be used byANIM readers for jumping from FORM to FORM. RESULT Pointer to the beginning of the chunk (that means to the chunk name itself, followed by the chunk size), zero if chunk not found SEE ALSO GetBMHD, GetColorTab BUGS none IFF/GetBMHD IFF/GetBMHD NAME GetBMHD -- find a BitMapHeader of an IFF-file SYNOPSIS header = GetBMHD(ifffile) D0 A1 LIBRARY OFFSET -48 FUNCTION Returns a pointer to a 'BitMapHeader' structure as defined in iff.h and iff.i INPUTS ifffile - IFF file pointer, returned by OpenIFF() RESULT Pointer to the BitMapHeader, or 0 if no BMHD chunk found SEE ALSO FindChunk, GetColorTab BUGS none IFF/GetColorTab IFF/GetColorTab NAME GetColorTab -- find a CMAP chunk and convert it to a ColorTable SYNOPSIS count = GetColorTab(ifffile,colortable) D0 A1 A0 LIBRARY OFFSET -54 FUNCTION Searches the CMAP chunk of an IFF file and converts it, if it's there, to an Amiga color table structure. This colortable can directly be used as a parameter for the LoadRGB4() function. INPUTS ifffile - IFF file pointer, returned by OpenIFF() colortable - Pointer to a block of memory which must be large enough to hold the colortable (2 bytes per color) RESULT Number of colors actually found, or zero if the file has no CMAP chunk SEE ALSO FindChunk, GetBMHD WARNING the colortable must be WORD aligned IFF/DecodePic IFF/DecodePic NAME DecodePic -- decode the BODY of an ILBM file into a BitMap SYNOPSIS success = DecodePic(ifffile,bitmap) D0 A1 A0 LIBRARY OFFSET -60 FUNCTION Decodes and decrunches a picture into the BitMap you supplied. If the picture is larger than your BitMap's planes, it will be truncated. If your BitMap is larger than the picture, the picture will be drawn into the top left corner of your BitMap. If the picture has more planes (colors) than your BitMap, the operation will fail and 0 will be returned. INPUTS ifffile - IFF file pointer, from OpenIFF() bitmap - Pointer to a properly initialized BitMap structure: bm_Planes[] must point to valid BitPlanes, bm_Depth contains the number of planes. bm_Width and bm_Height must be set according to the size of your bit planes. RESULT Non-zero if OK, 0 if error, Call IFFError() to know the reason of the failure WARNING This routine needs at least 520 bytes of stack BUGS The width of the IFF picture (in pixels) must be a multiple of 8 (I've never seen a picture which didn't obey this rule!) IFF/SaveBitMap IFF/SaveBitMap NAME SaveBitMap -- save the planes of a BitMap as an IFF-file SYNOPSIS result = SaveBitMap(filename,bitmap,colortable,flags) D0 A0 A1 A2 D0 LIBRARY OFFSET -66 FUNCTION Save the planes of a BitMap as an IFF-file, optionally with a colortable. The IFF file will contain the following chunks: FORM - The IFF header, with the type ILBM BMHD - The BitMap Header structre CMAP - The color map, this chunk is omitted if colortable is zero CAMG - The Amiga ViewModes word, contains the special ViewModes information (HAM, LACE, HIRES ...) BODY - The (crunched or uncompressed) picture INPUTS filename - Name of the IFF file to create bitmap - Pointer to the BitMap holding your picture colortable - Pointer to an Amiga ColorTable structure or zero (if colortable = 0, no CMAP chunk will be generated). flags - Bit 0: 1 = Use the "CmpByteRun1" compression algorythm, 0 = Save the file uncompressed Bit 7: 1 = This is a HAM (Hold and modify) picture 0 = This is a normal or Extra-Halfbrite picture RESULT Non-zero if successful, 0 if error, Call IFFError() to know the reason of the failure SEE ALSO SaveClip IFF/SaveClip IFF/SaveClip NAME SaveClip -- save a part of a BitMap as an IFF-file SYNOPSIS result = SaveClip(filename,bitmap,coltab,flags,xoff,yoff,width,height) D0 A0 A1 A2 D0 D1 D2 D3 D4 LIBRARY OFFSET -72 FUNCTION Save a part of a BitMap as an IFF file INPUTS filename - Name of the IFF file to create bitmap - Pointer to the BitMap holding your picture colortable - Pointer to an Amiga ColorTable structure or zero (if colortable = 0, no CMAP chunk will be generated). flags - Bit 0: 1 = Use the "CmpByteRun1" compression algorythm, 0 = Save the file uncompressed Bit 7: 1 = This is a HAM (Hold and modify) picture 0 = This is a normal or Extra-Halfbrite picture xoff - X offset of the clip to be saved (bytes from the left) yoff - Y offset of the clip to be saved (lines from the top) width - width in bytes of the rectangle height - height in lines of the rectangle RESULT Non-zero if successful, 0 if error, Call IFFError() to know the reason of the failure SEE ALSO SaveBitMap BUGS The width of the rectangle will be rounded to WORD boundaries, because DPAINT wants it! IFF/IFFError IFF/IFFError NAME IFFError -- Get detailed error descrpition SYNOPSIS error = IFFError() D0 LIBRARY OFFSET -78 FUNCTION If one of the above functions returns zero, you can call IFFError() to know the reason for the failure. An error code is returned, please refer to the files 'iff.h' or 'iff.i' for the complete list of errors. INPUTS none RESULT Error-number generated by the latest function call, or zero if no error Cuurently the following numbers are used: Nr. Symbol Function Description 16 IFF_CANTOPENFILE OpenIFF() File not found 17 IFF_READERROR OpenIFF() Read() returned an error 18 IFF_NOMEM OpenIFF() Not enough memory for the file 19 IFF_NOTIFF OpenIFF() File is not IFF 20 IFF_WRITEERROR SaveBitMap() Cannot write the file 24 IFF_NOILBM DecodePic() IFF file is not an ILBM file 25 IFF_NOBMHD DecodePic() BMHD chunk not found 26 IFF_NOBODY DecodePic() BODY chunk not found 27 IFF_TOOMANYPLANES DecodePic() Picture has more planes than your BitMap 28 IFF_UNKNOWNCOMPRESSION " Unknown compression type 29 IFF_NOANHD ModifyFrame() ANHD chunk not found 30 IFF_NODLTA ModifyFrame() DLTA chunk not found -1 IFF_BADTASK A task which did not open the IFF library tried to call IFFError(). Since the IFF library is capable of multi-tasking, the error-values are stored for each task separately. SEE ALSO BUGS If you don't close the IFF library at the end of your program (using CloseLibrary()) the error node will not be freed. The same task will then not be able to re-open the iff.library!!! (This is not a bug, it's a feature!) IFF/GetViewModes IFF/GetViewModes NAME GetViewModes -- Get Amiga-specific ViewModes SYNOPSIS viewmodes = GetViewModes(ifffile) D0 A1 LIBRARY OFFSET -84 FUNCTION Searches the IFF file for a 'CAMG' chunk which holds the view modes information. If there is no CAMG chunk, the view modes are calcu- lated using the information in the BitMapHeader structure. You can directly put the low WORD of the result of a GetViewModes() call into the ns_ViewModes field of a NewScreen structure. All forbidden bits are masked out. INPUTS ifffile - IFF file pointer, returned from OpenIFF() RESULT viewmodes - LONG containing the view modes (HAM, LACE, HIRES ...) Under Kickstart V1.3, only the lower WORD is used. SEE ALSO BUGS If the IFF file has no CAMG chunk and 6 bitplanes, the HAM bit will be set. This is not always correct since the picture could be in the Extra Halfbrite mode. You can load such Halfbrite pictures into DPaint III and save them again, DPaint will generate the correct CAMG chunk. IFF/ModifyFrame IFF/ModifyFrame NAME ModifyFrame -- Modify an anim frame using a DLTA chunk SYNOPSIS success = ModifyFrame(modifyform,bitmap) D0 A1 A0 LIBRARY OFFSET -96 FUNCTION Uses the DLTA chunk of the supplied FORM to modify the planes-data of the bitmap. Usually, playback of ANIMs will require two buffers, and double-buffering between them. So the data in the bitmap must be two frames back, and the DLTA chunk is used to modify the hidden frame to the next frame to be shown. INPUTS modifyform - pointer to the FORM containing the actual DLTA chunk bitmap - Pointer to a properly initialized BitMap structure, the planes must contain the image which was displayed to frames back (using double-buffering) RESULT Non-zero if OK, 0 if error; call IFFError() to know the reason of the failure WARNINGS This routine needs at least 820 bytes of stack RESTRICTIONS Currently, only compression type 5 (Byte Vertical Delta Mode) is implemented. If you have animations which use modes 1 to 4, try loading them with DPaint III and saving them again. Sculpt-Animate pictures do not work, because I have no documentation about the compression scheme they use. I will implement some more compression types upon request. BUGS The size of the bitmap is not checked by this routine, the planes must have at least the size described in the BMHD of the anim file.