Copyright (c) Hyperion Entertainment and contributors.
IFF Source Code
Code samples on this page are not yet updated to AmigaOS 4.x some of them may be obsolete or incompatible with AmigaOS 4.x. |
Contents
- 1 IFF Source Code
- 1.1 IFFP_Modules.README
- 1.2 Makefile.SAS
- 1.3 iffp/8svx.h
- 1.4 iffp/8svxapp.h
- 1.5 iffp/amiga.h
- 1.6 iffp/compiler.h
- 1.7 iffp/debug.h
- 1.8 iffp/iff.h
- 1.9 iffp/ilbm.h
- 1.10 iffp/ilbmapp.h
- 1.11 iffp/packer.h
- 1.12 iffp/smus.h
- 1.13 apps/24bitDemo/24bitDemo.c
- 1.14 apps/ILBMDemo/ILBMDemo.c
- 1.15 apps/ILBMLoad/ILBMLoad.c
- 1.16 apps/ILBMtoC/ILBMtoC.c
- 1.17 apps/ILBMtoRaw/ILBMtoRaw.c
- 1.18 apps/Play8SVX/Play8SVX.c
- 1.19 apps/RawtoILBM/RawtoILBM.c
- 1.20 apps/ScreenSave/ScreenSave.c
- 1.21 modules/bmprintc.c
- 1.22 modules/copychunks.c
- 1.23 modules/getbitmap.c
- 1.24 modules/getdisplay.c
- 1.25 modules/ilbmr.c
- 1.26 modules/ilbmw.c
- 1.27 modules/loadilbm.c
- 1.28 modules/packer.c
- 1.29 modules/parse.c
- 1.30 modules/saveilbm.c
- 1.31 modules/screen.c
- 1.32 modules/screendump.c
- 1.33 modules/unpacker.c
- 1.34 other/clipftxt.c
- 1.35 other/cycvb.c
- 1.36 other/ilbmscan.c
- 1.37 other/sift.c
IFF Source Code
This section contains a variety of source code listings showing how to use IFF files in applications. All of these programs require the new iffparse.library included with Release 2.0 of the Amiga operating system (Kickstart V36 and greater). There are four parts:
- IFF include files. These have been updated to be compatible with iffparse.library.
- Link modules which provide convenient IFF handling routines such as showilbm.c.
- Example programs showing how to use the link modules.
- Stand-alone utility and example programs.
IFFP_Modules.README
These iffparse.library code modules and examples are designed as replacements for the original EA IFF code. In some modules, it has been possible to retain much of the original code. However, most structures and most higher level function interfaces have changed. On the plus side, these new modules contain many new high-level easy-to-use functions for querying, loading, displaying, and saving ILBMs. During their development, modules similar to these have been used inhouse for the 2.0 Display program and several other ILBM applications. The screen.c module provides powerful display-opening functions which are 1.3-compatible yet provide a host of new options under 2.0 such as centered overscan screens, full-video display clips, border transparency control, and autoscroll. New modules have been added for printing (screendump) and for preserving/adding chunks (copychunks). And the 8SVX example now actually plays samples and instruments. In addition, clipboard support is automatic for all applications that use the IFFP modules because parse.c's openifile() interprets the filename -c[n] (ie. "-c", "-c1", "-c2", etc.) as clipboard unit n. All of the applications presented here require iffparse.library which is distributed on Workbench 2.0. Please note that iffparse.library is a 1.3-compatible library, and that all of these modules and examples have been designed to take advantage of 2.0, but also work under 1.3. Developers who wish to distribute iffparse.library on their commercial products may execute a 2.0 Workbench license, or may get an addendum to their 1.3 Workbench license to allow distribution of iffparse.library. It was not necessary to port the gio IO speedup code since iffparse can use your compiler's own buffered IO routines through the callback stdio_stream() in parse.c. Depending on your application, you may want to add your own additional buffering to this stdio_stream() code. Most of the high-level function pairs provided in these modules have been designed to provide safe cleanup for themselves. For example, a loadbrush() that succeeds or fails at any point can be cleaned up via unloadbrush. The cleanup routines null out the appropriate pointers so that allocations will not be freed twice. All applications are built upon the parse.c module. The basic concept of using the parse.c module are: - Define tag-like arrays of your desired chunks (readers only) - Allocates one or more [form]Info structures as defined in iffp/[form]app.h (for example an ILBMInfo defined in iffp/ilbmapp.h). - Initialize the ParseInfo part of these structures to the desired chunk arrays, and to an IFFHandle allocated via iffparse AllocIFF(). - Use the provided high level load/save functions, or use the lower level parse.c openifile(), reader-only parseifile()/ getcontext()/nextcontext(), and closeifile(). The filename -c[n] may be used to read/write clipboard unit n. - Clean up, FreeIFF(), and deallocate [form]Info's. IMPORTANT NOTES - Most of the higher-level load functions keep the IFFHandle (file or clipboard) open. While the handle is open, you may use parse.c functions (such as findpropdata) OR direct iffparse functions (FindProp(), FindCollection()) for accessing the gathered chunks. However, it is not a good idea to keep a filehandle OR the clipboard open. While a clipboard unit is open, no other applications can clip to the unit. And while a file is open, you can't write the file back out. So, instead of keeping the file or unit open, you can use copychunks (in copychunks.c) to create a copy of your gathered chunks, and do an early closeifile() (parse.c). Then access and later write back out (if you wish) and deallocate your copied chunks via the routines in the copychunks module (findchunk, writechunklist, freechunklist). WARNING REGARDING COMPLEX FORMS Regarding Complex FORMs - The parse.c module will enter complex formats such as CATSs, LISTs, and nested FORMs to find the FORM that you are interested in. This is great. However, if you are a read-modify-write program, you should warn your user when this occurs unless YOU are capable of recreating the complex format. Otherwise, your user may unknowingly destroy his complex file by writing over it with your program. Example - a paint program could read an ILBM out of a complex LIST containing pictures and music, and then save it back out as a simple ILBM, causing the user to lose his music and other pictures. To determine if a complex form was entered after a load, check the (form)Info.ParseInfo.hunt field. If TRUE (non-zero), then your file was found inside a complex format. COMPILATION NOTES These modules and examples have been compiled using SAS C 5.10a and Manx C 5.0d, with 2.0 (37.1) include files and 2.0 amiga.lib. You must have at least 37.1 alib_protos.h (older versions of this include file contained the amiga.lib stdio protos also which conflict with both SAS and Manx stdio). For Manx, I also had to comment out the conditional definition of abs() in libraries/mathffp.h. These modules do not use mathffp, but the mathffp include file is pulled in by alib_protos.h. When compiling with Manx, a warning seems to be generated for each string constant assigned to a UBYTE * field, and also by some references to ilbm->colortable. LIST OF IFFP MODULES AND APPLICATIONS ------------------------------------- NOTE - Some useful functions are listed with each module See module source code for docs on each function. APPLICATIONS (these require linkage with modules - see Makefiles) ------------ ILBMDemo Displays an ILBM, loads a brush, saves an ILBM, opt. print ILBMLoad Queries an ILBM and loads it into an existing screen ILBMtoC Outputs an ILBM as C source code ILBMtoRaw Converts an ILBM to raw plane/color file RawtoILBM Converts raw plane/color file (from ILBMtoRaw) to an ILBM 24bitDemo Saves a simple 24-bit ILBM and then shows it 4 planes at a time (if given filename, just does the show part) Play8SVX Reads and plays an 8SVX sound effect or instrument - LoadSample, UnloadSample, PlaySample, OpenAudio, CloseAudio, and body load/unpack functions ScreenSave Save the front screen as an ILBM, with an icon OTHER EXAMPLES (use iffparse.library directly and require no modules) -------------- Sift Checks and prints outline of any IFF file (uses RAWSTEP) ILBMScan Prints out useful info about any ILBM ClipFTXT Demonstrates simply clipping of FTXT to/from clipboard cycvb.c Dan Silva's routine for interrupt based color cycling apack.asm Dr. Gerald Hull's assembler replacement for packer.c GENERAL IFFPARSE SUPPORT MODULE ------------------------------- parse.c File/clipboard IO and general parsing - openifile, closeifile, parseifile, getcontext, nextcontext, contextis, currentchunkis, PutCk chunk writing function, and IFFerr text error routine ILBM READ MODULES ----------------- loadilbm.c High level ILBM load routines which are passed filenames (calls getbitmap) - loadbrush/unloadbrush,loadilbm/unloadilbm,and queryilbm getbitmap.c brush/bitmap loading (non-display, calls ilbmr.c) - createbrush/deletebrush, getbitmap/freebitmap getdisplay.c bitmap load/display (calls screen.c, ilbmr.c) - showilbm/unshowilbm, createdisplay/deletedisplay screen.c 1.3/2.0 ECS/non-ECS compatible screen/window module - opendisplay, openidscreen, modefallback, clipit ilbmr.c Lower level ILBM body/color load routines(calls unpacker.c) - loadbody, loadcmap, getcolors/freecolors, alloccolortable, getcamg (gets or creates modeid) unpacker.c BODY unpacker ILBM WRITE MODULES ------------------ saveilbm.c High level ILBM saving routines which are passed filenames (calls ilbmw.c) - screensave and saveilbm ilbmw.c Lower level ILBM body/color save routines (calls packer.c) - InitBMHD, PutCMAP, PutBODY packer.c BODY packer EXTRA MODULES ------------- copychunks.c Chunk cloning and chunk list writing routines - copychunks, findchunk, writechunklist, freechunklist screendump.c Screen printing module (iffparse not required) bmprintc.c Module to output ILBM as C code INCLUDE FILES ------------- iffp/#?.h This subdirectory may be kept in your current directory or in your main include directory. Thanks to Steve Walton for his code changes for Manx/SAS compatibility, and to Bill Barton and John Bittner for their comments and suggestions.
Makefile.SAS
#MYLIBS= LIB:debug.lib CC = lc ASM = asm CFLAGS = -cfistq -v -j73 -iINCLUDE: AFLAGS = -iINCLUDE: LFLAGS = SC BATCH ND M = modules/ A = apps/ # Our iffparse support object modules to link with IFFO = $(M)parse.o $(M)Hook.o ILBMRO = $(M)ilbmr.o $(M)unpacker.o ILBMSO = $(M)getdisplay.o $(M)screen.o ILBMLO = $(M)loadilbm.o $(M)getbitmap.o ILBMWO = $(M)saveilbm.o $(M)ilbmw.o $(M)packer.o ILBMO = $(IFFO) $(ILBMRO) $(ILBMLO) $(ILBMSO) $(ILBMWO) EXTRAO = $(M)copychunks.o $(M)screendump.o $(M)bmprintc.o # Our iffparse applications APP1 = $(A)ILBMDemo/ILBMDemo APP2 = $(A)ILBMLoad/ILBMLoad APP3 = $(A)Play8SVX/Play8SVX APP4 = $(A)ILBMtoC/ILBMtoC APP5 = $(A)ILBMtoRaw/ILBMtoRaw APP6 = $(A)ScreenSave/ScreenSave APP7 = $(A)RawtoILBM/RawtoILBM APP8 = $(A)24bitDemo/24bitDemo # The object modules needed by each application example APP1O = $(APP1).o $(ILBMO) $(M)screendump.o $(M)copychunks.o APP2O = $(APP2).o $(IFFO) $(ILBMRO) $(ILBMLO) $(ILBMSO) APP3O = $(APP3).o $(IFFO) APP4O = $(APP4).o $(IFFO) $(ILBMRO) $(ILBMLO) $(M)bmprintc.o APP5O = $(APP5).o $(IFFO) $(ILBMRO) $(ILBMLO) APP6O = $(APP6).o $(IFFO) $(ILBMWO) APP7O = $(APP7).o $(IFFO) $(ILBMWO) APP8O = $(APP8).o $(IFFO) $(ILBMRO) $(ILBMLO) $(ILBMSO) $(ILBMWO) .SUFFIXES: .SUFFIXES: .o .c .h .asm .i # Make all of the applications all: $(APP1) $(APP2) $(APP3) $(APP4) $(APP5) $(APP6) $(APP7) $(APP8) # Linkage for each application $(APP1): $(APP1O) blink <WITH < FROM lib:c.o $(APP1O) LIBRARY lib:lc.lib LIB:amiga.lib $(MYLIBS) TO $(APP1) $(LFLAGS) < $(APP2): $(APP2O) blink <WITH < FROM lib:c.o $(APP2O) LIBRARY lib:lc.lib LIB:amiga.lib $(MYLIBS) TO $(APP2) $(LFLAGS) < $(APP3): $(APP3O) blink <WITH < FROM lib:c.o $(APP3O) LIBRARY lib:lc.lib LIB:amiga.lib $(MYLIBS) TO $(APP3) $(LFLAGS) < $(APP4): $(APP4O) blink <WITH < FROM lib:c.o $(APP4O) LIBRARY lib:lc.lib LIB:amiga.lib $(MYLIBS) TO $(APP4) $(LFLAGS) < $(APP5): $(APP5O) blink <WITH < FROM lib:c.o $(APP5O) LIBRARY lib:lc.lib LIB:amiga.lib $(MYLIBS) TO $(APP5) $(LFLAGS) < $(APP6): $(APP6O) blink <WITH < FROM lib:c.o $(APP6O) LIBRARY lib:lc.lib LIB:amiga.lib $(MYLIBS) TO $(APP6) $(LFLAGS) < $(APP7): $(APP7O) blink <WITH < FROM lib:c.o $(APP7O) LIBRARY lib:lc.lib LIB:amiga.lib $(MYLIBS) TO $(APP7) $(LFLAGS) < $(APP8): $(APP8O) blink <WITH < FROM lib:c.o $(APP8O) LIBRARY lib:lc.lib LIB:amiga.lib $(MYLIBS) TO $(APP8) $(LFLAGS) < .c.o: $(CC) $(CFLAGS) $*.c .asm.o: $(ASM) $(AFLAGS) $*.asm
iffp/8svx.h
/*-----------------------------------------------------------------------* * 8SVX.H Definitions for 8-bit sampled voice (VOX). 2/10/86 * * By Jerry Morrison and Steve Hayes, Electronic Arts. * This software is in the public domain. * * Modified for use with iffparse.library 05/91 - CAS_CBM * * This version for the Amiga computer. *----------------------------------------------------------------------*/ #ifndef EIGHTSVX_H #define EIGHTSVX_H #ifndef COMPILER_H #include "iffp/compiler.h" #endif #include "iffp/iff.h" #define ID_8SVX MAKE_ID('8', 'S', 'V', 'X') #define ID_VHDR MAKE_ID('V', 'H', 'D', 'R') #define ID_ATAK MAKE_ID('A', 'T', 'A', 'K') #define ID_RLSE MAKE_ID('R', 'L', 'S', 'E') /* defined in iffp/iff.h #define ID_NAME MAKE_ID('N', 'A', 'M', 'E') #define ID_Copyright MAKE_ID('(', 'c', ')', ' ') #define ID_AUTH MAKE_ID('A', 'U', 'T', 'H') #define ID_ANNO MAKE_ID('A', 'N', 'N', 'O') #define ID_BODY MAKE_ID('B', 'O', 'D', 'Y') */ /* ---------- Voice8Header ---------------------------------------------*/ typedef LONG Fixed; /* A fixed-point value, 16 bits to the left of * the point and 16 to the right. A Fixed is a * number of 2**16ths, i.e. 65536ths. */ #define Unity 0x10000L /* Unity = Fixed 1.0 = maximum volume */ /* sCompression: Choice of compression algorithm applied to the samples. */ #define sCmpNone 0 /* not compressed */ #define sCmpFibDelta 1 /* Fibonacci-delta encoding (Appendix C) */ /* Could be more kinds in the future. */ typedef struct { ULONG oneShotHiSamples, /* # samples in the high octave 1-shot part */ repeatHiSamples, /* # samples in the high octave repeat part */ samplesPerHiCycle; /* # samples/cycle in high octave, else 0 */ UWORD samplesPerSec; /* data sampling rate */ UBYTE ctOctave, /* # of octaves of waveforms */ sCompression; /* data compression technique used */ Fixed volume; /* playback nominal volume from 0 to Unity * (full volume). Map this value into * the output hardware's dynamic range. */ } Voice8Header; /* ---------- NAME -----------------------------------------------------*/ /* NAME chunk contains a CHAR[], the voice's name. */ /* ---------- Copyright ------------------------------------------------*/ /* "(c) " chunk contains a CHAR[], the FORM's copyright notice. */ /* ---------- AUTH -----------------------------------------------------*/ /* AUTH chunk contains a CHAR[], the author's name. */ /* ---------- ANNO -----------------------------------------------------*/ /* ANNO chunk contains a CHAR[], the author's text annotations. */ /* ---------- Envelope ATAK & RLSE -------------------------------------*/ typedef struct { UWORD duration; /* segment duration in milliseconds, > 0 */ Fixed dest; /* destination volume factor */ } EGPoint; /* ATAK and RLSE chunks contain an EGPoint[], piecewise-linear envelope. */ /* The envelope defines a function of time returning Fixed values. * It's used to scale the nominal volume specified in the Voice8Header. */ /* ---------- BODY -----------------------------------------------------*/ /* BODY chunk contains a BYTE[], array of audio data samples. */ /* (8-bit signed numbers, -128 through 127.) */ /* ---------- 8SVX Writer Support Routines -----------------------------*/ /* Just call this macro to write a VHDR chunk. */ #define PutVHDR(iff, vHdr) \ PutCk(iff, ID_VHDR, sizeof(Voice8Header), (BYTE *)vHdr) #endif
iffp/8svxapp.h
/* 8svxapp.h * - definition of EightSVXInfo structure * - inclusion of includes needed by modules and application * - application-specific definitions */ #ifndef EIGHTSVXAPP_H #define EIGHTSVXAPP_H #include "iffp/8svx.h" #include <devices/audio.h> #define MAXOCT 16 struct EightSVXInfo { /* general parse.c related */ struct ParseInfo ParseInfo; /* For convenient access to VHDR, Name, and sample. * Other chunks will be accessible through FindProp() * (or findchunk() if the chunks have been copied) */ /* 8SVX */ Voice8Header Vhdr; BYTE *sample; ULONG samplebytes; BYTE *osamps[MAXOCT]; ULONG osizes[MAXOCT]; BYTE *rsamps[MAXOCT]; ULONG rsizes[MAXOCT]; ULONG spcycs[MAXOCT]; UBYTE name[80]; ULONG Reserved[8]; /* must be 0 for now */ /* Applications may add variables here */ }; /* referenced by modules */ extern struct Library *IFFParseBase; #endif
iffp/amiga.h
/* IFF application include files */ #ifndef AMIGA_H #define AMIGA_H #include <exec/types.h> #include <exec/memory.h> #include <exec/libraries.h> #include <libraries/dos.h> #include <intuition/intuition.h> #include <intuition/screens.h> #include <graphics/view.h> #include <graphics/displayinfo.h> #include <graphics/videocontrol.h> #include <graphics/gfxmacros.h> #include <libraries/iffparse.h> #include <clib/exec_protos.h> #include <clib/dos_protos.h> #include <clib/intuition_protos.h> #include <clib/graphics_protos.h> #include <clib/iffparse_protos.h> #include <stdlib.h> #include <stdio.h> #include <string.h> #include "iffp/debug.h" #endif
iffp/compiler.h
#ifndef COMPILER_H #define COMPILER_H /*** compiler.h *********************************************************/ /* Steve Shaw 1/29/86 */ /* Portability file to handle compiler idiosyncrasies. */ /* */ /* This software is in the public domain. */ /* modified 05/91 for use with iffparse - CAS_CBM */ /************************************************************************/ #ifndef EXEC_TYPES_H #include "exec/types.h" #endif /* #define NO_PROTOS */ #endif COMPILER_H
iffp/debug.h
/* * mydebug.h - #include this file sometime after stdio.h * Set MYDEBUG to 1 to turn on debugging, 0 to turn off debugging */ #ifndef MYDEBUG_H #define MYDEBUG_H #define MYDEBUG 0 #if MYDEBUG /* * MYDEBUG User Options */ /* Set to 1 to turn second level D2(bug()) statements */ #define DEBUGLEVEL2 1 /* Set to a non-zero # of ticks if a delay is wanted after each debug message */ #define DEBUGDELAY 0 /* Always non-zero for the DDx macros */ #define DDEBUGDELAY 50 /* Set to 1 for serial debugging (link with debug.lib) */ #define KDEBUG 0 /* Set to 1 for parallel debugging (link with ddebug.lib) */ #define DDEBUG 0 #endif /* MYDEBUG */ /* Prototypes for Delay, kprintf, dprintf. Or use proto/dos.h or functions.h. */ #include <clib/dos_protos.h> void kprintf(UBYTE *fmt,...); void dprintf(UBYTE *fmt,...); /* * D(bug()), D2(bug()), DQ((bug()) only generate code if MYDEBUG is non-zero * * Use D(bug()) for general debugging, D2(bug()) for extra debugging that * you usually won't need to see, DD(bug()) for debugging statements that * you always want followed by a delay, and DQ(bug()) for debugging that * you'll NEVER want a delay after (ie. debugging inside a Forbid, Disable, * Task, or Interrupt) * * Some example uses (all are used the same): * D(bug("about to do xyz. variable = $%lx\n",myvariable)); * D2(bug("v1=$%lx v2=$%lx v3=$%lx\n",v1,v2,v3)); * DQ(bug("in subtask: variable = $%lx\n",myvariable)); * DD(bug("About to do xxx\n")); * * Set MYDEBUG above to 1 when debugging is desired and recompile the modules * you wish to debug. Set to 0 and recompile to turn off debugging. * * User options set above: * Set DEBUGDELAY to a non-zero # of ticks (ex. 50) when a delay is desired. * Set DEBUGLEVEL2 nonzero to turn on second level (D2) debugging statements * Set KDEBUG to 1 and link with debug.lib for serial debugging. * Set DDEBUG to 1 and link with ddebug.lib for parallel debugging. */ /* * Debugging function automaticaly set to printf, kprintf, or dprintf */ #if KDEBUG #define bug kprintf #elif DDEBUG #define bug dprintf #else /* else changes all bug's to printf's */ #define bug printf #endif /* * Debugging macros */ /* D(bug( delays DEBUGDELAY if DEBUGDELAY is > 0 * DD(bug( always delays DDEBUGDELAY * DQ(bug( (debug quick) never uses Delay. Use in forbids,disables,ints * The similar macros with "2" in their names are second level debugging */ #if MYDEBUG /* Turn on first level debugging */ #define D(x) (x); if(DEBUGDELAY>0) Delay(DEBUGDELAY) #define DD(x) (x); Delay(DDEBUGDELAY) #define DQ(x) (x) #if DEBUGLEVEL2 /* Turn on second level debugging */ #define D2(x) (x); if(DEBUGDELAY>0) Delay(DEBUGDELAY) #define DD2(x) (x); Delay(DDEBUGDELAY) #define DQ2(x) (x) #else /* Second level debugging turned off */ #define D2(x) ; #define DD2(x) ; #define DQ2(x) ; #endif /* DEBUGLEVEL2 */ #else /* First level debugging turned off */ #define D(x) ; #define DQ(x) ; #define D2(x) ; #define DD(x) ; #endif #endif /* MYDEBUG_H */
iffp/iff.h
/* * * iff.h: General Definitions for IFFParse modules * * 6/27/91 */ #ifndef IFFP_IFF_H #define IFFP_IFF_H #include "iffp/compiler.h" #ifndef EXEC_TYPES_H #include <exec/types.h> #endif #ifndef EXEC_MEMORY_H #include <exec/memory.h> #endif #ifndef UTILITY_TAGITEM_H #include <utility/tagitem.h> #endif #ifndef UTILITY_HOOKS_H #include <utility/hooks.h> #endif #ifndef LIBRARIES_IFFPARSE_H #include <libraries/iffparse.h> #endif #include <stdio.h> #include <stdlib.h> #include <string.h> #ifndef MYDEBUG_H #include "iffp/debug.h" #endif #ifndef NO_PROTOS #include <clib/exec_protos.h> #include <clib/iffparse_protos.h> #endif #ifndef MAX #define MAX(a,b) ((a) > (b) ? (a) : (b)) #endif #ifndef MIN #define MIN(a,b) ((a) < (b) ? (a) : (b)) #endif #ifndef ABS #define ABS(x) ((x) < 0 ? -(x) : (x)) #endif #define CkErr(expression) {if (!error) error = (expression);} #define ChunkMoreBytes(cn) (cn->cn_Size - cn->cn_Scan) #define IS_ODD(a) (a & 1) #define IFF_OKAY 0L #define CLIENT_ERROR 1L #define NOFILE 5L #define message printf /* Generic Chunk ID's we may encounter */ #define ID_ANNO MAKE_ID('A','N','N','O') #define ID_AUTH MAKE_ID('A','U','T','H') #define ID_CHRS MAKE_ID('C','H','R','S') #define ID_Copyright MAKE_ID('(','c',')',' ') #define ID_CSET MAKE_ID('C','S','E','T') #define ID_FVER MAKE_ID('F','V','E','R') #define ID_NAME MAKE_ID('N','A','M','E') #define ID_TEXT MAKE_ID('T','E','X','T') #define ID_BODY MAKE_ID('B','O','D','Y') /* Used to keep track of allocated IFFHandle, and whether file is * clipboard or not, filename, copied chunks, etc. * This structure is included in the beginning of every * form-specific info structure used by the example modules. */ struct ParseInfo { /* general parse.c related */ struct IFFHandle *iff; /* to be alloc'd with AllocIFF */ UBYTE *filename; /* current filename of this ui */ LONG *propchks; /* properties to get */ LONG *collectchks; /* properties to collect */ LONG *stopchks; /* stop on these (like BODY) */ BOOL opened; /* this iff has been opened */ BOOL clipboard; /* file is clipboard */ BOOL hunt; /* we are parsing a complex file */ BOOL Reserved1; /* must be zero for now */ /* for copychunks.c - for read/modify/write programs * and programs that need to keep parsed chunk info * around after closing file. * Deallocated by freechunklist(); */ struct Chunk *copiedchunks; /* application may hang its own list of new chunks here * just to keep it with the frame. */ struct Chunk *newchunks; ULONG Reserved[8]; }; /* * Used by some modules to save or pass a singly linked list of chunks */ struct Chunk { struct Chunk *ch_Next; long ch_Type; long ch_ID; long ch_Size; void *ch_Data; }; #ifndef NO_PROTOS /* parse.c */ LONG openifile(struct ParseInfo *,UBYTE *,ULONG); void closeifile(struct ParseInfo *); LONG parseifile(struct ParseInfo *, LONG, LONG, LONG *, LONG *, LONG *); LONG getcontext(struct IFFHandle *); LONG nextcontext(struct IFFHandle *); LONG currentchunkis(struct IFFHandle *, LONG type, LONG id); LONG contextis(struct IFFHandle *, LONG type, LONG id); UBYTE *findpropdata(struct IFFHandle *iff, LONG type, LONG id); void initiffasstdio(struct IFFHandle *); UBYTE *IFFerr(LONG); LONG chkcnt(LONG *); long PutCk(struct IFFHandle *iff, long id, long size, void *data); /* copychunks.c */ struct Chunk *copychunks(struct IFFHandle *iff, LONG *propchks, LONG *collectchks, ULONG memtype); void freechunklist(struct Chunk *first); struct Chunk *findchunk(struct Chunk *first, long type, long id); long writechunklist(struct IFFHandle *iff, struct Chunk *first); #endif /* NO_PROTOS */ #endif /* IFFP_IFF_H */
iffp/ilbm.h
/* * * ilbm.h: Definitions for IFFParse ILBM reader. * * 6/27/91 */ #ifndef IFFP_ILBM_H #define IFFP_ILBM_H #ifndef IFFP_IFF_H #include "iffp/iff.h" #endif #ifndef INTUITION_INTUITION_H #include <intuition/intuition.h> #endif #ifndef GRAPHICS_VIDEOCONTROL_H #include <graphics/videocontrol.h> #endif #ifndef NO_PROTOS #include <clib/graphics_protos.h> #include <clib/intuition_protos.h> #include <clib/alib_protos.h> #endif /* IFF types we may encounter */ #define ID_ILBM MAKE_ID('I','L','B','M') /* ILBM Chunk ID's we may encounter * (see iffp/iff.h for some other generic chunks) */ #define ID_BMHD MAKE_ID('B','M','H','D') #define ID_CMAP MAKE_ID('C','M','A','P') #define ID_CRNG MAKE_ID('C','R','N','G') #define ID_CCRT MAKE_ID('C','C','R','T') #define ID_GRAB MAKE_ID('G','R','A','B') #define ID_SPRT MAKE_ID('S','P','R','T') #define ID_DEST MAKE_ID('D','E','S','T') #define ID_CAMG MAKE_ID('C','A','M','G') /* Use this constant instead of sizeof(ColorRegister). */ #define sizeofColorRegister 3 typedef WORD Color4; /* Amiga RAM version of a color-register, * with 4 bits each RGB in low 12 bits.*/ /* Maximum number of bitplanes storable in BitMap structure */ #define MAXAMDEPTH 8 #define MAXAMCOLORREG 32 /* Maximum planes we can save */ #define MAXSAVEDEPTH 24 /* convert width to BytesPerRow */ #define BytesPerRow(w) ((w) + 15 >> 4 << 1) #define BitsPerRow(w) ((w) + 15 >> 4 << 4) /* Flags that should be masked out of old 16-bit CAMG before save or use. * Note that 32-bit mode id (non-zero high word) bits should not be twiddled */ #define BADFLAGS (SPRITES|VP_HIDE|GENLOCK_AUDIO|GENLOCK_VIDEO) #define OLDCAMGMASK (~BADFLAGS) /* Masking techniques */ #define mskNone 0 #define mskHasMask 1 #define mskHasTransparentColor 2 #define mskLasso 3 /* Compression techniques */ #define cmpNone 0 #define cmpByteRun1 1 #define RowBytes(w) ((((w) + 15) >> 4) << 1) /* ---------- BitMapHeader ---------------------------------------------*/ /* Required Bitmap header (BMHD) structure describes an ILBM */ typedef struct { UWORD w, h; /* Width, height in pixels */ WORD x, y; /* x, y position for this bitmap */ UBYTE nPlanes; /* # of planes (not including mask) */ UBYTE masking; /* a masking technique listed above */ UBYTE compression; /* cmpNone or cmpByteRun1 */ UBYTE reserved1; /* must be zero for now */ UWORD transparentColor; UBYTE xAspect, yAspect; WORD pageWidth, pageHeight; } BitMapHeader; /* ---------- ColorRegister --------------------------------------------*/ /* A CMAP chunk is a packed array of ColorRegisters (3 bytes each). */ typedef struct { UBYTE red, green, blue; /* MUST be UBYTEs so ">> 4" won't sign extend.*/ } ColorRegister; /* ---------- Point2D --------------------------------------------------*/ /* A Point2D is stored in a GRAB chunk. */ typedef struct { WORD x, y; /* coordinates (pixels) */ } Point2D; /* ---------- DestMerge ------------------------------------------------*/ /* A DestMerge is stored in a DEST chunk. */ typedef struct { UBYTE depth; /* # bitplanes in the original source */ UBYTE pad1; /* UNUSED; for consistency store 0 here */ UWORD planePick; /* how to scatter source bitplanes into destination */ UWORD planeOnOff; /* default bitplane data for planePick */ UWORD planeMask; /* selects which bitplanes to store into */ } DestMerge; /* ---------- SpritePrecedence -----------------------------------------*/ /* A SpritePrecedence is stored in a SPRT chunk. */ typedef UWORD SpritePrecedence; /* ---------- Camg Amiga Viewport Mode ---------------------------------*/ /* A Commodore Amiga ViewPort->Modes is stored in a CAMG chunk. */ /* The chunk's content is declared as a LONG. */ typedef struct { ULONG ViewModes; } CamgChunk; /* ---------- CRange cycling chunk -------------------------------------*/ #define RNG_NORATE 36 /* Dpaint uses this rate to mean non-active */ /* A CRange is store in a CRNG chunk. */ typedef struct { WORD pad1; /* reserved for future use; store 0 here */ WORD rate; /* 60/sec=16384, 30/sec=8192, 1/sec=16384/60=273 */ WORD active; /* bit0 set = active, bit 1 set = reverse */ UBYTE low, high; /* lower and upper color registers selected */ } CRange; /* ---------- Ccrt (Graphicraft) cycling chunk -------------------------*/ /* A Ccrt is stored in a CCRT chunk. */ typedef struct { WORD direction; /* 0=don't cycle, 1=forward, -1=backwards */ UBYTE start; /* range lower */ UBYTE end; /* range upper */ LONG seconds; /* seconds between cycling */ LONG microseconds; /* msecs between cycling */ WORD pad; /* future exp - store 0 here */ } CcrtChunk; /* If you are writing all of your chunks by hand, * you can use these macros for these simple chunks. */ #define putbmhd(iff, bmHdr) \ PutCk(iff, ID_BMHD, sizeof(BitMapHeader), (BYTE *)bmHdr) #define putgrab(iff, point2D) \ PutCk(iff, ID_GRAB, sizeof(Point2D), (BYTE *)point2D) #define putdest(iff, destMerge) \ PutCk(iff, ID_DEST, sizeof(DestMerge), (BYTE *)destMerge) #define putsprt(iff, spritePrec) \ PutCk(iff, ID_SPRT, sizeof(SpritePrecedence), (BYTE *)spritePrec) #define putcamg(iff, camg) \ PutCk(iff, ID_CAMG, sizeof(CamgChunk),(BYTE *)camg) #define putcrng(iff, crng) \ PutCk(iff, ID_CRNG, sizeof(CRange),(BYTE *)crng) #define putccrt(iff, ccrt) \ PutCk(iff, ID_CCRT, sizeof(CcrtChunk),(BYTE *)ccrt) #ifndef NO_PROTOS /* unpacker.c */ BOOL unpackrow(BYTE **pSource, BYTE **pDest, WORD srcBytes0, WORD dstBytes0); /* packer.c */ LONG packrow(BYTE **pSource, BYTE **pDest, LONG rowSize); /* ilbmr.c ILBM reader routines */ LONG loadbody(struct IFFHandle *iff, struct BitMap *bitmap, BitMapHeader *bmhd); LONG loadbody2(struct IFFHandle *iff, struct BitMap *bitmap, BYTE *mask, BitMapHeader *bmhd, BYTE *buffer, ULONG bufsize); LONG loadcmap(struct IFFHandle *, WORD *colortable, USHORT *pNcolors); LONG getcolors(struct ILBMInfo *ilbm); void freecolors(struct ILBMInfo *ilbm); LONG alloccolortable(struct ILBMInfo *ilbm); ULONG getcamg(struct ILBMInfo *ilbm); /* ilbmw.c ILBM writer routines */ long initbmhd(BitMapHeader *bmhd, struct BitMap *bitmap, WORD masking, WORD compression, WORD transparentColor, WORD width, WORD height, WORD pageWidth, WORD pageHeight, ULONG modeid); long putcmap(struct IFFHandle *iff,APTR colortable,UWORD ncolors,UWORD bitspergun); long putbody(struct IFFHandle *iff, struct BitMap *bitmap, BYTE *mask, BitMapHeader *bmHdr, BYTE *buffer, LONG bufsize); /* getdisplay.c (used to load a display) */ LONG showilbm(struct ILBMInfo *ilbm, UBYTE *filename); void unshowilbm(struct ILBMInfo *ilbm); LONG createdisplay(struct ILBMInfo *); void deletedisplay(struct ILBMInfo *); LONG getdisplay(struct ILBMInfo *); void freedisplay(struct ILBMInfo *); /* getbitmap.c (used if just loading brush or bitmap) */ LONG createbrush(struct ILBMInfo *); void deletebrush(struct ILBMInfo *); LONG getbitmap(struct ILBMInfo *); void freebitmap(struct ILBMInfo *); /* screen.c (opens 1.3 or 2.0 screen) */ struct Screen *openidscreen(struct ILBMInfo *,SHORT,SHORT,SHORT,ULONG); struct Window *opendisplay(struct ILBMInfo *,SHORT,SHORT,SHORT,ULONG); ULONG modefallback(ULONG, SHORT, SHORT, SHORT); void clipit(SHORT wide, SHORT high, struct Rectangle *spos, struct Rectangle *dclip, struct Rectangle *txto, struct Rectangle *stdo,struct Rectangle *maxo, struct Rectangle * uclip); void closedisplay(struct ILBMInfo *); void modeErrorMsg(ULONG,ULONG); /* loadilbm.c */ LONG loadbrush(struct ILBMInfo *ilbm, UBYTE *filename); void unloadbrush(struct ILBMInfo *ilbm); LONG queryilbm(struct ILBMInfo *ilbm, UBYTE *filename); LONG loadilbm(struct ILBMInfo *ilbm, UBYTE *filename); void unloadilbm(struct ILBMInfo *ilbm); /* saveilbm.c */ LONG screensave(struct ILBMInfo *ilbm, struct Screen *scr, struct Chunk *chunklist1, struct Chunk *chunklist2, UBYTE *filename); LONG saveilbm(struct ILBMInfo *ilbm, struct BitMap *bitmap, ULONG modeid, WORD width, WORD height, WORD pagewidth, WORD pageheight, APTR colortable, UWORD count, UWORD bitspergun, WORD masking, WORD transparentColor, struct Chunk *chunklist1, struct Chunk *chunklist2, UBYTE *filename); /* screendump.c (print screen or brush) */ int screendump(struct Screen *scr, UWORD srcx, UWORD srcy, UWORD srcw, UWORD srch, LONG destcols, UWORD special); /* bmprintc.c (write C source for ILBM) */ void BMPrintCRep(struct BitMap *bm, FILE *fp, UBYTE *name, UBYTE *fmt); #endif /* NO_PROTOS */ #endif /* IFFP_ILBM_H */
iffp/ilbmapp.h
/* ilbmapp.h * - definition of ILBMInfo structure * - inclusion of includes needed by modules and application * - application-specific definitions * * 07/03/91 - added ilbm->stags for screen.c */ #ifndef ILBMAPP_H #define ILBMAPP_H #include "iffp/ilbm.h" struct ILBMInfo { /* general parse.c related */ struct ParseInfo ParseInfo; /* The following variables are for * programs using the ILBM-related modules. * They may be removed or replaced for * programs parsing other forms. */ /* ILBM */ BitMapHeader Bmhd; /* filled in by load and save ops */ ULONG camg; /* filled in by load and save ops */ Color4 *colortable; /* allocated by getcolors */ ULONG ctabsize; /* size of colortable in bytes */ USHORT ncolors; /* number of color registers loaded */ USHORT Reserved1; /* for getbitmap.c */ struct BitMap *brbitmap; /* for loaded brushes only */ /* for screen.c */ struct Screen *scr; /* screen of loaded display */ struct Window *win; /* window of loaded display */ struct ViewPort *vp; /* viewport of loaded display */ struct RastPort *srp; /* screen's rastport */ struct RastPort *wrp; /* window's rastport */ BOOL TBState; /* state of titlebar hiddenness */ /* caller preferences */ struct NewWindow *windef; /* definition for window */ UBYTE *stitle; /* screen title */ LONG stype; /* additional screen types */ WORD ucliptype; /* overscan display clip type */ BOOL EHB; /* default to EHB for 6-plane/NoCAMG */ BOOL Video; /* Max Video Display Clip (non-adjustable) */ BOOL Autoscroll; /* Enable Autoscroll of screens */ BOOL Notransb; /* Borders not transparent to genlock */ ULONG *stags; /* Additional screen tags for 2.0 screens */ ULONG Reserved[7]; /* must be 0 for now */ /* Application-specific variables may go here */ }; /* referenced by modules */ extern struct Library *IFFParseBase; /* protos for application module(s) */ #endif
iffp/packer.h
#ifndef PACKER_H #define PACKER_H /*----------------------------------------------------------------------* * PACKER.H typedefs for Data-Compresser. 1/22/86 * * This module implements the run compression algorithm "cmpByteRun1"; the * same encoding generated by Mac's PackBits. * * By Jerry Morrison and Steve Shaw, Electronic Arts. * This software is in the public domain. * * This version for the Commodore-Amiga computer. *----------------------------------------------------------------------*/ #include <exec/types.h> /* This macro computes the worst case packed size of a "row" of bytes. */ #define MaxPackedSize(rowSize) ( (rowSize) + ( ((rowSize)+127) >> 7 ) ) /* Given POINTERS to POINTER variables, packs one row, updating the source * and destination pointers. Returns the size in bytes of the packed row. * ASSUMES destination buffer is large enough for the packed row. * See MaxPackedSize. */ extern LONG PackRow(BYTE **, BYTE **, LONG); /* pSource, pDest, rowSize */ /* Given POINTERS to POINTER variables, unpacks one row, updating the source * and destination pointers until it produces dstBytes bytes (i.e., the * rowSize that went into PackRow). * If it would exceed the source's limit srcBytes or if a run would overrun * the destination buffer size dstBytes, it stops and returns TRUE. * Otherwise, it returns FALSE (no error). */ extern BOOL UnPackRow(BYTE **, BYTE **, WORD, WORD); /* pSource, pDest, srcBytes, dstBytes */ BYTE *PutDump(BYTE *, int); BYTE *PutRun(BYTE *,int,int); LONG PackRow(BYTE **,BYTE **,LONG); BOOL UnPackRow(BYTE **,BYTE **,WORD,WORD); #endif
iffp/smus.h
/*----------------------------------------------------------------------* * SMUS.H Definitions for Simple MUSical score. 2/12/86 * * By Jerry Morrison and Steve Hayes, Electronic Arts. * This software is in the public domain. * * Modified for use with iffparse.library 05/91 - CAS_CBM * * This version for the Commodore-Amiga computer. *----------------------------------------------------------------------*/ #ifndef SMUS_H #define SMUS_H #ifndef COMPILER_H #include "iffp/compiler.h" #endif #include "iffp/iff.h" #define ID_SMUS MAKE_ID('S', 'M', 'U', 'S') #define ID_SHDR MAKE_ID('S', 'H', 'D', 'R') /* Now defined in iffp/iff.h as generic chunks #define ID_NAME MAKE_ID('N', 'A', 'M', 'E') #define ID_Copyright MAKE_ID('(', 'c', ')', ' ') #define ID_AUTH MAKE_ID('A', 'U', 'T', 'H') #define ID_ANNO MAKE_ID('A', 'N', 'N', 'O') */ #define ID_INS1 MAKE_ID('I', 'N', 'S', '1') #define ID_TRAK MAKE_ID('T', 'R', 'A', 'K') /* ---------- SScoreHeader ---------------------------------------------*/ typedef struct { UWORD tempo; /* tempo, 128ths quarter note/minute */ UBYTE volume; /* playback volume 0 through 127 */ UBYTE ctTrack; /* count of tracks in the score */ } SScoreHeader; /* ---------- NAME -----------------------------------------------------*/ /* NAME chunk contains a CHAR[], the musical score's name. */ /* ---------- Copyright (c) --------------------------------------------*/ /* "(c) " chunk contains a CHAR[], the FORM's copyright notice. */ /* ---------- AUTH -----------------------------------------------------*/ /* AUTH chunk contains a CHAR[], the name of the score's author. */ /* ---------- ANNO -----------------------------------------------------*/ /* ANNO chunk contains a CHAR[], the author's text annotations. */ /* ---------- INS1 -----------------------------------------------------*/ /* Constants for the RefInstrument's "type" field. */ #define INS1_Name 0 /* just use the name; ignore data1, data2 */ #define INS1_MIDI 1 /* <data1, data2> = MIDI <channel, preset> */ typedef struct { UBYTE iRegister; /* set this instrument register number */ UBYTE type; /* instrument reference type (see above) */ UBYTE data1, data2; /* depends on the "type" field */ char name[60]; /* instrument name */ } RefInstrument; /* ---------- TRAK -----------------------------------------------------*/ /* TRAK chunk contains an SEvent[]. */ /* SEvent: Simple musical event. */ typedef struct { UBYTE sID; /* SEvent type code */ UBYTE data; /* sID-dependent data */ } SEvent; /* SEvent type codes "sID". */ #define SID_FirstNote 0 #define SID_LastNote 127 /* sIDs in the range SID_FirstNote through * SID_LastNote (sign bit = 0) are notes. The * sID is the MIDI tone number (pitch). */ #define SID_Rest 128 /* a rest; same data format as a note. */ #define SID_Instrument 129 /* set instrument number for this track. */ #define SID_TimeSig 130 /* set time signature for this track. */ #define SID_KeySig 131 /* set key signature for this track. */ #define SID_Dynamic 132 /* set volume for this track. */ #define SID_MIDI_Chnl 133 /* set MIDI channel number (sequencers) */ #define SID_MIDI_Preset 134 /* set MIDI preset number (sequencers) */ #define SID_Clef 135 /* inline clef change. * 0=Treble, 1=Bass, 2=Alto, 3=Tenor. */ #define SID_Tempo 136 /* Inline tempo change in beats per minute.*/ /* SID values 144 through 159: reserved for Instant Music SEvents. */ /* The remaining sID values up through 254: reserved for future * standardization. */ #define SID_Mark 255 /* SID reserved for an end-mark in RAM. */ /* ---------- SEvent FirstNote..LastNote or Rest -----------------------*/ typedef struct { unsigned tone :8, /* MIDI tone number 0 to 127; 128 = rest */ chord :1, /* 1 = a chorded note */ tieOut :1, /* 1 = tied to the next note or chord */ nTuplet :2, /* 0 = none, 1 = triplet, 2 = quintuplet, * 3 = septuplet */ dot :1, /* dotted note; multiply duration by 3/2 */ division :3; /* basic note duration is 2**-division: * 0 = whole note, 1 = half note, 2 = quarter * note, ... 7 = 128th note */ } SNote; /* Warning: An SNote is supposed to be a 16-bit entity. * Some C compilers will not pack bit fields into anything smaller * than an int. So avoid the actual use of this type unless you are certain * that the compiler packs it into a 16-bit word. */ /* You may get better object code by masking, ORing, and shifting using the * following definitions rather than the bit-packed fields, above. */ #define noteChord (1<<7) /* note is chorded to next note */ #define noteTieOut (1<<6) /* note/chord is tied to next note/chord */ #define noteNShift 4 /* shift count for nTuplet field */ #define noteN3 (1<<noteNShift) /* note is a triplet */ #define noteN5 (2<<noteNShift) /* note is a quintuplet */ #define noteN7 (3<<noteNShift) /* note is a septuplet */ #define noteNMask noteN7 /* bit mask for the nTuplet field */ #define noteDot (1<<3) /* note is dotted */ #define noteDShift 0 /* shift count for division field */ #define noteD1 (0<<noteDShift) /* whole note division */ #define noteD2 (1<<noteDShift) /* half note division */ #define noteD4 (2<<noteDShift) /* quarter note division */ #define noteD8 (3<<noteDShift) /* eighth note division */ #define noteD16 (4<<noteDShift) /* sixteenth note division */ #define noteD32 (5<<noteDShift) /* thirty-secondth note division */ #define noteD64 (6<<noteDShift) /* sixty-fourth note division */ #define noteD128 (7<<noteDShift) /* 1/128 note division */ #define noteDMask noteD128 /* bit mask for the division field */ #define noteDurMask 0x3F /* bit mask for all duration fields * division, nTuplet, dot */ /* Field access: */ #define IsChord(snote) (((UWORD)snote) & noteChord) #define IsTied(snote) (((UWORD)snote) & noteTieOut) #define NTuplet(snote) ((((UWORD)snote) & noteNMask) >> noteNShift) #define IsDot(snote) (((UWORD)snote) & noteDot) #define Division(snote) ((((UWORD)snote) & noteDMask) >> noteDShift) /* ---------- TimeSig SEvent -------------------------------------------*/ typedef struct { unsigned type :8, /* = SID_TimeSig */ timeNSig :5, /* time signature "numerator" timeNSig + 1 */ timeDSig :3; /* time signature "denominator" is * 2**timeDSig: 0 = whole note, 1 = half * note, 2 = quarter note, ... * 7 = 128th note */ } STimeSig; #define timeNMask 0xF8 /* bit mask for timeNSig field */ #define timeNShift 3 /* shift count for timeNSig field */ #define timeDMask 0x07 /* bit mask for timeDSig field */ /* Field access: */ #define TimeNSig(sTime) ((((UWORD)sTime) & timeNMask) >> timeNShift) #define TimeDSig(sTime) (((UWORD)sTime) & timeDMask) /* ---------- KeySig SEvent --------------------------------------------*/ /* "data" value 0 = Cmaj; 1 through 7 = G,D,A,E,B,F#,C#; * 8 through 14 = F,Bb,Eb,Ab,Db,Gb,Cb. */ /* ---------- Dynamic SEvent -------------------------------------------*/ /* "data" value is a MIDI key velocity 0..127. */ /* ---------- SMUS Writer Support Routines -----------------------------*/ /* Just call this to write a SHDR chunk. */ #define PutSHDR(iff, ssHdr) \ PutCk(iff, ID_SHDR, sizeof(SScoreHeader), (BYTE *)ssHdr) #endif
apps/24bitDemo/24bitDemo.c
/* 24bitDemo.c 05/91 C. Scheppner CBM * * Example which creates a 24-bit raster, saves it as a 24-bit ILBM, * then loads it as a brush and shows it to you 4 planes at a time * Optionally (if given a filename) just displays 4 planes at a time. * * requires linkage with several IFF modules * see Makefile */ #include "iffp/ilbmapp.h" #ifdef LATTICE int CXBRK(void) { return(0); } /* Disable Lattice CTRL/C handling */ int chkabort(void) { return(0); } /* really */ #endif void cleanup(void); void bye(UBYTE *s,int error); #define MINARGS 1 char *vers = "\0$VER: 24bitDemo 37.5"; char *Copyright = "24bitDemo v37.5 (Freely Redistributable)"; char *usage = "Usage: 24bitDemo [loadname] (saves/loads if no loadname given)"; struct Library *IntuitionBase = NULL; struct Library *GfxBase = NULL; struct Library *IFFParseBase = NULL; /* Note - these fields are also available in the ILBMInfo structure */ struct Screen *scr; /* for ptr to screen structure */ struct Window *win; /* for ptr to window structure */ struct RastPort *wrp; /* for ptr to RastPort */ struct ViewPort *vp; /* for ptr to Viewport */ struct NewWindow mynw = { 0, 0, /* LeftEdge and TopEdge */ 0, 0, /* Width and Height */ -1, -1, /* DetailPen and BlockPen */ VANILLAKEY|MOUSEBUTTONS, /* IDCMP Flags with Flags below */ BACKDROP|BORDERLESS|SMART_REFRESH|NOCAREREFRESH|ACTIVATE|RMBTRAP, NULL, NULL, /* Gadget and Image pointers */ NULL, /* Title string */ NULL, /* Screen ptr null till opened */ NULL, /* BitMap pointer */ 50, 20, /* MinWidth and MinHeight */ 0 , 0, /* MaxWidth and MaxHeight */ CUSTOMSCREEN /* Type of window */ }; BOOL FromWb; /* ILBM Property chunks to be grabbed * List BMHD, CMAP and CAMG first so we can skip them when we write * the file back out (they will be written out with separate code) */ LONG ilbmprops[] = { ID_ILBM, ID_BMHD, ID_ILBM, ID_CMAP, ID_ILBM, ID_CAMG, ID_ILBM, ID_CCRT, ID_ILBM, ID_AUTH, ID_ILBM, ID_Copyright, TAG_DONE }; /* ILBM Collection chunks (more than one in file) to be gathered */ LONG ilbmcollects[] = { ID_ILBM, ID_CRNG, TAG_DONE }; /* ILBM Chunk to stop on */ LONG ilbmstops[] = { ID_ILBM, ID_BODY, TAG_DONE }; UBYTE nomem[] = "Not enough memory\n"; UBYTE noiffh[] = "Can't alloc iff\n"; /* For our allocated ILBM frames */ struct ILBMInfo *ilbm[2]; #define SCRPLANES 4 USHORT colortable[32]; USHORT cstarts[]= { 0x000, 0x800, 0x000, 0x080, 0x000, 0x008 }; USHORT coffs[] = { 0x100, 0x100, 0x010, 0x010, 0x001, 0x001 }; UBYTE *ilbmname = "RAM:24bit.ilbm"; UBYTE *rgbnames[]={"R0","R1","R2","R3","R4","R5","R6","R7", "G0","G1","G2","G3","G4","G5","G6","G7", "B0","B1","B2","B3","B4","B5","B6","B7" }; UBYTE *endtext1 = "Displayed 24 planes, 4 at a time."; UBYTE *endtext2 = "Press mousebutton or key to exit."; /* * MAIN */ void main(int argc, char **argv) { struct RastPort *rp = NULL; struct BitMap dummy = {0}; struct BitMap *bm = NULL, *xbm, *sbm; LONG error = 0L; USHORT width, height, depth, pwidth, pheight, pmode, extra, rgb; ULONG plsize; UBYTE *tpp; BOOL DoSave = TRUE; int k, p, s, n; FromWb = argc ? FALSE : TRUE; if((argc > 1)&&(argv[argc-1][0]=='?')) { printf("%s\n%s\n",Copyright,usage); bye("",RETURN_OK); } if(argc==2) { ilbmname = argv[1]; DoSave = FALSE; } /* Open Libraries */ if(!(IntuitionBase = OpenLibrary("intuition.library", 0))) bye("Can't open intuition library.\n",RETURN_WARN); if(!(GfxBase = OpenLibrary("graphics.library",0))) bye("Can't open graphics library.\n",RETURN_WARN); if(!(IFFParseBase = OpenLibrary("iffparse.library",0))) bye("Can't open iffparse library.\n",RETURN_WARN); /* * Alloc ILBMInfo structs */ if(!(ilbm[0] = (struct ILBMInfo *) AllocMem(sizeof(struct ILBMInfo),MEMF_PUBLIC|MEMF_CLEAR))) bye(nomem,RETURN_FAIL); if(!(ilbm[1] = (struct ILBMInfo *) AllocMem(sizeof(struct ILBMInfo),MEMF_PUBLIC|MEMF_CLEAR))) bye(nomem,RETURN_FAIL); /* * Here we set up our ILBMInfo fields for our * application. * Above we have defined the propery and collection chunks * we are interested in (some required like BMHD) */ ilbm[0]->ParseInfo.propchks = ilbmprops; ilbm[0]->ParseInfo.collectchks = ilbmcollects; ilbm[0]->ParseInfo.stopchks = ilbmstops; ilbm[0]->windef = &mynw; *ilbm[1] = *ilbm[0]; /* * Alloc IFF handles for frame */ if(!(ilbm[0]->ParseInfo.iff = AllocIFF())) bye(noiffh,RETURN_FAIL); if(!(ilbm[1]->ParseInfo.iff = AllocIFF())) bye(noiffh,RETURN_FAIL); /* for saving our demo 24-bit ILBM */ width = 320; height = 200; depth = 24; /* Page width, height, and mode for saved ILBM */ pwidth = width < 320 ? 320 : width; pheight = height < 200 ? 200 : height; pmode = pwidth >= 640 ? HIRES : 0L; pmode |= pheight >= 400 ? LACE : 0L; plsize = RASSIZE(width,height); if(!DoSave) goto nosave; /* * Allocate Bitmap and planes */ extra = depth > 8 ? depth - 8 : 0; if(ilbm[0]->brbitmap = AllocMem(sizeof(struct BitMap) + (extra<<2), MEMF_CLEAR)) { bm = ilbm[0]->brbitmap; InitBitMap(bm,depth,width,height); for(k=0, error=0; k<depth && (!error); k++) { if(!(bm->Planes[k] = AllocRaster(width,height))) error = IFFERR_NOMEM; if(! error) { BltClear(bm->Planes[k], RASSIZE(width,height),0); } } if(!error) { if(!(rp = AllocMem(sizeof(struct RastPort),MEMF_CLEAR))) error = IFFERR_NOMEM; else { InitRastPort(rp); rp->BitMap = bm; rp->Mask = 0x01; /* we'll render 1 plane at a time */ SetAPen(rp,1); SetDrMd(rp,JAM1); } } if(!error) { /* Put something recognizable in the planes. * Our bitmap is not part of a screen or viewport * so we can fiddle with the pointers and depth */ tpp = bm->Planes[0]; /* save first plane pointer */ bm->Depth = 1; for(k=0; k<depth; k++) /* swap in planeptrs 1 at a time */ { bm->Planes[0] = bm->Planes[k]; Move(rp,k * 10, (k * 8) + 8); /* render rgb bitname text */ Text(rp, rgbnames[k], 2); } bm->Depth = depth; /* restore depth */ bm->Planes[0] = tpp; /* and first pointer */ /* Save the 24-bit ILBM */ printf("Saving %s\n",ilbmname); error = saveilbm(ilbm[0], ilbm[0]->brbitmap, pmode, width, height, pwidth, pheight, NULL, 0, 0, /* colortable */ mskNone, 0, /* masking, transparent */ NULL, NULL, /* chunklists */ ilbmname); } /* Free our bitmap */ for(k=0; k<depth; k++) { if(ilbm[0]->brbitmap->Planes[k]) FreeRaster(ilbm[0]->brbitmap->Planes[k],width,height); } FreeMem(ilbm[0]->brbitmap, sizeof(struct BitMap) + (extra << 2)); ilbm[0]->brbitmap = NULL; if(rp) FreeMem(rp, sizeof(struct RastPort)); } if(error) { printf("%s\n",IFFerr(error)); bye(" ", RETURN_FAIL); } nosave: /* Normally you would use showilbm() to open an appropriate acreen * and display an ILBM in it. However, this is a 24-bit ILBM * so we will load it as a brush (bitmap). * Here we are demonstrating * - first querying an ILBM to get its BMHD and CAMG (real or computed) * - then opening our own display * - then loading the 24-bit ILBM as a brush (bitmap) and displaying * it 4 planes at a time in our 4-plane screen. */ printf("Attempting to load %s as a bitmap and display 4 planes at a time\n", ilbmname); if(!(error = queryilbm(ilbm[0],ilbmname))) { D(bug("24bitDemo: after query, this ILBM is %ld x %ld x %ld,modeid=$%lx\n", ilbm[0]->Bmhd.w, ilbm[0]->Bmhd.h, ilbm[0]->Bmhd.nPlanes, ilbm[0]->camg)); /* Note - you could use your own routines to open your * display, but if so, you must initialize ilbm[0]->scr, * ilbm[0]->win, ilbm[0]->wrp, ilbm[0]->srp, and ilbm[0]->vp for your * display. Here we will use opendisplay() which will initialize * those fields. */ if(!(opendisplay(ilbm[0], MAX(ilbm[0]->Bmhd.pageWidth, ilbm[0]->Bmhd.w), MAX(ilbm[0]->Bmhd.pageHeight,ilbm[0]->Bmhd.h), MIN(ilbm[0]->Bmhd.nPlanes, SCRPLANES), ilbm[0]->camg))) { printf("Failed to open display\n"); } else { D(bug("24bitDemo: opendisplay (%ld planes) successful\n",SCRPLANES)); scr = ilbm[0]->scr; win = ilbm[0]->win; wrp = ilbm[0]->wrp; vp = ilbm[0]->vp; if(!(error = loadbrush(ilbm[1], ilbmname))) { D(bug("24bitDemo: loadbrush successful\n")); /* Note - we don't need to examine or copy any * chunks from the file, so we will close file now */ closeifile(ilbm[0]); ScreenToFront(ilbm[0]->scr); xbm = &dummy; /* spare bitmap */ sbm = &scr->BitMap; /* screen's bitmap */ bm = ilbm[1]->brbitmap; /* the 24-plane bitmap */ depth = bm->Depth; InitBitMap(xbm,SCRPLANES,scr->Width,scr->Height); /* Show the 24 planes */ for(p=0; p<depth; p+=SCRPLANES) /* 4 at a time */ { SetRast(&scr->RastPort, 0); for(s=0; s<SCRPLANES; s++) { if((p+s) < depth) xbm->Planes[s] = bm->Planes[p+s]; else xbm->Planes[s] = NULL, xbm->Depth--; } /* Blit planes to the screen */ BltBitMap(xbm, 0, 0, sbm, 0, 0, scr->Width, scr->Height, 0xC0, 0x0F, NULL); /* Emulate 8-bit color with 4-bit per gun colors * by using each rgb value twice */ for(n=0, rgb=cstarts[p /SCRPLANES]; n < 16; n++) { if(!n) colortable[n] = 0xFFF; else colortable[n] = rgb; /* bump gun for every 2 planes since * we only have 8 bits per gun */ if(n & 1) rgb += coffs[ p / SCRPLANES]; } LoadRGB4(vp, colortable, 16); Delay(50); } SetRast(&scr->RastPort, 0); SetAPen(wrp, 1); Move(wrp, 24, 80); Text(wrp, endtext1, strlen(endtext1)); Move(wrp, 24, 120); Text(wrp, endtext2, strlen(endtext2)); Wait(1<<win->UserPort->mp_SigBit); unloadbrush(ilbm[1]); /* deallocs colors, closeifile if needed */ } closedisplay(ilbm[0]); printf("Done\n"); } } if(error) printf("%s\n",IFFerr(error)); cleanup(); exit(RETURN_OK); } void bye(UBYTE *s,int error) { if((*s)&&(!FromWb)) printf("%s\n",s); cleanup(); exit(error); } void cleanup() { if(ilbm[0]) { if(ilbm[0]->ParseInfo.iff) FreeIFF(ilbm[0]->ParseInfo.iff); FreeMem(ilbm[0],sizeof(struct ILBMInfo)); } if(ilbm[1]) { if(ilbm[1]->ParseInfo.iff) FreeIFF(ilbm[1]->ParseInfo.iff); FreeMem(ilbm[1],sizeof(struct ILBMInfo)); } if(GfxBase) CloseLibrary(GfxBase); if(IntuitionBase) CloseLibrary(IntuitionBase); if(IFFParseBase) CloseLibrary(IFFParseBase); }
apps/ILBMDemo/ILBMDemo.c
/* ILBMDemo.c 05/91 C. Scheppner CBM * * Demonstrates displaying an ILBM, loading a brush, * saving an ILBM, and optionally printing a screen (CTRL-p) * Use -c (or -c1, -c2, etc) as filename to read from or save to clipboard. * * requires linkage with several iffp modules - see Makefile */ #include "iffp/ilbmapp.h" #ifdef LATTICE int CXBRK(void) { return(0); } /* Disable Lattice CTRL/C handling */ int chkabort(void) { return(0); } /* really */ #endif void chkmsg(void); void cleanup(void); void bye(UBYTE *s,int error); #define SAVECHANGES #define MINARGS 3 char *vers = "\0$VER: ILBMDemo 37.5"; char *Copyright = "ILBMDemo v37.5 (Freely Redistributable)"; char *usage = "Usage: ILBMDemo sourceilbm destilbm [brushname] (CTRL-p to print screen)\n" "Displays source, optionally loads and blits brush, saves to dest\n" "Use filename -c[unit] (ie. -c, -c1, -c2, etc.) for clipboard\n"; char *savename; struct Library *IntuitionBase = NULL; struct Library *GfxBase = NULL; struct Library *IFFParseBase = NULL; /* Note - these fields are also available in the ILBMInfo structure */ struct Screen *scr; /* for ptr to screen structure */ struct Window *win; /* for ptr to window structure */ struct RastPort *wrp; /* for ptr to RastPort */ struct ViewPort *vp; /* for ptr to Viewport */ struct IntuiMessage *msg; struct NewWindow mynw = { 0, 0, /* LeftEdge and TopEdge */ 0, 0, /* Width and Height */ -1, -1, /* DetailPen and BlockPen */ VANILLAKEY|MOUSEBUTTONS, /* IDCMP Flags with Flags below */ BACKDROP|BORDERLESS|SMART_REFRESH|NOCAREREFRESH|ACTIVATE|RMBTRAP, NULL, NULL, /* Gadget and Image pointers */ NULL, /* Title string */ NULL, /* Screen ptr null till opened */ NULL, /* BitMap pointer */ 50, 20, /* MinWidth and MinHeight */ 0 , 0, /* MaxWidth and MaxHeight */ CUSTOMSCREEN /* Type of window */ }; BOOL FromWb, Done; /* ILBM Property chunks to be grabbed * List BMHD, CMAP and CAMG first so we can skip them when we write * the file back out (they will be written out with separate code) */ LONG ilbmprops[] = { ID_ILBM, ID_BMHD, ID_ILBM, ID_CMAP, ID_ILBM, ID_CAMG, ID_ILBM, ID_CCRT, ID_ILBM, ID_AUTH, ID_ILBM, ID_Copyright, TAG_DONE }; /* ILBM Collection chunks (more than one in file) to be gathered */ LONG ilbmcollects[] = { ID_ILBM, ID_CRNG, TAG_DONE }; /* ILBM Chunk to stop on */ LONG ilbmstops[] = { ID_ILBM, ID_BODY, TAG_DONE }; /* For test of adding new chunks to saved FORM */ struct Chunk newchunks[2] = { { &newchunks[1], ID_ILBM, ID_AUTH, IFFSIZE_UNKNOWN, "CAS_CBM"}, { NULL, ID_ILBM, ID_NAME, IFFSIZE_UNKNOWN, "Untitled No. 27"}, }; UBYTE nomem[] = "Not enough memory\n"; UBYTE noiffh[] = "Can't alloc iff\n"; /* our indexes to reference our frames * DEFault, BRUsh, and SCReen */ #define DEF 0 #define BRU 1 #define SCR 2 #define UICOUNT 3 /* For our ILBM frames */ struct ILBMInfo *ilbms[UICOUNT] = { NULL }; /* * MAIN */ void main(int argc, char **argv) { #ifdef SAVECHANGES struct Chunk *chunk; CamgChunk *camg; LONG saverror; #endif UBYTE *ilbmname=NULL, *brushname=NULL, ans, c; BPTR lock; LONG error; FromWb = argc ? FALSE : TRUE; if((argc<MINARGS)||(argv[argc-1][0]=='?')) { printf("%s\n%s\n",Copyright,usage); bye("",RETURN_OK); } switch(argc) { case 4: brushname = argv[3]; case 3: savename = argv[2]; ilbmname = argv[1]; break; } /* if dest not clipboard, warn if dest file already exists */ if(strcmp(savename,"-c")) { if(lock = Lock(savename,ACCESS_READ)) { UnLock(lock); printf("Dest file \"%s\" already exists. Overwrite (y or n) ? ", savename); ans = 0; while((c = getchar()) != '\n') if(!ans) ans = c | 0x20; if(ans == 'n') bye("Exiting.\n",RETURN_OK); } } /* Open Libraries */ if(!(IntuitionBase = OpenLibrary("intuition.library", 0))) bye("Can't open intuition library.\n",RETURN_WARN); if(!(GfxBase = OpenLibrary("graphics.library",0))) bye("Can't open graphics library.\n",RETURN_WARN); if(!(IFFParseBase = OpenLibrary("iffparse.library",0))) bye("Can't open iffparse library.\n",RETURN_WARN); /* * Alloc three ILBMInfo structs (one each for defaults, screen, brush) */ if(!(ilbms[0] = (struct ILBMInfo *) AllocMem(UICOUNT * sizeof(struct ILBMInfo),MEMF_PUBLIC|MEMF_CLEAR))) bye(nomem,RETURN_FAIL); else { ilbms[BRU] = ilbms[0] + 1; ilbms[SCR] = ilbms[0] + 2; } /* * Here we set up default ILBMInfo fields for our * application's frames. * Above we have defined the propery and collection chunks * we are interested in (some required like BMHD) * Since all of our frames are for ILBM's, we'll initialize * one default frame and clone the others from it. */ ilbms[DEF]->ParseInfo.propchks = ilbmprops; ilbms[DEF]->ParseInfo.collectchks = ilbmcollects; ilbms[DEF]->ParseInfo.stopchks = ilbmstops; ilbms[DEF]->windef = &mynw; /* * Initialize our working ILBM frames from our default one */ *ilbms[SCR] = *ilbms[DEF]; /* for our screen */ *ilbms[BRU] = *ilbms[DEF]; /* for our brush */ /* * Alloc two IFF handles (one for screen frame, one for brush frame) */ if(!(ilbms[SCR]->ParseInfo.iff = AllocIFF())) bye(noiffh,RETURN_FAIL); if(!(ilbms[BRU]->ParseInfo.iff = AllocIFF())) bye(noiffh,RETURN_FAIL); /* Load and display an ILBM */ if(error = showilbm(ilbms[SCR],ilbmname)) { printf("Can't load background \"%s\"\n",ilbmname); bye("",RETURN_WARN); } /* These were set up by our successful showilbm() above */ win = ilbms[SCR]->win; /* our window */ wrp = ilbms[SCR]->wrp; /* our window's RastPort */ scr = ilbms[SCR]->scr; /* our screen */ vp = ilbms[SCR]->vp; /* our screen's ViewPort */ ScreenToFront(scr); /* Now let's load a brush and blit it into the window */ if(brushname) { if (error = loadbrush(ilbms[BRU],brushname)) { printf("Can't load brush \"%s\"\n",brushname); bye("",RETURN_WARN); } else /* Success */ { D(bug("About to Blt bitmap $%lx to rp $%lx, w=%ld h=%ld\n", ilbms[BRU]->brbitmap,wrp,ilbms[BRU]->Bmhd.w,ilbms[BRU]->Bmhd.h)); BltBitMapRastPort(ilbms[BRU]->brbitmap,0,0, wrp,0,0, ilbms[BRU]->Bmhd.w, ilbms[BRU]->Bmhd.h, 0xC0); } } #ifdef SAVECHANGES /* This code is an example for Read/Modify/Write programs * * We copy off the parsed chunks we want to preserve, * close the IFF read file, reopen it for write, * and save a new ILBM which * will include the chunks we have preserved, but * with newly computed and set-up BMHD, CMAP, and CAMG. */ if(!(ilbms[SCR]->ParseInfo.copiedchunks = copychunks(ilbms[SCR]->ParseInfo.iff, ilbmprops, ilbmcollects, MEMF_PUBLIC))) printf("error cloning chunks\n"); else { /* we can close the file now */ closeifile(ilbms[SCR]); printf("Test of copychunks and findchunk:\n"); /* Find copied CAMG chunk if any */ if(chunk = findchunk(ilbms[SCR]->ParseInfo.copiedchunks,ID_ILBM,ID_CAMG)) { camg = (CamgChunk *)chunk->ch_Data; printf("CAMG: $%08lx\n",camg->ViewModes); } else printf("No CAMG found\n"); /* Find copied CRNG chunks if any */ if(chunk = findchunk(ilbms[SCR]->ParseInfo.copiedchunks,ID_ILBM,ID_CRNG)) { while((chunk)&&(chunk->ch_ID == ID_CRNG)) { printf("Found a CRNG chunk\n"); chunk = chunk->ch_Next; } } else printf("No CRNG chunks found\n"); } printf("\nAbout to save screen as %s, adding NAME and AUTH chunks\n", savename); if(saverror = screensave(ilbms[SCR], ilbms[SCR]->scr, ilbms[SCR]->ParseInfo.copiedchunks, newchunks, savename)) printf("%s\n",IFFerr(saverror)); #endif Done = FALSE; while(!Done) { Wait(1<<win->UserPort->mp_SigBit); chkmsg(); } cleanup(); exit(RETURN_OK); } void chkmsg(void) { LONG error; ULONG class; UWORD code; WORD mousex, mousey; while(msg = (struct IntuiMessage *)GetMsg(win->UserPort)) { class = msg->Class; code = msg->Code; mousex = msg->MouseX; mousey = msg->MouseY; ReplyMsg(msg); switch(class) { case MOUSEBUTTONS: switch(code) { /* emulate a close gadget */ case SELECTDOWN: if((mousex < 12)&&(mousey < 12)) Done = TRUE; break; default: break; } case VANILLAKEY: switch(code) { /* also quit on CTRL-C, CTRL-D, or q */ case 'q': case 0x04: case 0x03: Done = TRUE; break; case 0x10: /* CTRL-p means print */ /* Print the whole screen */ if(error=screendump(ilbms[SCR]->scr, 0,0, ilbms[SCR]->scr->Width, ilbms[SCR]->scr->Height, 0,0)) printf("Screendump printer error=%ld\n",error); break; default: break; } default: break; } } } void bye(UBYTE *s,int error) { if((*s)&&(!FromWb)) printf("%s\n",s); cleanup(); exit(error); } void cleanup() { if(ilbms[SCR]) { if(ilbms[SCR]->scr) unshowilbm(ilbms[SCR]); #ifdef SAVECHANGES freechunklist(ilbms[SCR]->ParseInfo.copiedchunks); #endif if(ilbms[SCR]->ParseInfo.iff) FreeIFF(ilbms[SCR]->ParseInfo.iff); } if(ilbms[BRU]) { if(ilbms[BRU]->brbitmap) unloadbrush(ilbms[BRU]); if(ilbms[BRU]->ParseInfo.iff) FreeIFF(ilbms[BRU]->ParseInfo.iff); } if(ilbms[0]) { FreeMem(ilbms[0],UICOUNT * sizeof(struct ILBMInfo)); } if(GfxBase) CloseLibrary(GfxBase); if(IntuitionBase) CloseLibrary(IntuitionBase); if(IFFParseBase) CloseLibrary(IFFParseBase); }
apps/ILBMLoad/ILBMLoad.c
/* ILBMLoad.c 05/91 C. Scheppner CBM * * Example which * - first queries an ILBM to determine size and mode * - then opens an appropriate screen and window * - then loads the ILBM into the already opened screen * * For clipboard, use filename -c[unit] (like -c, -c1, -c2, etc.) * * requires linkage with several IFF modules * see Makefile */ #include "iffp/ilbmapp.h" #ifdef LATTICE int CXBRK(void) { return(0); } /* Disable Lattice CTRL/C handling */ int chkabort(void) { return(0); } /* really */ #endif void cleanup(void); void bye(UBYTE *s,int error); #define MINARGS 2 char *vers = "\0$VER: ILBMLoad 37.5"; char *Copyright = "ILBMLoad v37.5 (Freely Redistributable)"; char *usage = "Usage: ILBMLoad ilbmname (-c[unit] for clipboard"; struct Library *IntuitionBase = NULL; struct Library *GfxBase = NULL; struct Library *IFFParseBase = NULL; /* Note - these fields are also available in the ILBMInfo structure */ struct Screen *scr; /* for ptr to screen structure */ struct Window *win; /* for ptr to window structure */ struct RastPort *wrp; /* for ptr to RastPort */ struct ViewPort *vp; /* for ptr to Viewport */ struct IntuiMessage *msg; struct NewWindow mynw = { 0, 0, /* LeftEdge and TopEdge */ 0, 0, /* Width and Height */ -1, -1, /* DetailPen and BlockPen */ VANILLAKEY|MOUSEBUTTONS, /* IDCMP Flags with Flags below */ BACKDROP|BORDERLESS|SMART_REFRESH|NOCAREREFRESH|ACTIVATE|RMBTRAP, NULL, NULL, /* Gadget and Image pointers */ NULL, /* Title string */ NULL, /* Screen ptr null till opened */ NULL, /* BitMap pointer */ 50, 20, /* MinWidth and MinHeight */ 0 , 0, /* MaxWidth and MaxHeight */ CUSTOMSCREEN /* Type of window */ }; BOOL FromWb; /* ILBM Property chunks to be grabbed * List BMHD, CMAP and CAMG first so we can skip them when we write * the file back out (they will be written out with separate code) */ LONG ilbmprops[] = { ID_ILBM, ID_BMHD, ID_ILBM, ID_CMAP, ID_ILBM, ID_CAMG, ID_ILBM, ID_CCRT, ID_ILBM, ID_AUTH, ID_ILBM, ID_Copyright, TAG_DONE }; /* ILBM Collection chunks (more than one in file) to be gathered */ LONG ilbmcollects[] = { ID_ILBM, ID_CRNG, TAG_DONE }; /* ILBM Chunk to stop on */ LONG ilbmstops[] = { ID_ILBM, ID_BODY, TAG_DONE }; UBYTE nomem[] = "Not enough memory\n"; UBYTE noiffh[] = "Can't alloc iff\n"; /* For our allocated ILBM frame */ struct ILBMInfo *ilbm; /* * MAIN */ void main(int argc, char **argv) { UBYTE *ilbmname=NULL; LONG error = 0L; FromWb = argc ? FALSE : TRUE; if((argc<MINARGS)||(argv[argc-1][0]=='?')) { printf("%s\n%s\n",Copyright,usage); bye("",RETURN_OK); } ilbmname = argv[1]; /* Open Libraries */ if(!(IntuitionBase = OpenLibrary("intuition.library", 0))) bye("Can't open intuition library.\n",RETURN_WARN); if(!(GfxBase = OpenLibrary("graphics.library",0))) bye("Can't open graphics library.\n",RETURN_WARN); if(!(IFFParseBase = OpenLibrary("iffparse.library",0))) bye("Can't open iffparse library.\n",RETURN_WARN); /* * Alloc one ILBMInfo struct */ if(!(ilbm = (struct ILBMInfo *) AllocMem(sizeof(struct ILBMInfo),MEMF_PUBLIC|MEMF_CLEAR))) bye(nomem,RETURN_FAIL); /* * Here we set up our ILBMInfo fields for our * application. * Above we have defined the propery and collection chunks * we are interested in (some required like BMHD) */ ilbm->ParseInfo.propchks = ilbmprops; ilbm->ParseInfo.collectchks = ilbmcollects; ilbm->ParseInfo.stopchks = ilbmstops; ilbm->windef = &mynw; /* * Alloc IFF handle for frame */ if(!(ilbm->ParseInfo.iff = AllocIFF())) bye(noiffh,RETURN_FAIL); /* Normally you would use showilbm() to open an appropriate acreen * and display an ILBM in it. * * However, here we are demonstrating * - first querying an ILBM to get its BMHD and CAMG (real or computed) * - then opening our own display * - then loading the ILBM into it */ if(!(error = queryilbm(ilbm,ilbmname))) { D(bug("ilbmload: after query, this ILBM is %ld x %ld x %ld, modeid=$%lx\n", ilbm->Bmhd.w, ilbm->Bmhd.h, ilbm->Bmhd.nPlanes, ilbm->camg)); /* Note - you could use your own routines to open your * display, but if so, you must initialize ilbm->scr, * ilbm->win, ilbm->wrp, ilbm->srp, and ilbm->vp for your display. * Here we will use opendisplay() which will initialize * those fields. */ if(!(opendisplay(ilbm, MAX(ilbm->Bmhd.pageWidth, ilbm->Bmhd.w), MAX(ilbm->Bmhd.pageHeight,ilbm->Bmhd.h), MIN(ilbm->Bmhd.nPlanes,MAXAMDEPTH), ilbm->camg))) { printf("Failed to open display\n"); } else { D(bug("ilbmload: opendisplay successful\n")); scr = ilbm->scr; win = ilbm->win; if(!(error = loadilbm(ilbm, ilbmname))) { D(bug("ilbmload: loadilbm successful\n")); /* Note - we don't need to examine or copy any * chunks from the file, so we will close file now */ closeifile(ilbm); ScreenToFront(ilbm->scr); Wait(1<<win->UserPort->mp_SigBit); unloadilbm(ilbm); /* deallocs colors, closeifile if needed */ } closedisplay(ilbm); } } if(error) printf("%s\n",IFFerr(error)); cleanup(); exit(RETURN_OK); } void bye(UBYTE *s,int error) { if((*s)&&(!FromWb)) printf("%s\n",s); cleanup(); exit(error); } void cleanup() { if(ilbm) { if(ilbm->ParseInfo.iff) FreeIFF(ilbm->ParseInfo.iff); FreeMem(ilbm,sizeof(struct ILBMInfo)); } if(GfxBase) CloseLibrary(GfxBase); if(IntuitionBase) CloseLibrary(IntuitionBase); if(IFFParseBase) CloseLibrary(IFFParseBase); }
apps/ILBMtoC/ILBMtoC.c
/*--------------------------------------------------------------*/ /* */ /* ILBMtoC: reads in ILBM, prints out ascii representation, */ /* for including in C files. */ /* */ /* Based on ILBMDump.c by Jerry Morrison and Steve Shaw, */ /* Electronic Arts. */ /* Jan 31, 1986 */ /* */ /* This software is in the public domain. */ /* This version for the Commodore-Amiga computer. */ /* */ /* Callable from CLI ONLY */ /* modified 05-91 for use wuth iffparse modules */ /* Requires linkage with several other modules - see Makefile */ /*--------------------------------------------------------------*/ #include "iffp/ilbmapp.h" #ifdef LATTICE int CXBRK(void) { return(0); } /* Disable Lattice CTRL/C handling */ int chkabort(void) { return(0); } /* really */ #endif char *vers = "\0$VER: ILBMtoC 37.5"; char *Copyright = "ILBMtoC v37.5 (Freely Redistributable)"; void GetSuffix(UBYTE *to, UBYTE *fr); void bye(UBYTE *s, int e); void cleanup(void); struct Library *IFFParseBase = NULL; struct Library *GfxBase = NULL; /* ILBM frame */ struct ILBMInfo ilbm = {0}; /* ILBM Property chunks to be grabbed - only BMHD needed for this app */ LONG ilbmprops[] = { ID_ILBM, ID_BMHD, TAG_DONE }; /* ILBM Collection chunks (more than one in file) to be gathered */ LONG *ilbmcollects = NULL; /* none needed for this app */ /* ILBM Chunk to stop on */ LONG ilbmstops[] = { ID_ILBM, ID_BODY, TAG_DONE }; UBYTE defSwitch[] = "b"; /** main() ******************************************************************/ void main(int argc, char **argv) { UBYTE *sw; FILE *fp; LONG error=NULL; UBYTE *ilbmname, name[80], fname[80]; if ((argc < 2)||(argv[argc-1][0]=='?')) { printf("Usage from CLI: 'ILBMtoC filename switch-string'\n"); printf(" where switch-string = \n"); printf(" <nothing> : Bob format (default)\n"); printf(" s : Sprite format (with header and trailer words)\n"); printf(" sn : Sprite format (No header and trailer words)\n"); printf(" a : Attached sprite (with header and trailer)\n"); printf(" an : Attached sprite (No header and trailer)\n"); printf(" Add 'c' to switch list to output CR's with LF's \n"); exit(RETURN_OK); } if(!(GfxBase = OpenLibrary("graphics.library",0))) bye("Can't open graphics.library",RETURN_FAIL); if(!(IFFParseBase = OpenLibrary("iffparse.library",0))) bye("Can't open iffparse.library",RETURN_FAIL); /* * Here we set up default ILBMInfo fields for our * application's frames. * Above we have defined the propery and collection chunks * we are interested in (some required like BMHD) */ ilbm.ParseInfo.propchks = ilbmprops; ilbm.ParseInfo.collectchks = ilbmcollects; ilbm.ParseInfo.stopchks = ilbmstops; if(!(ilbm.ParseInfo.iff = AllocIFF())) bye(IFFerr(IFFERR_NOMEM),RETURN_FAIL); /* Alloc an IFFHandle */ sw = (argc>2) ? (UBYTE *)argv[2] : defSwitch; ilbmname = argv[1]; if (error = loadbrush(&ilbm,ilbmname)) { printf("Can't load ilbm \"%s\", ifferr=%s\n",ilbmname,IFFerr(error)); bye("",RETURN_WARN); } else /* Successfully loaded ILBM */ { printf(" Creating file %s.c \n",argv[1]); GetSuffix(name,argv[1]); strcpy(fname,argv[1]); strcat(fname,".c"); fp = fopen(fname,"w"); if(fp) { BMPrintCRep(ilbm.brbitmap,fp,name,sw); fclose(fp); } else printf("Couldn't open output file: %s. \n", fname); unloadbrush(&ilbm); } printf("\n"); bye("",RETURN_OK); } /* this copies part of string after the last '/' or ':' */ void GetSuffix(to, fr) UBYTE *to, *fr; { int i; UBYTE c,*s = fr; for (i=0; ;i++) { c = *s++; if (c == 0) break; if (c == '/') fr = s; else if (c == ':') fr = s; } strcpy(to,fr); } void bye(UBYTE *s, int e) { if(s&&(*s)) printf("%s\n",s); cleanup(); exit(e); } void cleanup() { if(ilbm.ParseInfo.iff) FreeIFF(ilbm.ParseInfo.iff); if(IFFParseBase) CloseLibrary(IFFParseBase); if(GfxBase) CloseLibrary(GfxBase); }
apps/ILBMtoRaw/ILBMtoRaw.c
/*--------------------------------------------------------------*/ /* */ /* ILBMtoRaw: reads in ILBM, writes out raw file (raw planes, */ /* followed by colormap) */ /* */ /* Based on ILBMRaw.c by Jerry Morrison and Steve Shaw, */ /* Electronic Arts. */ /* Jan 31, 1986 */ /* */ /* This software is in the public domain. */ /* This version for the Commodore-Amiga computer. */ /* */ /* Callable from CLI ONLY */ /* modified 05-91 for use wuth iffparse modules */ /* Requires linkage with several other modules - see Makefile */ /*--------------------------------------------------------------*/ #include "iffp/ilbmapp.h" #ifdef LATTICE int CXBRK(void) { return(0); } /* Disable Lattice CTRL/C handling */ int chkabort(void) { return(0); } /* really */ #endif char *vers = "\0$VER: ILBMtoRaw 37.5"; char *Copyright = "ILBMtoRaw v37.5 (Freely Redistributable)"; void bye(UBYTE *s, int e); void cleanup(void); LONG SaveBitMap(UBYTE *name, struct BitMap *bm, SHORT *cols, int ncols); struct Library *IFFParseBase = NULL; struct Library *GfxBase = NULL; /* ILBM frame */ struct ILBMInfo ilbm = {0}; /* ILBM Property chunks to be grabbed - BMHD and CMAP needed for this app */ LONG ilbmprops[] = { ID_ILBM, ID_BMHD, ID_ILBM, ID_CMAP, TAG_DONE }; /* ILBM Collection chunks (more than one in file) to be gathered */ LONG *ilbmcollects = NULL; /* none needed for this app */ /* ILBM Chunk to stop on */ LONG ilbmstops[] = { ID_ILBM, ID_BODY, TAG_DONE }; /** main() ******************************************************************/ void main(int argc, char **argv) { LONG error=NULL; UBYTE *ilbmname, fname[80], buf[24]; if ((argc < 2)||(argv[argc-1][0]=='?')) bye("Usage from CLI: 'ILBMtoRaw filename'\n",RETURN_OK); if(!(GfxBase = OpenLibrary("graphics.library",0))) bye("Can't open graphics.library",RETURN_FAIL); if(!(IFFParseBase = OpenLibrary("iffparse.library",0))) bye("Can't open iffparse.library",RETURN_FAIL); /* * Here we set up default ILBMInfo fields for our * application's frames. * Above we have defined the propery and collection chunks * we are interested in (some required like BMHD) */ ilbm.ParseInfo.propchks = ilbmprops; ilbm.ParseInfo.collectchks = ilbmcollects; ilbm.ParseInfo.stopchks = ilbmstops; if(!(ilbm.ParseInfo.iff = AllocIFF())) bye(IFFerr(IFFERR_NOMEM),RETURN_FAIL); /* Alloc an IFFHandle */ ilbmname = argv[1]; /* Load as a brush since we don't need to display it */ if (error = loadbrush(&ilbm,ilbmname)) { printf("Can't load ilbm \"%s\", ifferr=%s\n",ilbmname,IFFerr(error)); bye("",RETURN_WARN); } else /* Successfully loaded ILBM */ { strcpy(fname,argv[1]); if(ilbm.camg & HAM) strcat(fname, ".ham"); if(ilbm.camg & EXTRA_HALFBRITE) strcat(fname, ".ehb"); if(ilbm.camg & HIRES) strcat(fname, ".hi"); else strcat(fname, ".lo"); if(ilbm.camg & LACE) strcat(fname, ".lace"); strcat(fname,"."); sprintf(buf,"%d",ilbm.Bmhd.w); strcat(fname,buf); strcat(fname,"x"); sprintf(buf,"%d",ilbm.Bmhd.h); strcat(fname,buf); strcat(fname,"x"); sprintf(buf,"%d",ilbm.brbitmap->Depth); strcat(fname, buf); printf(" Creating file %s \n", fname); error=SaveBitMap(fname, ilbm.brbitmap, ilbm.colortable, ilbm.ncolors); unloadbrush(&ilbm); } if(error) bye(IFFerr(error),RETURN_WARN); else bye("",RETURN_OK); } /* SaveBitMap (as raw planes and colortable) * * Given filename, bitmap structure, and colortable pointer, * writes out raw bitplanes and colortable (not an ILBM) * Returns 0 for success */ LONG SaveBitMap(UBYTE *name, struct BitMap *bm, SHORT *cols, int ncols) { SHORT i; LONG nb,plsize; LONG file = Open( name, MODE_NEWFILE); if( file == 0 ) { printf(" couldn't open %s \n",name); return(CLIENT_ERROR); /* couldnt open a load-file */ } plsize = bm->BytesPerRow*bm->Rows; for (i=0; i<bm->Depth; i++) { nb = Write(file, bm->Planes[i], plsize); if (nb<plsize) break; } if(nb>0) nb=Write(file, cols, (1<<bm->Depth)*2); /* save color map */ Close(file); return(nb >= 0 ? 0L : IFFERR_WRITE); } void bye(UBYTE *s, int e) { if(s&&(*s)) printf("%s\n",s); cleanup(); exit(e); } void cleanup() { if(ilbm.ParseInfo.iff) FreeIFF(ilbm.ParseInfo.iff); if(IFFParseBase) CloseLibrary(IFFParseBase); if(GfxBase) CloseLibrary(GfxBase); }
apps/Play8SVX/Play8SVX.c
/** Play8SVX.c ************************************************************** * * Read and play sound sample from an IFF file. 21Jan85 * * By Steve Hayes, Electronic Arts. * This software is in the public domain. * * Modified 05/91 for use with iffparse & to play notes - CAS_CBM * requires linkage with several IFF modules - see Makefile ****************************************************************************/ #include "iffp/8svxapp.h" #include <exec/execbase.h> #include <graphics/gfxbase.h> #include <clib/alib_protos.h> #ifdef LATTICE int CXBRK(void) { return(0); } /* Disable Lattice CTRL/C handling */ int chkabort(void) { return(0); } /* really */ #endif /* prototypes for our functions */ void cleanup(void); void bye(UBYTE *s,int error); void DUnpack(BYTE source[], LONG n, BYTE dest[]); BYTE D1Unpack(BYTE source[], LONG n, BYTE dest[], BYTE x); LONG LoadSample(struct EightSVXInfo *esvx, UBYTE *filename); void UnloadSample(struct EightSVXInfo *esvx); LONG LoadSBody(struct EightSVXInfo *esvx); void UnloadSBody(struct EightSVXInfo *esvx); LONG ShowSample(struct EightSVXInfo *esvx); LONG OpenAudio(void); void CloseAudio(void); LONG PlaySample(struct EightSVXInfo *esvx, LONG octave, LONG note, UWORD volume, ULONG delay); struct IOAudio *playbigsample(struct IOAudio *aio0, struct IOAudio *aio1, BYTE *samptr, LONG ssize, ULONG period, UWORD volume); #define MINARGS 2 char *vers = "\0$VER: Play8SVX 37.5"; char *Copyright = "Play8SVX v37.5 (Freely Redistributable)"; char *usage = "Usage: Play8SVX 8SVXname"; /* globals */ struct Library *IFFParseBase = NULL; struct Library *GfxBase = NULL; BOOL FromWb; /* 8SVX Property chunks to be grabbed */ LONG esvxprops[] = { ID_8SVX, ID_VHDR, ID_8SVX, ID_NAME, ID_8SVX, ID_ATAK, ID_8SVX, ID_RLSE, ID_8SVX, ID_AUTH, ID_8SVX, ID_Copyright, TAG_DONE }; /* 8SVX Collection chunks (more than one in file) to be gathered */ LONG esvxcollects[] = { ID_8SVX, ID_ANNO, TAG_DONE }; /* 8SVX Chunk to stop on */ LONG esvxstops[] = { ID_8SVX, ID_BODY, TAG_DONE }; UBYTE nomem[] = "Not enough memory\n"; UBYTE noiffh[] = "Can't alloc iff\n"; /* For our allocated EightSVXInfo */ struct EightSVXInfo *esvx = NULL; /* * MAIN */ void main(int argc, char **argv) { UBYTE *esvxname=NULL; ULONG oct; LONG error=0L; FromWb = argc ? FALSE : TRUE; if((argc<MINARGS)||(argv[argc-1][0]=='?')) { printf("%s\n%s\n",Copyright,usage); bye("",RETURN_OK); } esvxname = argv[1]; /* Open Libraries */ if(!(IFFParseBase = OpenLibrary("iffparse.library",0))) bye("Can't open iffparse library.\n",RETURN_WARN); /* * Alloc one EightSVXInfo struct */ if(!(esvx = (struct EightSVXInfo *) AllocMem(sizeof(struct EightSVXInfo),MEMF_PUBLIC|MEMF_CLEAR))) bye(nomem,RETURN_FAIL); /* * Here we set up our EightSVXInfo fields for our * application. * Above we have defined the propery and collection chunks * we are interested in (some required like VHDR). * We want to stop on BODY. */ esvx->ParseInfo.propchks = esvxprops; esvx->ParseInfo.collectchks = esvxcollects; esvx->ParseInfo.stopchks = esvxstops; /* * Alloc the IFF handle for the frame */ if(!(esvx->ParseInfo.iff = AllocIFF())) bye(noiffh,RETURN_FAIL); if(!(error = LoadSample(esvx, esvxname))) { ShowSample(esvx); if(!(error = OpenAudio())) { /* If we think this is a sound effect, play it as such (note=-1) */ if((esvx->Vhdr.ctOctave==1)&&(esvx->Vhdr.samplesPerSec) &&(esvx->Vhdr.oneShotHiSamples)&&(!esvx->Vhdr.repeatHiSamples)) { PlaySample(esvx,0,-1,64,0); } /* Else play it like an instrument */ else { for(oct=0; oct < esvx->Vhdr.ctOctave; oct++) { PlaySample(esvx,oct,0,64,50); PlaySample(esvx,oct,4,64,50); PlaySample(esvx,oct,7,64,50); } } CloseAudio(); } else printf("error opening audio device\n"); } else printf("%s\n",IFFerr(error)); cleanup(); exit(RETURN_OK); } void bye(UBYTE *s,int error) { if((*s)&&(!FromWb)) printf("%s\n",s); cleanup(); exit(error); } void cleanup() { if(esvx) { DD(bug("About to UnloadSample\n")); UnloadSample(esvx); DD(bug("About to FreeIFF\n")); if(esvx->ParseInfo.iff) FreeIFF(esvx->ParseInfo.iff); DD(bug("About to free EightSVXInfo\n")); FreeMem(esvx,sizeof(struct EightSVXInfo)); } if(IFFParseBase) CloseLibrary(IFFParseBase); } /** ShowSample() ********************************************** * * Show sample information after calling LoadSample() * *************************************************************************/ LONG ShowSample(struct EightSVXInfo *esvx) { LONG error = 0L; BYTE *buf; Voice8Header *vhdr; if(!esvx) return(CLIENT_ERROR); if(!(buf = esvx->sample)) return(CLIENT_ERROR); /* LoadSample copied VHDR and NAME (if any) to our esvx frame */ vhdr = &esvx->Vhdr; if(esvx->name[0]) printf("\nNAME: %s",esvx->name); printf("\n\nVHDR Info:"); printf("\noneShotHiSamples=%ld", vhdr->oneShotHiSamples); printf("\nrepeatHiSamples=%ld", vhdr->repeatHiSamples); printf("\nsamplesPerHiCycle=%ld", vhdr->samplesPerHiCycle); printf("\nsamplesPerSec=%ld", vhdr->samplesPerSec); printf("\nctOctave=%ld", vhdr->ctOctave); printf("\nsCompression=%ld", vhdr->sCompression); printf("\nvolume=0x%lx", vhdr->volume); printf("\nData = %3ld %3ld %3ld %3ld %3ld %3ld %3ld %3ld", buf[0],buf[1],buf[2],buf[3],buf[4],buf[5],buf[6],buf[7]); printf("\n %3ld %3ld %3ld %3ld %3ld %3ld %3ld %3ld ...\n", buf[8+0],buf[8+1],buf[8+2],buf[8+3],buf[8+4],buf[8+5], buf[8+6],buf[8+ 7]); return(error); } /* OpenAudio * * Opens audio device for one audio channel, 2 IO requests * Returns 0 for success * * Based on code by Dan Baker */ UBYTE whichannel[] = { 1,2,4,8 }; /* periods for scale starting at 65.40Hz (C) with 128 samples per cycle * or 130.81Hz (C) with 64 samples per cycle * or 261.63Hz (C) with 32 samples per cycle * or 523.25Hz (C) with 16 samples per cycle * or 1046.50Hz (C) with 8 samples per cycle * or 2093.00Hz (C) with 4 samples per cycle */ UWORD per_ntsc[12]= { 428, 404, 380, 360, 340, 320, 302, 286, 270, 254, 240, 226 }; /* periods adjusted for system clock frequency */ UWORD per[12]; /* Note - these values 3579545 NTSC, 3546895 PAL */ #define NTSC_CLOCK 3579545L #define PAL_CLOCK 3546895L #define AIOCNT 4 struct IOAudio *aio[AIOCNT] = {NULL}; /* Ptrs to IO blocks for commands */ struct MsgPort *port; /* Pointer to a port so the device can reply */ BOOL devopened; ULONG clock = NTSC_CLOCK; /* Will check for PAL and change if necessary */ LONG OpenAudio() { extern struct ExecBase *SysBase; LONG error=0L; ULONG period; int k; if(devopened) return(-1); /*-------------------------------------------------------------------------*/ /* Ask the system if we are PAL or NTSC and set clock constant accordingly */ /*-------------------------------------------------------------------------*/ if(GfxBase=OpenLibrary("graphics.library",0L)) { if(((struct GfxBase *)GfxBase)->DisplayFlags & PAL) clock = PAL_CLOCK; else clock = NTSC_CLOCK; CloseLibrary((struct Library *) GfxBase); } printf("OpenAudio: For period calculations, clock=%ld\n", clock); /* calculate period values for one octave based on system clock */ for(k=0; k<12; k++) { period = ((per_ntsc[k] * clock) + (NTSC_CLOCK >> 1)) / NTSC_CLOCK; per[k] = period; D(bug("per[%ld]=%ld ",k,per[k])); } D(bug("\n")); /*-------------------------------------------------------------------*/ /* Create a reply port so the audio device can reply to our commands */ /*-------------------------------------------------------------------*/ if(!(port=CreatePort(0,0))) { error = 1; goto bailout; } /*--------------------------------------------------------------------------*/ /* Create audio I/O blocks so we can send commands to the audio device */ /*--------------------------------------------------------------------------*/ for(k=0; k<AIOCNT; k++) { if(!(aio[k]=(struct IOAudio *)CreateExtIO(port,sizeof(struct IOAudio)))) { error = k+2; goto bailout; } } /*----------------------------------------------------------------------*/ /* Set up the audio I/O block for channel allocation: */ /* ioa_Request.io_Message.mn_ReplyPort is the address of a reply port. */ /* ioa_Request.io_Message.mn_Node.ln_Pri sets the precedence (priority) */ /* of our use of the audio device. Any tasks asking to use the audio */ /* device that have a higher precedence will steal the channel from us.*/ /* ioa_Request.io_Command is the command field for IO. */ /* ioa_Request.io_Flags is used for the IO flags. */ /* ioa_AllocKey will be filled in by the audio device if the allocation */ /* succeeds. We must use the key it gives for all other commands sent.*/ /* ioa_Data is a pointer to the array listing the channels we want. */ /* ioa_Length tells how long our list of channels is. */ /*----------------------------------------------------------------------*/ aio[0]->ioa_Request.io_Command = ADCMD_ALLOCATE; aio[0]->ioa_Request.io_Flags = ADIOF_NOWAIT; aio[0]->ioa_AllocKey = 0; aio[0]->ioa_Data = whichannel; aio[0]->ioa_Length = sizeof(whichannel); /*-----------------------------------------------*/ /* Open the audio device and allocate a channel */ /*-----------------------------------------------*/ if(!(OpenDevice("audio.device",0L, (struct IORequest *) aio[0] ,0L))) devopened = TRUE; else { error = 5; goto bailout; } /* Clone the flags, channel allocation, etc. into other IOAudio requests */ for(k=1; k<AIOCNT; k++) *aio[k] = *aio[0]; bailout: if(error) { printf("OpenAudio errored out at step %ld\n",error); CloseAudio(); } return(error); } /* CloseAudio * * Close audio device as opened by OpenAudio, null out pointers */ void CloseAudio() { int k; D(bug("Closing audio device...\n")); /* Note - we know we have no outstanding audio requests */ if(devopened) { CloseDevice((struct IORequest *) aio[0]); devopened = FALSE; } for(k=0; k<AIOCNT; k++) { if(aio[k]) DeleteExtIO(aio[k]), aio[k] = NULL; } if(port) DeletePort(port), port = NULL; } /** PlaySample() ********************************************** * * Play a note in octave for delay/50ths of a second * OR Play a sound effect (set octave and note to 0, -1) * * Requires successful OpenAudio() called previously * * When playing notes: * Expects note values between 0 (C) and 11 (B#) * Uses largest octave sample in 8SVX as octave 0, next smallest * as octave 1, etc. * * Notes - this simple example routine does not do ATAK and RLSE) * - use of Delay for timing is simplistic, synchronous, and does * not take into account that the oneshot itself may be * longer than the delay. * Use timer.device for more accurate asynchronous delays * *************************************************************************/ /* Max playable sample in one IO request is 128K */ #define MAXSAMPLE 131072 LONG PlaySample(struct EightSVXInfo *esvx, LONG octave, LONG note, UWORD volume, ULONG delay) { /* pointers to outstanding requests */ struct IOAudio *aout0=NULL, *aout1=NULL; ULONG period; LONG osize, rsize; BYTE *oneshot, *repeat; if(!devopened) return(-1); if(note > 11) note=0; if( note == -1 ) period = clock / esvx->Vhdr.samplesPerSec; else period = per[note]; /* table set up by OpenAudio */ if(octave > esvx->Vhdr.ctOctave) octave = 0; if(volume > 64) volume = 64; oneshot = esvx->osamps[octave]; osize = esvx->osizes[octave]; repeat = esvx->rsamps[octave]; rsize = esvx->rsizes[octave]; D(bug("oneshot $%lx size %ld, repeat $%lx size %ld\n", oneshot, osize, repeat, rsize)); /*------------------------------------------------------------*/ /* Set up audio I/O blocks to play a sample using CMD_WRITE. */ /* Set up one request for the oneshot and one for repeat */ /* (all ready for simple case, but we may not need both) */ /* The io_Flags are set to ADIOF_PERVOL so we can set the */ /* period (speed) and volume with the our sample; */ /* ioa_Data points to the sample; ioa_Length gives the length */ /* ioa_Cycles tells how many times to repeat the sample */ /* If you want to play the sample at a given sampling rate, */ /* set ioa_Period = clock/(given sampling rate) */ /*------------------------------------------------------------*/ aio[0]->ioa_Request.io_Command =CMD_WRITE; aio[0]->ioa_Request.io_Flags =ADIOF_PERVOL; aio[0]->ioa_Data =oneshot; aio[0]->ioa_Length =osize; aio[0]->ioa_Period =period; aio[0]->ioa_Volume =volume; aio[0]->ioa_Cycles =1; aio[2]->ioa_Request.io_Command =CMD_WRITE; aio[2]->ioa_Request.io_Flags =ADIOF_PERVOL; aio[2]->ioa_Data =repeat; aio[2]->ioa_Length =rsize; aio[2]->ioa_Period =period; aio[2]->ioa_Volume =volume; aio[2]->ioa_Cycles =0; /* repeat until stopped */ /*---------------------------------------------------*/ /* Send the command to start a sound using BeginIO() */ /* Go to sleep and wait for the sound to finish with */ /* WaitIO() to wait and get the get the ReplyMsg */ /*---------------------------------------------------*/ printf("Starting tone O len %ld for %0ld cyc, R len %ld for %0ld cyc, per=%ld...", osize, aio[0]->ioa_Cycles, rsize, aio[1]->ioa_Cycles, period); if(osize) { /* Simple case for oneshot sample <= 128K (ie. most samples) */ if(osize <= MAXSAMPLE) BeginIO((struct IORequest *)(aout0=aio[0])); /* Note - this else case code is for samples >128K */ else { *aio[1] = *aio[0]; aout0 = playbigsample(aio[0],aio[1],oneshot,osize,period,volume); } } if(rsize) { /* Simple case for oneshot sample <= 128K (ie. most samples) */ if(rsize <= MAXSAMPLE) BeginIO((struct IORequest *)(aout1=aio[2])); /* Note - this else case code is for samples >128K */ else { *aio[3] = *aio[2]; aout1 = playbigsample(aio[2],aio[3],repeat,rsize,period,volume); } } if(delay) Delay(delay); /* crude timing for notes */ /* Wait for any requests we still have out */ if(aout0) WaitIO(aout0); if(aout1) { if(note >= 0) AbortIO(aout1); /* if a note, stop it now */ WaitIO(aout1); } printf("Done\n"); } /** playbigsample() ******************************************************** * * called by playsample to deal with samples > 128K * * wants pointers to two ready-to-use IOAudio iorequest blocks * * returns pointer to the IOAudio request that is still out * or NULL if none (error) *************************************************************************/ struct IOAudio *playbigsample(struct IOAudio *aio0, struct IOAudio* aio1, BYTE *samptr, LONG ssize, ULONG period, UWORD volume) { struct IOAudio *aio[2]; LONG size; int req=0, reqn=1; /* current and next IOAudio request indexes */ if((!aio0)||(!aio1)||(ssize < MAXSAMPLE)) return(NULL); aio[req] = aio0; aio[reqn] = aio1; /* start the first 128 K playing */ aio[req]->ioa_Request.io_Command =CMD_WRITE; aio[req]->ioa_Request.io_Flags =ADIOF_PERVOL; aio[req]->ioa_Data =samptr; aio[req]->ioa_Length =MAXSAMPLE; aio[req]->ioa_Period =period; aio[req]->ioa_Volume =volume; aio[req]->ioa_Cycles =1; BeginIO((struct IORequest*)aio[req]); for(samptr=samptr + MAXSAMPLE, size = ssize - MAXSAMPLE; size > 0; samptr += MAXSAMPLE) { /* queue the next piece of sample */ reqn = req ^ 1; /* alternate IO blocks 0 and 1 */ aio[reqn]->ioa_Request.io_Command =CMD_WRITE; aio[reqn]->ioa_Request.io_Flags =ADIOF_PERVOL; aio[reqn]->ioa_Data =samptr; aio[reqn]->ioa_Length = (size > MAXSAMPLE) ? MAXSAMPLE : size; aio[reqn]->ioa_Period =period; aio[reqn]->ioa_Volume =volume; aio[reqn]->ioa_Cycles =1; BeginIO((struct IORequest*)aio[reqn]); /* Wait for previous request to finish */ WaitIO(aio[req]); /* decrement size */ size = (size > MAXSAMPLE) ? size-MAXSAMPLE : 0; req = reqn; /* switch between aio[0] and aio[1] */ } return(aio[reqn]); } /** LoadSample() ********************************************************** * * Read 8SVX, given an initialized EightSVXInfo with not-in-use IFFHandle, * and filename. Leaves the IFFHandle open so you can FindProp() * additional chunks or copychunks(). You must UnloadSample() * when done. UnloadSample will closeifile if the file is still * open. * * Fills in esvx->Vhdr and Name, and allocates/loads esvx->sample, * setting esvx->samplebytes to size for deallocation. * * Returns 0 for success of an IFFERR (libraries/iffparse.h) *************************************************************************/ LONG LoadSample(struct EightSVXInfo *esvx, UBYTE *filename) { struct IFFHandle *iff; struct StoredProperty *sp; Voice8Header *vhdr; BYTE *oneshot, *repeat; ULONG osize, rsize, spcyc; int oct; LONG error = 0L; D(bug("LoadSample:\n")); if(!esvx) return(CLIENT_ERROR); if(!(iff=esvx->ParseInfo.iff)) return(CLIENT_ERROR); if(!(error = openifile((struct ParseInfo *)esvx, filename, IFFF_READ))) { printf("Reading '%s'...\n",filename); error = parseifile((struct ParseInfo *)esvx, ID_FORM, ID_8SVX, esvx->ParseInfo.propchks, esvx->ParseInfo.collectchks, esvx->ParseInfo.stopchks); D(bug("LoadSample: after parseifile - error = %ld\n",error)); if((!error)||(error == IFFERR_EOC)||(error == IFFERR_EOF)) { if(contextis(iff,ID_8SVX,ID_FORM)) { D(bug("LoadSample: context is 8SVX\n")); if(!(sp = FindProp(iff,ID_8SVX,ID_VHDR))) { message("No 8SVX.VHDR!"); error = IFFERR_SYNTAX; } else { D(bug("LoadSample: Have VHDR\n")); /* copy Voice8Header into frame */ vhdr = (Voice8Header *)(sp->sp_Data); *(&esvx->Vhdr) = *vhdr; /* copy name if any */ esvx->name[0]='\0'; if(sp = FindProp(iff,ID_8SVX,ID_NAME)) { strncpy(esvx->name,sp->sp_Data,sp->sp_Size); esvx->name[MIN(sp->sp_Size,79)] = '\0'; } error = LoadSBody(esvx); D(bug("LoadSample: After LoadSBody - error = %ld\n",error)); if(!error) { osize = esvx->Vhdr.oneShotHiSamples; rsize = esvx->Vhdr.repeatHiSamples; spcyc = esvx->Vhdr.samplesPerHiCycle; if(!spcyc) spcyc = esvx->Vhdr.repeatHiSamples; if(!spcyc) spcyc = 8; oneshot = esvx->sample; for(oct = esvx->Vhdr.ctOctave-1; oct >= 0; oct--, oneshot+=(osize+rsize), osize <<= 1, rsize <<=1, spcyc <<=1) { repeat = oneshot + osize; esvx->osizes[oct] = osize; if(osize) esvx->osamps[oct] = oneshot; else esvx->osamps[oct] = 0; esvx->rsizes[oct] = rsize; if(rsize) esvx->rsamps[oct] = repeat; else esvx->rsamps[oct] = 0; esvx->spcycs[oct] = spcyc; D(bug("oneshot $%lx size %ld, repeat $%lx size %ld\n", oneshot, osize, repeat, rsize)); } } } } else { message("Not an 8SVX\n"); error = NOFILE; } } } if(error) { closeifile((struct ParseInfo *)esvx); UnloadSample(esvx); } return(error); } /** UnloadSample() ******************************************************* * * Frees and closes everything opened/alloc'd by LoadSample() * *************************************************************************/ void UnloadSample(struct EightSVXInfo *esvx) { if(esvx) { UnloadSBody(esvx); closeifile((struct ParseInfo *)esvx); } } /** LoadSBody() *********************************************************** * * Read a 8SVX Sample BODY into RAM. * *************************************************************************/ LONG LoadSBody(struct EightSVXInfo *esvx) { struct IFFHandle *iff; LONG sbytes, rlen, error = 0L; ULONG memtype; Voice8Header *vhdr = &esvx->Vhdr; BYTE *t; D(bug("LoadSBody:\n")); if(!(iff=esvx->ParseInfo.iff)) return(CLIENT_ERROR); if(!esvx) return(CLIENT_ERROR); if(!(currentchunkis(iff,ID_8SVX,ID_BODY))) { message("LoadSBody: not at BODY!"); return(IFFERR_READ); } sbytes = ChunkMoreBytes(CurrentChunk(iff)); /* if we have to decompress, let's just load it into public mem */ memtype = vhdr->sCompression ? MEMF_PUBLIC : MEMF_CHIP; D(bug("LoadSBody: samplebytes=%ld, compression=%ld\n", sbytes,vhdr->sCompression)); if(!(esvx->sample = (BYTE *)AllocMem(sbytes, memtype))) { error = CLIENT_ERROR; } else { D(bug("LoadSBody: have load buffer\n")); esvx->samplebytes = sbytes; if(rlen=ReadChunkBytes(iff,esvx->sample,sbytes) != sbytes) error = IFFERR_READ; if(error) { D(bug("LoadSBody: ReadChunkBytes error = %ld, read %ld bytes\n", error)); UnloadSample(esvx); } else if (vhdr->sCompression) /* Decompress, if needed. */ { if(t = (BYTE *)AllocMem(sbytes<<1, MEMF_CHIP)) { D(bug("LoadSBody: have decompression buffer\n")); DUnpack(esvx->sample, sbytes, t); FreeMem(esvx->sample, sbytes); esvx->sample = t; esvx->samplebytes = sbytes << 1; } else { UnloadSample(esvx); error = IFFERR_NOMEM; } } } return(error); } /** UnloadSBody() ******************************************************** * * Deallocates esvx->smaple * *************************************************************************/ void UnloadSBody(struct EightSVXInfo *esvx) { if(esvx) { if(esvx->sample) { DD(bug("About to free SBody\n")); FreeMem(esvx->sample,esvx->samplebytes); esvx->sample = NULL; } esvx->samplebytes = NULL; } } /* DUnpack.c --- Fibonacci Delta decompression by Steve Hayes */ /* Fibonacci delta encoding for sound data */ BYTE codeToDelta[16] = {-34,-21,-13,-8,-5,-3,-2,-1,0,1,2,3,5,8,13,21}; /* Unpack Fibonacci-delta encoded data from n byte source * buffer into 2*n byte dest buffer, given initial data * value x. It returns the lats data value x so you can * call it several times to incrementally decompress the data. */ BYTE D1Unpack(BYTE source[], LONG n, BYTE dest[], BYTE x) { BYTE d; LONG i, lim; lim = n << 1; for (i=0; i < lim; ++i) { /* Decode a data nibble, high nibble then low nibble */ d = source[i >> 1]; /* get a pair of nibbles */ if (i & 1) /* select low or high nibble */ d &= 0xf; /* mask to get the low nibble */ else d >>= 4; /* shift to get the high nibble */ x += codeToDelta[d]; /* add in the decoded delta */ dest[i] = x; /* store a 1 byte sample */ } return(x); } /* Unpack Fibonacci-delta encoded data from n byte * source buffer into 2*(n-2) byte dest buffer. * Source buffer has a pad byte, an 8-bit initial * value, followed by n-2 bytes comprising 2*(n-2) * 4-bit encoded samples. */ void DUnpack(source, n, dest) BYTE source[], dest[]; LONG n; { D1Unpack(source+2, n-2, dest, source[1]); }
apps/RawtoILBM/RawtoILBM.c
/* RawtoILBM * Converts raw file (from ILBMtoRaw) into an ILBM * Requires linkage with several iffparse modiules - See Makefile */ #include "iffp/ilbmapp.h" #include <intuition/intuitionbase.h> #include <workbench/workbench.h> #ifdef LATTICE int CXBRK(void) { return(0); } /* Disable Lattice CTRL/C handling */ int chkabort(void) { return(0); } /* really */ #endif char *vers = "\0$VER: RawtoILBM 37.5"; char *Copyright = "RawtoILBM v37.5 - converts raw file to ILBM - Freely Redistributable"; #define MINARGS 6 char *usage = "Usage: RawtoILBM rawname ilbmname width height depth\n"; void bye(UBYTE *s,int e); void cleanup(void); struct Library *IntuitionBase = NULL; struct Library *GfxBase = NULL; struct Library *IFFParseBase = NULL; struct ILBMInfo ilbm = {0}; USHORT colortable[MAXAMCOLORREG]; BOOL fromWB; void main(int argc, char **argv) { LONG error = 0L, rawfile, rlen; USHORT width, height, depth, pwidth, pheight, pmode, extra; ULONG plsize; char *rawname,*ilbmname; int k; fromWB = (argc==0) ? TRUE : FALSE; if(!(IntuitionBase = OpenLibrary("intuition.library", 0))) bye("Can't open intuition library.\n",RETURN_WARN); if(!(GfxBase = OpenLibrary("graphics.library",0))) bye("Can't open graphics library.\n",RETURN_WARN); if(!(IFFParseBase = OpenLibrary("iffparse.library",0))) bye("Can't open iffparse library.\n",RETURN_WARN); if(!(ilbm.ParseInfo.iff = AllocIFF())) bye(IFFerr(IFFERR_NOMEM),RETURN_WARN); if(argc==MINARGS) /* Passed filenames via command line */ { rawname = argv[1]; ilbmname = argv[2]; width = atoi(argv[3]); height = atoi(argv[4]); depth = atoi(argv[5]); /* Page width, height, and mode for saved ILBM */ pwidth = width < 320 ? 320 : width; pheight = height < 200 ? 200 : height; pmode = pwidth >= 640 ? HIRES : 0L; pmode |= pheight >= 400 ? LACE : 0L; plsize = RASSIZE(width,height); } else { printf("%s\n%s\n",Copyright,usage); bye("\n",RETURN_OK); } if(!(rawfile = Open(rawname,MODE_OLDFILE))) { printf("Can't open raw file '%s'\n",rawname); bye(" ",RETURN_WARN); } /* * Allocate Bitmap and planes */ extra = depth > 8 ? depth - 8 : 0; if(ilbm.brbitmap = AllocMem(sizeof(struct BitMap) + (extra<<2), MEMF_CLEAR)) { InitBitMap(ilbm.brbitmap,depth,width,height); for(k=0, error=0, rlen=1; k<depth && (!error) && (rlen >0); k++) { if(!(ilbm.brbitmap->Planes[k] = AllocRaster(width,height))) error = IFFERR_NOMEM; if(! error) { BltClear(ilbm.brbitmap->Planes[k], RASSIZE(width,height),0); /* Read a plane */ rlen = Read(rawfile,ilbm.brbitmap->Planes[k],plsize); } } /* get colortable */ if((!error)&&(rlen > 0)) rlen=Read(rawfile,colortable,(MIN(1<<depth,MAXAMCOLORREG)<<1)); if((error)||(rlen<=0)) { if(rlen <= 0) printf("Error loading raw file - check dimensions\n"); else printf("Error allocating planes\n"); } else { error = saveilbm(&ilbm, ilbm.brbitmap, pmode, width, height, pwidth, pheight, colortable, MIN(1<<depth,MAXAMCOLORREG), 4, /* colors */ mskNone, 0, /* masking. transColor */ NULL, NULL, /* additional chunk lists */ ilbmname); } for(k=0; k<depth; k++) { if(ilbm.brbitmap->Planes[k]) FreeRaster(ilbm.brbitmap->Planes[k],width,height); } FreeMem(ilbm.brbitmap, sizeof(struct BitMap) + (extra << 2)); } Close(rawfile); if(error) { printf("%s\n",IFFerr(error)); bye(" ", RETURN_FAIL); } else bye("",RETURN_OK); } void bye(UBYTE *s,int e) { if(s&&(*s)) printf("%s\n",s); if ((fromWB)&&(*s)) /* Wait so user can read messages */ { printf("\nPRESS RETURN TO EXIT\n"); while(getchar() != '\n'); } cleanup(); exit(e); } void cleanup() { if(ilbm.ParseInfo.iff) FreeIFF(ilbm.ParseInfo.iff); if(GfxBase) CloseLibrary(GfxBase); if(IntuitionBase) CloseLibrary(IntuitionBase); if(IFFParseBase) CloseLibrary(IFFParseBase); }
apps/ScreenSave/ScreenSave.c
/* ScreenSave * Saves front screen as an ILBM * Requires linkage with several iffparse modiules - See Makefile */ #include "iffp/ilbmapp.h" #include <intuition/intuitionbase.h> #include <workbench/workbench.h> #include <clib/icon_protos.h> #ifdef LATTICE int CXBRK(void) { return(0); } /* Disable Lattice CTRL/C handling */ int chkabort(void) { return(0); } /* really */ #endif char *vers = "\0$VER: screensave 37.5"; char *Copyright = "screensave v37.5 - supports new modes - Freely Redistributable"; char *usage = "Usage: screensave filename (filename -c[unit] for clipboard)\n" "Options: QUIET, NODELAY, NOICON, SEQUENCE (sequence adds a number to name)\n" "Saves front screen after 10-sec delay (unless NODELAY).\n"; int mygets(char *s); void bye(UBYTE *s,int e); void cleanup(void); struct Library *IntuitionBase = NULL; struct Library *GfxBase = NULL; struct Library *IconBase = NULL; struct Library *IFFParseBase = NULL; struct ILBMInfo ilbm = {0}; BOOL fromWB, Quiet, NoDelay, NoIcon, Sequence; #define INBUFSZ 128 char nbuf[INBUFSZ]; /* Data for project icon for saved ILBM * */ UWORD ILBMI1Data[] = { /* Plane 0 */ 0x0000,0x0000,0x0000,0x0001,0x0000,0x0000,0x0000,0x0003, 0x0FFF,0xFFFF,0xFFFF,0xFFF3,0x0FFF,0x0000,0x0000,0xFFF3, 0x0FFC,0x0000,0x0000,0x3FF3,0x0FE0,0x0E80,0xF800,0x07F3, 0x0F80,0x1C01,0x8C00,0x01F3,0x0F00,0x0001,0x8C00,0x00F3, 0x0600,0x0000,0x0600,0x0063,0x0600,0x0003,0xBC00,0x0063, 0x0600,0x0001,0xFC00,0x0063,0x0600,0x0000,0xFC00,0x0063, 0x0600,0x1FC1,0xFE40,0x0063,0x0600,0x1DC1,0xFE20,0x0063, 0x0600,0x1CE3,0xFF12,0x0063,0x0F00,0x1CE0,0x004F,0xC0F3, 0x0F80,0x1CE0,0x002F,0x01F3,0x0FE0,0x0E78,0x423D,0x07F3, 0x0FFC,0x0000,0x0000,0x3FF3,0x0FFF,0x0000,0x0000,0xFFF3, 0x0FFF,0xFFFF,0xFFFF,0xFFF3,0x0000,0x0000,0x0000,0x0003, 0x7FFF,0xFFFF,0xFFFF,0xFFFF, /* Plane 1 */ 0xFFFF,0xFFFF,0xFFFF,0xFFFE,0xD555,0x5555,0x5555,0x5554, 0xD000,0x0000,0x0000,0x0004,0xD3FC,0xFFFF,0xFFFF,0x3FC4, 0xD3C0,0x0000,0x0000,0x03C4,0xD300,0x0100,0xF800,0x00C4, 0xD300,0x0381,0xFC00,0x00C4,0xD080,0x0701,0xFC00,0x0104, 0xD180,0xF883,0xFE00,0x0194,0xD181,0xDF80,0x4700,0x0194, 0xD181,0xDF82,0x0180,0x0194,0xD180,0x6F82,0x00C0,0x0194, 0xD180,0x0002,0x0020,0x0194,0xD180,0x0000,0x0000,0x0194, 0xD180,0x0000,0x0002,0x0194,0xD080,0x0000,0xCC46,0xC104, 0xD300,0x0000,0xCC2F,0x00C4,0xD300,0x0E78,0x883D,0x00C4, 0xD3C0,0x0000,0x0000,0x03C4,0xD3FC,0xFFFF,0xFFFF,0x3FC4, 0xD000,0x0000,0x0000,0x0004,0xD555,0x5555,0x5555,0x5554, 0x8000,0x0000,0x0000,0x0000, }; struct Image ILBMI1 = { 0, 0, /* Upper left corner */ 64, 23, 2, /* Width, Height, Depth */ ILBMI1Data, /* Image data */ 0x0003, 0x0000, /* PlanePick, PlaneOnOff */ NULL /* Next image */ }; UBYTE *ILBMTools[] = { "FILETYPE=ILBM", NULL }; struct DiskObject ILBMobject = { WB_DISKMAGIC, /* Magic Number */ WB_DISKVERSION, /* Version */ { /* Embedded Gadget Structure */ NULL, /* Next Gadget Pointer */ 0, 0, 64, 24, /* Left,Top,Width,Height */ GADGIMAGE | GADGBACKFILL, /* Flags */ RELVERIFY | GADGIMMEDIATE, /* Activation Flags */ BOOLGADGET, /* Gadget Type */ (APTR)&ILBMI1, /* Render Image */ NULL, /* Select Image */ NULL, /* Gadget Text */ NULL, /* Mutual Exclude */ NULL, /* Special Info */ 0, /* Gadget ID */ NULL, /* User Data */ }, WBPROJECT, /* Icon Type */ "Display", /* Default Tool */ ILBMTools, /* Tool Type Array */ NO_ICON_POSITION, /* Current X */ NO_ICON_POSITION, /* Current Y */ NULL, /* Drawer Structure */ NULL, /* Tool Window */ 0 /* Stack Size */ }; void main(int argc, char **argv) { struct Screen *frontScreen; LONG error = 0L, seqlock; char *filename; int l, k; fromWB = (argc==0) ? TRUE : FALSE; if(!(IntuitionBase = OpenLibrary("intuition.library", 0))) bye("Can't open intuition library.\n",RETURN_WARN); if(!(GfxBase = OpenLibrary("graphics.library",0))) bye("Can't open graphics library.\n",RETURN_WARN); if(!(IFFParseBase = OpenLibrary("iffparse.library",0))) bye("Can't open iffparse library.\n",RETURN_WARN); if(!(IconBase = OpenLibrary("icon.library",0))) bye("Can't open icon library.\n",RETURN_WARN); if(!(ilbm.ParseInfo.iff = AllocIFF())) bye(IFFerr(IFFERR_NOMEM),RETURN_WARN); if(argc>1) /* Passed filename via command line */ { if(argv[1][0]=='?') { printf("%s\n%s\n",Copyright,usage); bye("\n",RETURN_OK); } else filename = argv[1]; NoDelay = NoIcon = Quiet = Sequence = FALSE; for(k=2; k < (argc); k++) { if(!(stricmp(argv[k],"NODELAY"))) NoDelay = TRUE; else if(!(stricmp(argv[k],"NOICON"))) NoIcon = TRUE; else if(!(stricmp(argv[k],"QUIET"))) Quiet = TRUE; else if(!(stricmp(argv[k],"SEQUENCE"))) Sequence = TRUE; } if(Sequence) { for(k=1; k<9999; k++) { sprintf(nbuf,"%s%04ld",filename,k); if(seqlock = Lock(nbuf,ACCESS_READ)) UnLock(seqlock); else break; } filename = nbuf; } } else { printf("%s\n%s\n",Copyright,usage); printf("Enter filename for save: "); l = mygets(&nbuf[0]); if(l==0) /* No filename - Exit */ { bye("\nScreen not saved, filename required\n",RETURN_FAIL); } else { filename = &nbuf[0]; } } if(!NoDelay) Delay(500); Forbid(); frontScreen = ((struct IntuitionBase *)IntuitionBase)->FirstScreen; Permit(); if(error = screensave(&ilbm, frontScreen, NULL, NULL, filename)) { printf("%s\n",IFFerr(error)); } else { if(!Quiet) printf("Screen saved as %s... ",filename); if((!NoIcon)&&(filename[0]!='-')&&(filename[1]!='c')) /* not clipboard */ { if(!(PutDiskObject(filename,&ILBMobject))) { bye("Error saving icon\n",RETURN_WARN); } if(!Quiet) printf("Icon saved\n"); } else if(!Quiet) printf("\n"); bye("",RETURN_OK); } } void bye(UBYTE *s,int e) { if(s&&(*s)) printf("%s\n",s); if ((fromWB)&&(*s)) /* Wait so user can read messages */ { printf("\nPRESS RETURN TO EXIT\n"); mygets(&nbuf[0]); } cleanup(); exit(e); } void cleanup() { if(ilbm.ParseInfo.iff) FreeIFF(ilbm.ParseInfo.iff); if(GfxBase) CloseLibrary(GfxBase); if(IntuitionBase) CloseLibrary(IntuitionBase); if(IconBase) CloseLibrary(IconBase); if(IFFParseBase) CloseLibrary(IFFParseBase); } int mygets(char *s) { int l = 0, max = INBUFSZ - 1; while (((*s = getchar()) !='\n' )&&(l < max)) s++, l++; *s = NULL; return(l); }
modules/bmprintc.c
/*--------------------------------------------------------------*/ /* */ /* bmprintc.c */ /* */ /* print out a C-language representation of data for bitmap */ /* */ /* By Jerry Morrison and Steve Shaw, Electronic Arts. */ /* This software is in the public domain. */ /* */ /* This version for the Commodore-Amiga computer. */ /* Cleaned up and modified a bit by Chuck McManis, Aug 1988 */ /* Modified 05/91 by CBM for use with iffparse modules */ /* */ /*--------------------------------------------------------------*/ #include "iffp/ilbmapp.h" #include <stdio.h> #define NO 0 #define YES 1 void PSprite(struct BitMap *bm, FILE *fp, UBYTE *name, int p, BOOL dohead); void PrCRLF(FILE *fp); void PrintBob(struct BitMap *bm, FILE *fp, UBYTE *name); void PrintSprite(struct BitMap *bm, FILE *fp, UBYTE *name, BOOL attach, BOOL dohdr); static BOOL doCRLF; char sp_colors[] = ".oO@"; void PrCRLF(FILE *fp) { if (doCRLF) fprintf(fp, "%c%c", 0xD, 0xA); else fprintf(fp, "\n"); } void PrintBob(struct BitMap *bm, FILE *fp, UBYTE *name) { register UWORD *wp; /* Pointer to the bitmap data */ short p,i,j,nb; /* temporaries */ short nwords = (bm->BytesPerRow/2)*bm->Rows; fprintf(fp, "/*----- bitmap : w = %ld, h = %ld ------ */", bm->BytesPerRow*8, bm->Rows); PrCRLF(fp); for (p = 0; p < bm->Depth; ++p) { /* For each bit plane */ wp = (UWORD *)bm->Planes[p]; fprintf(fp, "/*------ plane # %ld: --------*/", p); PrCRLF(fp); fprintf(fp, "UWORD %s%c[%ld] = { ", name, (p?('0'+p):' '), nwords); PrCRLF(fp); for (j = 0; j < bm->Rows; j++, wp += (bm->BytesPerRow >> 1)) { fprintf(fp, " "); for (nb = 0; nb < (bm->BytesPerRow) >> 1; nb++) fprintf(fp, "0x%04x,", *(wp+nb)); if (bm->BytesPerRow <= 6) { fprintf(fp, "\t/* "); for (nb = 0; nb < (bm->BytesPerRow) >> 1; nb++) for (i=0 ; i<16; i++) fprintf(fp, "%c", (((*(wp+nb)>>(15-i))&1) ? '*' : '.')); fprintf(fp, " */"); } PrCRLF(fp); } fprintf(fp," };"); PrCRLF(fp); } } void PSprite(struct BitMap *bm, FILE *fp, UBYTE *name, int p, BOOL dohead) { UWORD *wp0, *wp1; /* Pointer temporaries */ short i, j, nwords, /* Counter temporaries */ color; /* pixel color */ short wplen = bm->BytesPerRow/2; nwords = 2*bm->Rows + (dohead?4:0); wp0 = (UWORD *)bm->Planes[p]; wp1 = (UWORD *)bm->Planes[p+1]; fprintf(fp, "UWORD %s[%ld] = {", name, nwords); PrCRLF(fp); if (dohead) { fprintf(fp," 0x0000, 0x0000, /* VStart, VStop */"); PrCRLF(fp); } for (j=0 ; j < bm->Rows; j++) { fprintf(fp, " 0x%04x, 0x%04x", *wp0, *wp1); if (dohead || (j != bm->Rows-1)) { fprintf(fp, ","); } fprintf(fp, "\t/* "); for (i = 0; i < 16; i++) { color = ((*wp1 >> (14-i)) & 2) + ((*wp0 >> (15-i)) & 1); fprintf(fp, "%c", sp_colors[color]); } fprintf(fp," */"); PrCRLF(fp); wp0 += wplen; wp1 += wplen; } if (dohead) fprintf(fp, " 0x0000, 0x0000 }; /* End of Sprite */"); else fprintf(fp," };"); PrCRLF(fp); PrCRLF(fp); } void PrintSprite(struct BitMap *bm, FILE *fp, UBYTE *name, BOOL attach, BOOL dohdr) { fprintf(fp,"/*----- Sprite format: h = %ld ------ */", bm->Rows); PrCRLF(fp); if (bm->Depth > 1) { fprintf(fp, "/*--Sprite containing lower order two planes: */"); PrCRLF(fp); PSprite(bm, fp, name, 0, dohdr); } if (attach && (bm->Depth > 3) ) { strcat(name, "1"); fprintf(fp, "/*--Sprite containing higher order two planes: */"); PrCRLF(fp); PSprite(bm, fp, name, 2, dohdr); } } #define BOB 0 #define SPRITE 1 /* BMPrintCRep * Passed pointer to BitMap structure, C filehandle opened for write, * name associated with file, and string describing the output * format desired (see cases below), outputs C representation of the ILBM. */ void BMPrintCRep(struct BitMap *bm, FILE *fp, UBYTE *name, UBYTE *fmt) { BOOL attach, doHdr; char c; SHORT type; doCRLF = NO; doHdr = YES; type = BOB; attach = NO; while ( (c=*fmt++) != 0 ) switch (c) { case 'b': type = BOB; break; case 's': type = SPRITE; attach = NO; break; case 'a': type = SPRITE; attach = YES; break; case 'n': doHdr = NO; break; case 'c': doCRLF = YES; break; } switch(type) { case BOB: PrintBob(bm, fp, name); break; case SPRITE: PrintSprite(bm, fp, name, attach, doHdr); break; } }
modules/copychunks.c
/* copychunks * * For Read/Modify/Write programs and other programs that need * to close the IFF file but still reference gathered chunks. * Copies your gathered property and collection chunks * from an iff context so that IFF handle may be * closed right after parsing (allowing file or clipboard to * to be reopened for read or write by self or other programs) * * The created list of chunks can be modified and written * back out to a new handle with writechunklist(). * * If you have used copychunks(), remember to free the copied * chunks with freechunklist(), when ready, to deallocate them. * * Note that this implementation is flat and is suitable only * for simple FORMs. */ #include "iffp/iff.h" /* copychunks() * * Copies chunks specified in propchks and collectchks * FROM an already-parsed IFFHandle * TO a singly linked list of Chunk structures, * and returns a pointer to the start of the list. * * Generally you would store this pointer in parseInfo.copiedchunks. * * You must later free the list of copied chunks by calling * FreeChunkList(). * * Reorders collection chunks so they appear in SAME ORDER * in chunk list as they did in the file. * * Returns 0 for failure */ struct Chunk *copychunks(struct IFFHandle *iff, LONG *propchks, LONG *collectchks, ULONG memtype) { struct Chunk *chunk, *first=NULL, *prevchunk = NULL; struct StoredProperty *sp; struct CollectionItem *ci, *cii; long error; int k, kk, bk; if(!iff) return(NULL); /* Copy gathered property chunks */ error = 0; for(k=0; (!error) && (propchks) && (propchks[k] != TAG_DONE); k+=2) { if(sp=FindProp(iff,propchks[k],propchks[k+1])) { D(bug("copying %.4s.%.4s chunk\n",&propchks[k],&propchks[k+1])); if(chunk=(struct Chunk *) AllocMem(sizeof(struct Chunk),memtype|MEMF_CLEAR)) { chunk->ch_Type = propchks[k]; chunk->ch_ID = propchks[k+1]; if(chunk->ch_Data = AllocMem(sp->sp_Size,memtype)) { chunk->ch_Size = sp->sp_Size; CopyMem(sp->sp_Data,chunk->ch_Data,sp->sp_Size); if(prevchunk) prevchunk->ch_Next = chunk; else first = chunk; prevchunk = chunk; } else { FreeMem(chunk,sizeof(struct Chunk)); chunk=NULL; error = 1; } } else error = 1; } } /* Copy gathered collection chunks in reverse order */ for(k=0; (!error) && (collectchks) && (collectchks[k] != TAG_DONE); k+=2) { if(ci=FindCollection(iff,collectchks[k],collectchks[k+1])) { D(bug("copying %.4s.%.4s collection\n",&collectchks[k],&collectchks[k+1])); for(cii=ci, bk=0; cii; cii=cii->ci_Next) bk++; D(bug(" There are %ld of these, first is at $%lx\n",bk,ci)); for( bk; bk; bk--) { for(kk=1, cii=ci; kk<bk; kk++) cii=cii->ci_Next; D(bug(" copying number %ld\n",kk)); if(chunk=(struct Chunk *) AllocMem(sizeof(struct Chunk),memtype|MEMF_CLEAR)) { chunk->ch_Type = collectchks[k]; chunk->ch_ID = collectchks[k+1]; if(chunk->ch_Data = AllocMem(cii->ci_Size,memtype)) { chunk->ch_Size = cii->ci_Size; CopyMem(cii->ci_Data,chunk->ch_Data,cii->ci_Size); if(prevchunk) prevchunk->ch_Next = chunk; else first = chunk; prevchunk = chunk; } else { FreeMem(chunk,sizeof(struct Chunk)); chunk=NULL; error = 1; } } else error = 1; } } } if(error) { if(first) freechunklist(first); first = NULL; } return(first); } /* freechunklist - Free a dynamically allocated Chunk list and * all of its ch_Data. * * Note - if a chunk's ch_Size is IFFSIZE_UNKNOWN, its ch_Data * will not be deallocated. */ void freechunklist(struct Chunk *first) { struct Chunk *chunk, *next; chunk = first; while(chunk) { next = chunk->ch_Next; if((chunk->ch_Data)&&(chunk->ch_Size != IFFSIZE_UNKNOWN)) FreeMem(chunk->ch_Data,chunk->ch_Size); FreeMem(chunk, sizeof(struct Chunk)); chunk = next; } } /* findchunk - find first matching chunk in list of struct Chunks * example finchunk(pi->copiedchunks,ID_ILBM,ID_CRNG); * * returns struct Chunk *, or NULL if none found */ struct Chunk *findchunk(struct Chunk *first, long type, long id) { struct Chunk *chunk; for(chunk=first; chunk; chunk=chunk->ch_Next) { if((chunk->ch_Type == type)&&(chunk->ch_ID == id)) return(chunk); } return(NULL); } /* writechunklist - write out list of struct Chunk's * If data is a null terminated string, you may use * IFFSIZE_UNKNOWN as the ch_Szie and strlen(chunk->ch_Data) * will be used here as size. * * Returns 0 for success or an IFFERR */ long writechunklist(struct IFFHandle *iff, struct Chunk *first) { struct Chunk *chunk; long size, error = 0; D(bug("writechunklist: first chunk pointer = $%lx\n",first)); for(chunk=first; chunk && (!error); chunk=chunk->ch_Next) { size = (chunk->ch_Size == IFFSIZE_UNKNOWN) ? strlen(chunk->ch_Data) : chunk->ch_Size; error = PutCk(iff, chunk->ch_ID, size, chunk->ch_Data); D(bug("writechunklist: put %.4s size=%ld, error=%ld\n", &chunk->ch_ID,size, error)); } return(error); }
modules/getbitmap.c
/*----------------------------------------------------------------------* * GETBITMAP.C Support routines for reading ILBM files. * (IFF is Interchange Format File.) * * Based on code by Jerry Morrison and Steve Shaw, Electronic Arts. * This software is in the public domain. * Modified for iffparse.library by CBM 04/90 * This version for the Commodore-Amiga computer. *----------------------------------------------------------------------*/ #include "iffp/ilbm.h" #include "iffp/packer.h" #include "iffp/ilbmapp.h" /* createbrush * * Passed an initialized ILBMInfo with a parsed IFFHandle (chunks parsed, * stopped at BODY), * gets the bitmap and colors * Sets up ilbm->brbitmap, ilbm->colortable, ilbm->ncolors * Returns 0 for success */ LONG createbrush(struct ILBMInfo *ilbm) { int error; error = getbitmap(ilbm); if(!error) error = loadbody(ilbm->ParseInfo.iff, ilbm->brbitmap,&ilbm->Bmhd); if(!error) getcolors(ilbm); if(error) deletebrush(ilbm); return(error); } /* deletebrush * * closes and deallocates created brush bitmap and colors */ void deletebrush(ilbm) struct ILBMInfo *ilbm; { freebitmap(ilbm); freecolors(ilbm); } /* getbitmap * * Passed an initialized ILBMInfo with parsed IFFHandle (chunks parsed, * stopped at BODY), allocates a BitMap structure and planes just large * enough for the BODY. Generally used for brushes but may be used * to load backgrounds without displaying, or to load deep ILBM's. * Sets ilbm->brbitmap. Returns 0 for success. */ LONG getbitmap(struct ILBMInfo *ilbm) { struct IFFHandle *iff; BitMapHeader *bmhd; USHORT wide, high; LONG error = NULL; int k, extra=0; BYTE deep; if(!(iff=ilbm->ParseInfo.iff)) return(CLIENT_ERROR); ilbm->brbitmap = NULL; if (!( bmhd = (BitMapHeader *) findpropdata(iff, ID_ILBM, ID_BMHD))) { message("No ILBM.BMHD chunk!\n"); return(IFFERR_SYNTAX); } *(&ilbm->Bmhd) = *bmhd; /* copy contents of BMHD */ wide = BitsPerRow(bmhd->w); high = bmhd->h; deep = bmhd->nPlanes; ilbm->camg = getcamg(ilbm); D(bug("allocbitmap: bmhd=$%lx wide=%ld high=%ld deep=%ld\n", bmhd,wide,high,deep)); /* * Allocate Bitmap and planes */ extra = deep > 8 ? deep - 8 : 0; if(ilbm->brbitmap = AllocMem(sizeof(struct BitMap)+(extra<<2),MEMF_CLEAR)) { InitBitMap(ilbm->brbitmap,deep,wide,high); for(k=0; k<deep && (!error); k++) { if(!(ilbm->brbitmap->Planes[k] = AllocRaster(wide,high))) error = 1; if(! error) BltClear(ilbm->brbitmap->Planes[k],RASSIZE(wide,high),0); } if(error) { message("Failed to allocate raster\n"); freebitmap(ilbm); } } else error = 1; return(error); } /* freebitmap * * deallocates ilbm->brbitmap BitMap structure and planes */ void freebitmap(struct ILBMInfo * ilbm) { int k, extra=0; if(ilbm->brbitmap) { for(k=0; k< ilbm->brbitmap->Depth; k++) { if(ilbm->brbitmap->Planes[k]) FreeRaster(ilbm->brbitmap->Planes[k], (USHORT)(ilbm->brbitmap->BytesPerRow << 3), ilbm->brbitmap->Rows); } extra = ilbm->brbitmap->Depth > 8 ? ilbm->brbitmap->Depth - 8 : 0; FreeMem(ilbm->brbitmap,sizeof(struct BitMap) + (extra << 2)); ilbm->brbitmap = NULL; } } /* end */
modules/getdisplay.c
/*----------------------------------------------------------------------* * GETDISPLAY.C Support routines for reading/displaying ILBM files. * (IFF is Interchange Format File.) * * Based on code by Jerry Morrison and Steve Shaw, Electronic Arts. * This software is in the public domain. * Modified for iffparse.library by CBM 04/90 * This version for the Commodore-Amiga computer. *----------------------------------------------------------------------*/ #include "iffp/ilbm.h" #include "iffp/packer.h" #include "iffp/ilbmapp.h" extern struct Library *GfxBase; /* showilbm * * Passed an ILBMInfo initilized with with a not-in-use ParseInfo.iff * IFFHandle and desired propchks, collectchks, stopchks, and a filename, * will load and display an ILBM, initializing ilbm->Bmhd, ilbm->camg, * ilbm->scr, ilbm->win, ilbm->vp, ilbm->srp, ilbm->wrp, * ilbm->colortable, and ilbm->ncolors. * * Note that ncolors may be more colors than you can LoadRGB4. * Use MIN(ilbm->ncolors,MAXAMCOLORREG) for color count if you change * the colors yourself using 1.3/2.0 functions. * * Returns 0 for success or an IFFERR (libraries/iffparse.h) */ LONG showilbm(struct ILBMInfo *ilbm, UBYTE *filename) { LONG error = 0L; if(!(ilbm->ParseInfo.iff)) return(CLIENT_ERROR); if(!(error = openifile((struct ParseInfo *)ilbm, filename, IFFF_READ))) { D(bug("showilbm: openifile successful\n")); error = parseifile((struct ParseInfo *)ilbm, ID_FORM, ID_ILBM, ilbm->ParseInfo.propchks, ilbm->ParseInfo.collectchks, ilbm->ParseInfo.stopchks); if((!error)||(error == IFFERR_EOC)||(error == IFFERR_EOF)) { D(bug("showilbm: parseifile successful\n")); if(contextis(ilbm->ParseInfo.iff,ID_ILBM,ID_FORM)) { if(error = createdisplay(ilbm)) deletedisplay(ilbm); } else { closeifile((struct ParseInfo *)ilbm); message("Not an ILBM\n"); error = NOFILE; } } } return(error); } /* unshowilbm * * frees and closes everything alloc'd/opened by showilbm */ void unshowilbm(struct ILBMInfo *ilbm) { deletedisplay(ilbm); closeifile((struct ParseInfo *)ilbm); } /* createdisplay * * Passed a initialized ILBMInfo with parsed IFFHandle (chunks parsed, * stopped at BODY), * opens/allocs the display and colortable, and displays the ILBM. * * If successful, sets up ilbm->Bmhd, ilbm->camg, ilbm->scr, ilbm->win, * ilbm->vp, ilbm->wrp, ilbm->srp and also ilbm->colortable and * ilbm->ncolors. * * Note that ncolors may be more colors than you can LoadRGB4. * Use MIN(ilbm->ncolors,MAXAMCOLORREG) for color count if you change * the colors yourself using 1.3/2.0 functions. * * Returns 0 for success or an IFFERR (libraries/iffparse.h) */ LONG createdisplay(struct ILBMInfo *ilbm) { int error; D(bug("createdisplay:\n")); error = getdisplay(ilbm); D(bug("createdisplay: after getdisplay, error = %ld\n", error)); if(!error) error = loadbody(ilbm->ParseInfo.iff, &ilbm->scr->BitMap,&ilbm->Bmhd); D(bug("createdisplay: after loadbody, error = %ld\n", error)); if(!error) { if(!(getcolors(ilbm))) LoadRGB4(ilbm->vp, ilbm->colortable, MIN(ilbm->ncolors,MAXAMCOLORREG)); } if(error) deletedisplay(ilbm); return(error); } /* deletedisplay * * closes and deallocates created display and colors */ void deletedisplay(struct ILBMInfo *ilbm) { freedisplay(ilbm); freecolors(ilbm); } /* getdisplay * * Passed an initialized ILBMInfo with a parsed IFFHandle (chunks parsed, * stopped at BODY), * gets the dimensions and mode for the display and calls the external * routine opendisplay(). Our opendisplay() is in the screen.c * module. It opens a 2.0 or 1.3, ECS or non-ECS screen and window. * It also does 2.0 overscan centering based on the closest user prefs. * * If successful, sets up ilbm->Bmhd, ilbm->camg, ilbm->scr, ilbm->win, * ilbm->vp, ilbm->wrp, ilbm->srp * * Returns 0 for success or an IFFERR (libraries/iffparse.h) */ LONG getdisplay(struct ILBMInfo *ilbm) { struct IFFHandle *iff; BitMapHeader *bmhd; ULONG modeid; UWORD wide, high, deep; if(!(iff=ilbm->ParseInfo.iff)) return(CLIENT_ERROR); if(!(bmhd = (BitMapHeader *)findpropdata(iff, ID_ILBM, ID_BMHD))) { message ("No ILBM.BMHD chunk\n"); return(IFFERR_SYNTAX); } *(&ilbm->Bmhd) = *bmhd; wide = (RowBytes(bmhd->w)) >= (RowBytes(bmhd->pageWidth)) ? bmhd->w : bmhd->pageWidth; high = MAX(bmhd->h, bmhd->pageHeight); deep = MIN(bmhd->nPlanes,MAXAMDEPTH); ilbm->camg = modeid = getcamg(ilbm); /* * Open the display */ if(!(opendisplay(ilbm,wide,high,deep,modeid))) { message("Failed to open display.\n"); return(1); } return(0); } /* freedisplay * * closes and deallocates display from getdisplay (not colors) */ void freedisplay(struct ILBMInfo *ilbm) { closedisplay(ilbm); }
modules/ilbmr.c
/* ilbmr.c --- ILBM loading routines for use with iffparse */ /*----------------------------------------------------------------------* * ILBMR.C Support routines for reading ILBM files. * (IFF is Interchange Format File.) * * Based on code by Jerry Morrison and Steve Shaw, Electronic Arts. * This software is in the public domain. * Modified for iffparse.library 05/90 * This version for the Commodore-Amiga computer. *----------------------------------------------------------------------*/ #include "iffp/ilbm.h" #include "iffp/packer.h" #include "iffp/ilbmapp.h" #define movmem CopyMem #define MaxSrcPlanes (25) extern struct Library *GfxBase; /*---------- loadbody ---------------------------------------------------*/ LONG loadbody(iff, bitmap, bmhd) struct IFFHandle *iff; struct BitMap *bitmap; BitMapHeader *bmhd; { BYTE *buffer; ULONG bufsize; LONG error = 1; D(bug("In loadbody\n")); if(!(currentchunkis(iff,ID_ILBM,ID_BODY))) { message("ILBM has no BODY\n"); /* Maybe it's a palette */ return(IFF_OKAY); } if((bitmap)&&(bmhd)) { D(bug("Have bitmap and bmhd\n")); bufsize = MaxPackedSize(RowBytes(bmhd->w)) << 4; if(!(buffer = AllocMem(bufsize,0L))) { D(bug("Buffer alloc of %ld failed\n",bufsize)); return(IFFERR_NOMEM); } error = loadbody2(iff, bitmap, NULL, bmhd, buffer, bufsize); D(bug("Returned from getbody, error = %ld\n",error)); } FreeMem(buffer,bufsize); return(error); } /* like the old GetBODY */ LONG loadbody2(iff, bitmap, mask, bmhd, buffer, bufsize) struct IFFHandle *iff; struct BitMap *bitmap; BYTE *mask; BitMapHeader *bmhd; BYTE *buffer; ULONG bufsize; { UBYTE srcPlaneCnt = bmhd->nPlanes; /* Haven't counted for mask plane yet*/ WORD srcRowBytes = RowBytes(bmhd->w); WORD destRowBytes = bitmap->BytesPerRow; LONG bufRowBytes = MaxPackedSize(srcRowBytes); int nRows = bmhd->h; WORD compression = bmhd->compression; register int iPlane, iRow, nEmpty; register WORD nFilled; BYTE *buf, *nullDest, *nullBuf, **pDest; BYTE *planes[MaxSrcPlanes]; /* array of ptrs to planes & mask */ struct ContextNode *cn; D(bug("srcRowBytes = %ld\n",srcRowBytes)); cn = CurrentChunk(iff); if (compression > cmpByteRun1) return(CLIENT_ERROR); D(bug("loadbody2: compression=%ld srcBytes=%ld bitmapBytes=%ld\n", compression, srcRowBytes, bitmap->BytesPerRow)); D(bug("loadbody2: bufsize=%ld bufRowBytes=%ld, srcPlaneCnt=%ld\n", bufsize, bufRowBytes, srcPlaneCnt)); /* Complain if client asked for a conversion GetBODY doesn't handle.*/ if ( srcRowBytes > bitmap->BytesPerRow || bufsize < bufRowBytes * 2 || srcPlaneCnt > MaxSrcPlanes ) return(CLIENT_ERROR); D(bug("loadbody2: past conversion checks\n")); if (nRows > bitmap->Rows) nRows = bitmap->Rows; D(bug("loadbody2: srcRowBytes=%ld, srcRows=%ld, srcDepth=%ld, destDepth=%ld\n", srcRowBytes, nRows, bmhd->nPlanes, bitmap->Depth)); /* Initialize array "planes" with bitmap ptrs; NULL in empty slots.*/ for (iPlane = 0; iPlane < bitmap->Depth; iPlane++) planes[iPlane] = (BYTE *)bitmap->Planes[iPlane]; for ( ; iPlane < MaxSrcPlanes; iPlane++) planes[iPlane] = NULL; /* Copy any mask plane ptr into corresponding "planes" slot.*/ if (bmhd->masking == mskHasMask) { if (mask != NULL) planes[srcPlaneCnt] = mask; /* If there are more srcPlanes than * dstPlanes, there will be NULL plane-pointers before this.*/ else planes[srcPlaneCnt] = NULL; /* In case more dstPlanes than src.*/ srcPlaneCnt += 1; /* Include mask plane in count.*/ } /* Setup a sink for dummy destination of rows from unwanted planes.*/ nullDest = buffer; buffer += srcRowBytes; bufsize -= srcRowBytes; /* Read the BODY contents into client's bitmap. * De-interleave planes and decompress rows. * MODIFIES: Last iteration modifies bufsize.*/ buf = buffer + bufsize; /* Buffer is currently empty.*/ for (iRow = nRows; iRow > 0; iRow--) { for (iPlane = 0; iPlane < srcPlaneCnt; iPlane++) { pDest = &planes[iPlane]; /* Establish a sink for any unwanted plane.*/ if (*pDest == NULL) { nullBuf = nullDest; pDest = &nullBuf; } /* Read in at least enough bytes to uncompress next row.*/ nEmpty = buf - buffer; /* size of empty part of buffer.*/ nFilled = bufsize - nEmpty; /* this part has data.*/ if (nFilled < bufRowBytes) { /* Need to read more.*/ /* Move the existing data to the front of the buffer.*/ /* Now covers range buffer[0]..buffer[nFilled-1].*/ movmem(buf, buffer, nFilled); /* Could be moving 0 bytes.*/ if(nEmpty > ChunkMoreBytes(cn)) { /* There aren't enough bytes left to fill the buffer.*/ nEmpty = ChunkMoreBytes(cn); bufsize = nFilled + nEmpty; /* heh-heh */ } /* Append new data to the existing data.*/ if(ReadChunkBytes(iff, &buffer[nFilled], nEmpty) < nEmpty) return(CLIENT_ERROR); buf = buffer; nFilled = bufsize; nEmpty = 0; } /* Copy uncompressed row to destination plane.*/ if(compression == cmpNone) { if(nFilled < srcRowBytes) return(IFFERR_MANGLED); movmem(buf, *pDest, srcRowBytes); buf += srcRowBytes; *pDest += destRowBytes; } else { /* Decompress row to destination plane.*/ if ( unpackrow(&buf, pDest, nFilled, srcRowBytes) ) /* pSource, pDest, srcBytes, dstBytes */ return(IFFERR_MANGLED); else *pDest += (destRowBytes - srcRowBytes); } } } return(IFF_OKAY); } /* ----------- getcolors ------------- */ /* getcolors - allocates a ilbm->colortable for at least MAXAMCOLORREG * and loads CMAP colors into it, setting ilbm->ncolors to number * of colors actually loaded. */ LONG getcolors(struct ILBMInfo *ilbm) { struct IFFHandle *iff; int error = 1; if(!(iff=ilbm->ParseInfo.iff)) return(CLIENT_ERROR); if(!(error = alloccolortable(ilbm))) error = loadcmap(iff, ilbm->colortable, &ilbm->ncolors); if(error) freecolors(ilbm); D(bug("getcolors: error = %ld\n",error)); return(error); } /* alloccolortable - allocates ilbm->colortable and sets ilbm->ncolors * to the number of colors we have room for in the table. */ LONG alloccolortable(struct ILBMInfo *ilbm) { struct IFFHandle *iff; struct StoredProperty *sp; LONG error = CLIENT_ERROR; ULONG ctabsize; USHORT ncolors; if(!(iff=ilbm->ParseInfo.iff)) return(CLIENT_ERROR); if(sp = FindProp (iff, ID_ILBM, ID_CMAP)) { /* * Compute the size table we need */ ncolors = sp->sp_Size / 3; /* how many in CMAP */ ncolors = MAX(ncolors, MAXAMCOLORREG); ctabsize = ncolors * sizeof(Color4); if(ilbm->colortable = (Color4 *)AllocMem(ctabsize,MEMF_CLEAR|MEMF_PUBLIC)) { ilbm->ncolors = ncolors; ilbm->ctabsize = ctabsize; error = 0L; } else error = IFFERR_NOMEM; } D(bug("alloccolortable for %ld colors: error = %ld\n",ncolors,error)); return(error); } void freecolors(struct ILBMInfo *ilbm) { if(ilbm->colortable) { FreeMem(ilbm->colortable, ilbm->ctabsize); } ilbm->colortable = NULL; ilbm->ctabsize = 0; } /* Passed IFFHandle, pointer to colortable array, and pointer to * a USHORT containing number of colors caller has space to hold, * loads the colors and sets pNcolors to the number actually read. * * NOTE !!! - Old GetCMAP passed a pointer to a UBYTE for pNcolors * This one is passed a pointer to a USHORT */ LONG loadcmap(struct IFFHandle *iff, WORD *colortable,USHORT *pNcolors) { register struct StoredProperty *sp; register LONG idx; register ULONG ncolors; register UBYTE *rgb; LONG r, g, b; if(!(colortable)) { message("No colortable allocated\n"); return(1); } if(!(sp = FindProp (iff, ID_ILBM, ID_CMAP))) return(1); rgb = sp->sp_Data; ncolors = sp->sp_Size / sizeofColorRegister; if(*pNcolors < ncolors) ncolors = *pNcolors; *pNcolors = ncolors; idx = 0; while (ncolors--) { r = (*rgb++ & 0xF0) << 4; g = *rgb++ & 0xF0; b = *rgb++ >> 4; colortable[idx] = r | g | b; idx++; } return(0); } /* * Returns CAMG or computed mode for storage in ilbm->camg * * ilbm->Bmhd structure must be initialized prior to this call. */ ULONG getcamg(struct ILBMInfo *ilbm) { struct IFFHandle *iff; struct StoredProperty *sp; UWORD wide,high,deep; ULONG modeid = 0L; if(!(iff=ilbm->ParseInfo.iff)) return(0L); wide = ilbm->Bmhd.pageWidth; high = ilbm->Bmhd.pageHeight; deep = ilbm->Bmhd.nPlanes; D(bug("Getting CAMG for w=%ld h=%ld d=%ld ILBM\n",wide,high,deep)); /* * Grab CAMG's idea of the viewmodes. */ if (sp = FindProp (iff, ID_ILBM, ID_CAMG)) { modeid = (* (ULONG *) sp->sp_Data); /* knock bad bits out of old-style 16-bit viewmode CAMGs */ if((!(modeid & MONITOR_ID_MASK))|| ((modeid & EXTENDED_MODE)&&(!(modeid & 0xFFFF0000)))) modeid &= (~(EXTENDED_MODE|SPRITES|GENLOCK_AUDIO|GENLOCK_VIDEO|VP_HIDE)); /* check for bogus CAMG like DPaintII brushes * with junk in upper word and extended bit * not set in lower word. */ if((modeid & 0xFFFF0000)&&(!(modeid & 0x00001000))) sp=NULL; } if(!sp) { /* * No CAMG (or bad CAMG) present; use computed modes. */ if (wide >= 640) modeid = HIRES; if (high >= 400) modeid |= LACE; if (deep == 6) { modeid |= ilbm->EHB ? EXTRA_HALFBRITE : HAM; } D(bug("No CAMG found - using mode $%08lx\n",modeid)); } D(bug("getcamg: modeid = $%08lx\n",modeid)); return(modeid); }
modules/ilbmw.c
/*----------------------------------------------------------------------* * ILBMW.C Support routines for writing ILBM files using IFFParse. * (IFF is Interchange Format File.) * * Based on code by Jerry Morrison and Steve Shaw, Electronic Arts. * This software is in the public domain. * * This version for the Commodore-Amiga computer. *----------------------------------------------------------------------*/ #include "iffp/ilbm.h" #include "iffp/packer.h" #include <graphics/gfxbase.h> extern struct Library *GfxBase; /*---------- initbmhd -------------------------------------------------*/ long initbmhd(BitMapHeader *bmhd, struct BitMap *bitmap, WORD masking, WORD compression, WORD transparentColor, WORD width, WORD height, WORD pageWidth, WORD pageHeight, ULONG modeid) { extern struct Library *GfxBase; struct DisplayInfo DI; WORD rowBytes = bitmap->BytesPerRow; D(bug("In InitBMHD\n")); bmhd->w = width; bmhd->h = height; bmhd->x = bmhd->y = 0; /* Default position is (0,0).*/ bmhd->nPlanes = bitmap->Depth; bmhd->masking = masking; bmhd->compression = compression; bmhd->reserved1 = 0; bmhd->transparentColor = transparentColor; bmhd->pageWidth = pageWidth; bmhd->pageHeight = pageHeight; bmhd->xAspect = 0; /* So we can tell when we've got it */ if(GfxBase->lib_Version >=36) { if(GetDisplayInfoData(NULL, (UBYTE *)&DI, sizeof(struct DisplayInfo), DTAG_DISP, modeid)) { bmhd->xAspect = DI.Resolution.x; bmhd->yAspect = DI.Resolution.y; } } /* If running under 1.3 or GetDisplayInfoData failed, use old method * of guessing aspect ratio */ if(! bmhd->xAspect) { bmhd->xAspect = 44; bmhd->yAspect = ((struct GfxBase *)GfxBase)->DisplayFlags & PAL ? 44 : 52; if(modeid & HIRES) bmhd->xAspect = bmhd->xAspect >> 1; if(modeid & LACE) bmhd->yAspect = bmhd->yAspect >> 1; } return( IS_ODD(rowBytes) ? CLIENT_ERROR : IFF_OKAY ); } /*---------- putcmap ---------------------------------------------------*/ /* This function will accept a table of color values in one of the * following forms: * if bitspergun=4, colortable is words, each with nibbles 0RGB * if bitspergun=8, colortable is bytes of RGBRGB etc. (like a CMAP) * if bitspergun=32, colortable is ULONGS of RGBRGB etc. * (only the high eight bits of each gun will be written to CMAP) */ long putcmap(struct IFFHandle *iff, APTR colortable, UWORD ncolors, UWORD bitspergun) { long error, offs; WORD *tabw; UBYTE *tab8; ColorRegister cmapReg; D(bug("In PutCMAP\n")); if((!iff)||(!colortable)) return(CLIENT_ERROR); /* size of CMAP is 3 bytes * ncolors */ if(error = PushChunk(iff, NULL, ID_CMAP, ncolors * sizeofColorRegister)) return(error); D(bug("Pushed ID_CMAP, error = %ld\n",error)); if(bitspergun == 4) { /* Store each 4-bit value n as nn */ tabw = (UWORD *)colortable; for( ; ncolors; --ncolors ) { cmapReg.red = ( *tabw >> 4 ) & 0xf0; cmapReg.red |= (cmapReg.red >> 4); cmapReg.green = ( *tabw ) & 0xf0; cmapReg.green |= (cmapReg.green >> 4); cmapReg.blue = ( *tabw << 4 ) & 0xf0; cmapReg.blue |= (cmapReg.blue >> 4); if((WriteChunkBytes(iff, (BYTE *)&cmapReg, sizeofColorRegister)) != sizeofColorRegister) return(IFFERR_WRITE); ++tabw; } } else if((bitspergun == 8)||(bitspergun == 32)) { tab8 = (UBYTE *)colortable; offs = (bitspergun == 8) ? 1 : 4; for( ; ncolors; --ncolors ) { cmapReg.red = *tab8; tab8 += offs; cmapReg.green = *tab8; tab8 += offs; cmapReg.blue = *tab8; tab8 += offs; if((WriteChunkBytes(iff, (BYTE *)&cmapReg, sizeofColorRegister)) != sizeofColorRegister) return(IFFERR_WRITE); } } else (error = CLIENT_ERROR) D(bug("Wrote registers, error = %ld\n",error)); error = PopChunk(iff); return(error); } /*---------- putbody ---------------------------------------------------*/ /* NOTE: This implementation could be a LOT faster if it used more of the * supplied buffer. It would make far fewer calls to IFFWriteBytes (and * therefore to DOS Write). */ long putbody(struct IFFHandle *iff, struct BitMap *bitmap, BYTE *mask, BitMapHeader *bmhd, BYTE *buffer, LONG bufsize) { long error; LONG rowBytes = bitmap->BytesPerRow; int dstDepth = bmhd->nPlanes; UBYTE compression = bmhd->compression; int planeCnt; /* number of bit planes including mask */ register int iPlane, iRow; register LONG packedRowBytes; BYTE *buf; BYTE *planes[MAXSAVEDEPTH + 1]; /* array of ptrs to planes & mask */ D(bug("In PutBODY\n")); if ( bufsize < MaxPackedSize(rowBytes) || /* Must buffer a comprsd row*/ compression > cmpByteRun1 || /* bad arg */ bitmap->Rows != bmhd->h || /* inconsistent */ rowBytes != RowBytes(bmhd->w) || /* inconsistent*/ bitmap->Depth < dstDepth || /* inconsistent */ dstDepth > MAXSAVEDEPTH ) /* too many for this routine*/ return(CLIENT_ERROR); planeCnt = dstDepth + (mask == NULL ? 0 : 1); /* Copy the ptrs to bit & mask planes into local array "planes" */ for (iPlane = 0; iPlane < dstDepth; iPlane++) planes[iPlane] = (BYTE *)bitmap->Planes[iPlane]; if (mask != NULL) planes[dstDepth] = mask; /* Write out a BODY chunk header */ if(error = PushChunk(iff, NULL, ID_BODY, IFFSIZE_UNKNOWN)) return(error); /* Write out the BODY contents */ for (iRow = bmhd->h; iRow > 0; iRow--) { for (iPlane = 0; iPlane < planeCnt; iPlane++) { /* Write next row.*/ if (compression == cmpNone) { if(WriteChunkBytes(iff,planes[iPlane],rowBytes) != rowBytes) error = IFFERR_WRITE; planes[iPlane] += rowBytes; } /* Compress and write next row.*/ else { buf = buffer; packedRowBytes = packrow(&planes[iPlane], &buf, rowBytes); if(WriteChunkBytes(iff,buffer,packedRowBytes) != packedRowBytes) error = IFFERR_WRITE; } if(error) return(error); } } /* Finish the chunk */ error = PopChunk(iff); return(error); }
modules/loadilbm.c
/* loadilbm.c 05/91 C. Scheppner CBM * * High-level ILBM load routines */ #include "iffp/ilbm.h" #include "iffp/ilbmapp.h" extern struct Library *GfxBase; /* loadbrush * * Passed an initialized ILBMInfo with a not-in-use ParseInfo.iff * IFFHandle and desired propchks, collectchks, and stopchks, and filename, * will load an ILBM as a brush, setting up ilbm->Bmhd, ilbm->camg, * ilbm->brbitmap, ilbm->colortable, and ilbm->ncolors * * Note that ncolors may be more colors than you can LoadRGB4. * Use MIN(ilbm->ncolors,MAXAMCOLORREG) for color count if you change * the colors yourself using 1.3/2.0 functions. * * Returns 0 for success or an IFFERR (libraries/iffparse.h) */ LONG loadbrush(struct ILBMInfo *ilbm, UBYTE *filename) { LONG error = 0L; if(!(ilbm->ParseInfo.iff)) return(CLIENT_ERROR); if(!(error = openifile((struct ParseInfo *)ilbm, filename, IFFF_READ))) { error = parseifile((struct ParseInfo *)ilbm, ID_FORM, ID_ILBM, ilbm->ParseInfo.propchks, ilbm->ParseInfo.collectchks, ilbm->ParseInfo.stopchks); if((!error)||(error == IFFERR_EOC)||(error == IFFERR_EOF)) { if(contextis(ilbm->ParseInfo.iff,ID_ILBM,ID_FORM)) { if(error = createbrush(ilbm)) deletebrush(ilbm); } else { closeifile((struct ParseInfo *)ilbm); message("Not an ILBM\n"); error = NOFILE; } } } return(error); } /* unloadbrush * * frees and close everything alloc'd/opened by loadbrush */ void unloadbrush(struct ILBMInfo *ilbm) { closeifile((struct ParseInfo *)ilbm); deletebrush(ilbm); } /* queryilbm * * Passed an initilized ILBMInfo with a not-in-use IFFHandle, * and a filename, * will open an ILBM, fill in ilbm->camg and ilbm->bmhd, * and close the ILBM. * * This allows you to determine if the ILBM is a size and * type you want to deal with. * * Returns 0 for success or an IFFERR (libraries/iffparse.h) */ /* query just wants these chunks */ LONG queryprops[] = { ID_ILBM, ID_BMHD, ID_ILBM, ID_CAMG, TAG_DONE }; /* scan can stop when a CMAP or BODY is reached */ LONG querystops[] = { ID_ILBM, ID_CMAP, ID_ILBM, ID_BODY, TAG_DONE }; LONG queryilbm(struct ILBMInfo *ilbm, UBYTE *filename) { LONG error = 0L; BitMapHeader *bmhd; if(!(ilbm->ParseInfo.iff)) return(CLIENT_ERROR); if(!(error = openifile((struct ParseInfo *)ilbm, filename, IFFF_READ))) { D(bug("queryilbm: openifile successful\n")); error = parseifile((struct ParseInfo *)ilbm, ID_FORM, ID_ILBM, queryprops, NULL, querystops); D(bug("queryilbm: after parseifile, error = %ld\n",error)); if((!error)||(error == IFFERR_EOC)||(error == IFFERR_EOF)) { if(contextis(ilbm->ParseInfo.iff,ID_ILBM,ID_FORM)) { if(bmhd = (BitMapHeader*) findpropdata(ilbm->ParseInfo.iff,ID_ILBM,ID_BMHD)) { *(&ilbm->Bmhd) = *bmhd; ilbm->camg = getcamg(ilbm); } else error = NOFILE; } else { message("Not an ILBM\n"); error = NOFILE; } } closeifile(ilbm); } return(error); } /* loadilbm * * Passed a not-in-use IFFHandle, an initialized ILBMInfo, and filename, * will load an ILBM into your already opened ilbm->scr, setting up * ilbm->Bmhd, ilbm->camg, ilbm->colortable, and ilbm->ncolors * and loading the colors into the screen's viewport * * Note that ncolors may be more colors than you can LoadRGB4. * Use MIN(ilbm->ncolors,MAXAMCOLORREG) for color count if you change * the colors yourself using 1.3/2.0 functions. * * Returns 0 for success or an IFFERR (libraries/iffparse.h) * * NOTE - loadilbm() keeps the IFFHandle open so you can copy * or examine other chunks. You must call closeifile(iff,ilbm) * to close the file and deallocate the parsed context * */ LONG loadilbm(struct ILBMInfo *ilbm, UBYTE *filename) { LONG error = 0L; D(bug("loadilbm:\n")); if(!(ilbm->ParseInfo.iff)) return(CLIENT_ERROR); if(!ilbm->scr) return(CLIENT_ERROR); if(!(error = openifile((struct ParseInfo *)ilbm, filename, IFFF_READ))) { D(bug("loadilbm: openifile successful\n")); error = parseifile((struct ParseInfo *)ilbm, ID_FORM, ID_ILBM, ilbm->ParseInfo.propchks, ilbm->ParseInfo.collectchks, ilbm->ParseInfo.stopchks); D(bug("loadilbm: after parseifile, error = %ld\n",error)); if((!error)||(error == IFFERR_EOC)||(error == IFFERR_EOF)) { if(contextis(ilbm->ParseInfo.iff,ID_ILBM,ID_FORM)) { error = loadbody(ilbm->ParseInfo.iff, &ilbm->scr->BitMap, &ilbm->Bmhd); D(bug("loadilbm: after loadbody, error = %ld\n",error)); if(!error) { if(!(getcolors(ilbm))) LoadRGB4(&ilbm->scr->ViewPort,ilbm->colortable, MIN(ilbm->ncolors,MAXAMCOLORREG)); } } else { closeifile((struct ParseInfo *)ilbm); message("Not an ILBM\n"); error = NOFILE; } } } return(error); } /* unloadilbm * * frees and closes everything allocated by loadilbm */ void unloadilbm(struct ILBMInfo *ilbm) { closeifile((struct ParseInfo *)ilbm); freecolors(ilbm); }
modules/packer.c
/*----------------------------------------------------------------------* * packer.c Convert data to "cmpByteRun1" run compression. 11/15/85 * * By Jerry Morrison and Steve Shaw, Electronic Arts. * This software is in the public domain. * * control bytes: * [0..127] : followed by n+1 bytes of data. * [-1..-127] : followed by byte to be repeated (-n)+1 times. * -128 : NOOP. * * This version for the Commodore-Amiga computer. *----------------------------------------------------------------------*/ #include "iffp/packer.h" #define DUMP 0 #define RUN 1 #define MinRun 3 #define MaxRun 128 #define MaxDat 128 /* When used on global definitions, static means private. * This keeps these names, which are only referenced in this * module, from conficting with same-named objects in your program. */ static LONG putSize; static char buf[256]; /* [TBD] should be 128? on stack?*/ #define GetByte() (*source++) #define PutByte(c) { *dest++ = (c); ++putSize; } static BYTE *PutDump(dest, nn) BYTE *dest; int nn; { int i; PutByte(nn-1); for(i = 0; i < nn; i++) PutByte(buf[i]); return(dest); } static BYTE *PutRun(dest, nn, cc) BYTE *dest; int nn, cc; { PutByte(-(nn-1)); PutByte(cc); return(dest); } #define OutDump(nn) dest = PutDump(dest, nn) #define OutRun(nn,cc) dest = PutRun(dest, nn, cc) /*----------- packrow --------------------------------------------------*/ /* Given POINTERS TO POINTERS, packs one row, updating the source and * destination pointers. RETURNs count of packed bytes. */ LONG packrow(BYTE **pSource, BYTE **pDest, LONG rowSize) { BYTE *source, *dest; char c,lastc = '\0'; BOOL mode = DUMP; short nbuf = 0; /* number of chars in buffer */ short rstart = 0; /* buffer index current run starts */ source = *pSource; dest = *pDest; putSize = 0; buf[0] = lastc = c = GetByte(); /* so have valid lastc */ nbuf = 1; rowSize--; /* since one byte eaten.*/ for (; rowSize; --rowSize) { buf[nbuf++] = c = GetByte(); switch (mode) { case DUMP: /* If the buffer is full, write the length byte, then the data */ if (nbuf>MaxDat) { OutDump(nbuf-1); buf[0] = c; nbuf = 1; rstart = 0; break; } if (c == lastc) { if (nbuf-rstart >= MinRun) { if (rstart > 0) OutDump(rstart); mode = RUN; } else if (rstart == 0) mode = RUN; /* no dump in progress, so can't lose by making these 2 a run.*/ } else rstart = nbuf-1; /* first of run */ break; case RUN: if ( (c != lastc)|| ( nbuf-rstart > MaxRun)) { /* output run */ OutRun(nbuf-1-rstart,lastc); buf[0] = c; nbuf = 1; rstart = 0; mode = DUMP; } break; } lastc = c; } switch (mode) { case DUMP: OutDump(nbuf); break; case RUN: OutRun(nbuf-rstart,lastc); break; } *pSource = source; *pDest = dest; return(putSize); }
modules/parse.c
/* * parse.c - iffparse file IO support module * based on some of looki.c by Leo Schwab * * The filename for clipboard is -c or -cUnit as in -c0 -c1 etc. (default 0) */ #include <exec/types.h> #include "iffp/iff.h" /* local function prototypes */ LONG stdio_stream(struct Hook *, struct IFFHandle *, struct IFFStreamCmd *); UBYTE *omodes[2] = {"r","w"}; /* openifile * * Passed a ParseInfo structure with a not-in-use IFFHandle, filename * ("-c" or -cUnit like "-c1" for clipboard), and IFF open mode * (IFFF_READ or IFFF_WRITE) opens file or clipboard for use with * iffparse.library support modules. * * Returns 0 for success or an IFFERR (libraries/iffparse.h) */ LONG openifile(struct ParseInfo *pi, UBYTE *filename, ULONG iffopenmode) { struct IFFHandle *iff; BOOL cboard; ULONG unit = PRIMARY_CLIP; LONG error; if(!pi) return(CLIENT_ERROR); if(!(iff=pi->iff)) return(CLIENT_ERROR); cboard = (*filename == '-' && filename[1] == 'c'); if(cboard && filename[2]) unit = atoi(&filename[2]); if (cboard) { /* * Set up IFFHandle for Clipboard I/O. */ pi->clipboard = TRUE; if (!(iff->iff_Stream = (ULONG)OpenClipboard(unit))) { message("Clipboard open of unit %ld failed.\n",unit); return(NOFILE); } InitIFFasClip(iff); } else { pi->clipboard = FALSE; /* * Set up IFFHandle for buffered stdio I/O. */ if (!(iff->iff_Stream = (ULONG) fopen(filename, omodes[iffopenmode & 1]))) { message("%s: File open failed.\n",filename); return(NOFILE); } else initiffasstdio(iff); } D(bug("%s file opened: \n", cboard ? "[Clipboard]" : filename)); pi->filename = filename; error=OpenIFF(iff, iffopenmode); pi->opened = error ? FALSE : TRUE; /* currently open handle */ D(bug("OpenIFF error = %ld\n",error)); return(error); } /* closeifile * * closes file or clipboard opened with openifile, and frees all * iffparse context parsed by parseifile. * * Note - You should closeifile as soon as possible if using clipboard * ("-c[n]"). You also need to closeifile if, for example, you wish to * reopen the file to write changes back out. See the copychunks.c * module for routines which allow you clone the chunks iffparse has * gathered so that you can closeifile and still be able to modify and * write back out gathered chunks. * */ void closeifile(struct ParseInfo *pi) { struct IFFHandle *iff; D(bug("closeifile:\n")); if(!pi) return; if(!(iff=pi->iff)) return; DD(bug("closeifile: About to CloseIFF if open, iff=$%lx, opened=%ld\n", iff, pi->opened)); if(pi->opened) CloseIFF(iff); DD(bug("closeifile: About to close %s, stream=$%lx\n", pi->clipboard ? "clipboard" : "file", iff->iff_Stream)); if(iff->iff_Stream) { if (pi->clipboard) CloseClipboard((struct ClipHandle *)(iff->iff_Stream)); else fclose ((FILE *)(iff->iff_Stream)); } iff->iff_Stream = NULL; pi->clipboard = NULL; pi->opened = NULL; } /* parseifile * * Passed a ParseInfo with an initialized and open IFFHandle, * grouptype (like ID_FORM), groupid (like ID_ILBM), * and TAG_DONE terminated longword arrays of type,id * for chunks to be grabbed, gathered, and stopped on * (like { ID_ILBM, ID_BMHD, ID_ILBM, ID_CAMG, TAG_DONE }) * will parse an IFF file, grabbing/gathering and stopping * on specified chunk. * * Note - you can call getcontext() (to continue after a stop chunk) or * nextcontext() (after IFFERR_EOC, to parse next form in the same file) * if you wish to continue parsing the same IFF file. If parseifile() * has to delve into a complex format to find your desired FORM, the * pi->hunt flag will be set. This should be a signal to you that * you may not have the capability to simply modify and rewrite * the data you have gathered. * * Returns 0 for success else and IFFERR (libraries/iffparse.h) */ LONG parseifile(pi,groupid,grouptype,propchks,collectchks,stopchks) struct ParseInfo *pi; LONG groupid, grouptype; LONG *propchks, *collectchks, *stopchks; { struct IFFHandle *iff; register struct ContextNode *cn; LONG error = 0L; if(!(iff=pi->iff)) return(CLIENT_ERROR); if(!iff->iff_Stream) return(IFFERR_READ); pi->hunt = FALSE; /* * Declare property, collection and stop chunks. */ if (propchks) if (error = PropChunks (iff, propchks, chkcnt(propchks))) return (error); if (collectchks) if (error = CollectionChunks(iff, collectchks, chkcnt(collectchks))) return (error); if (stopchks) if (error = StopChunks (iff, stopchks, chkcnt(stopchks))) return (error); /* * We want to stop at the end of an ILBM context. */ if (grouptype) if (error = StopOnExit (iff, grouptype, groupid)) return(error); /* * Take first parse step to enter main chunk. */ if (error = ParseIFF (iff, IFFPARSE_STEP)) return(error); /* * Test the chunk info to see if simple form of type we want (ILBM). */ if (!(cn = CurrentChunk (iff))) { /* * This really should never happen. If it does, it means * our parser is broken. */ message("Parsing error; no top chunk!\n"); return(NOFILE); } if (cn->cn_ID != groupid || cn->cn_Type != grouptype) { D(bug("This is a(n) %.4s.%.4s. Looking for embedded %.4s's...\n", &cn->cn_Type, &cn->cn_ID, &grouptype)); pi->hunt = TRUE; /* Warning - this is a complex file */ } if(!error) error = getcontext(iff); return(error); } /* chkcnt * * simply counts the number of chunk pairs (type,id) in array */ LONG chkcnt(LONG *taggedarray) { LONG k = 0; while(taggedarray[k] != TAG_DONE) k++; return(k>>1); } /* currentchunkis * * returns the ID of the current chunk (like ID_CAMG) */ LONG currentchunkis(struct IFFHandle *iff, LONG type, LONG id) { register struct ContextNode *cn; LONG result = 0; if (cn = CurrentChunk (iff)) { if((cn->cn_Type == type)&&(cn->cn_ID == id)) result = 1; } return(result); } /* contextis * * returns the enclosing context of the current chunk (like ID_ILBM) */ LONG contextis(struct IFFHandle *iff, LONG type, LONG id) { register struct ContextNode *cn; LONG result = 0; if (cn = (CurrentChunk (iff))) { if (cn = (ParentChunk(cn))) { if((cn->cn_Type == type)&&(cn->cn_ID == id)) result = 1; } } D(bug("This is a %.4s %.4s\n",&cn->cn_Type,&cn->cn_ID)); return(result); } /* getcontext() * * Continues to gather the context which was specified to parseifile(), * stopping at specified stop chunk, or end of context, or EOF * * Returns 0 (stopped on a stop chunk) * or IFFERR_EOC (end of context, not an error) * or IFFER_EOF (end of file) */ LONG getcontext(iff) struct IFFHandle *iff; { LONG error = 0L; /* Based on our parse initialization, * ParseIFF() will return on a stop chunk (error = 0) * or end of context for an ILBM FORM (error = IFFERR_EOC) * or end of file (error = IFFERR_EOF) */ return(error = ParseIFF(iff, IFFPARSE_SCAN)); } /* nextcontext * * If you have finished parsing and reading your context (IFFERR_EOC), * nextcontext will enter the next context contained in the file * and parse it. * * Returns 0 or an IFFERR such as IFFERR_EOF (end of file) */ LONG nextcontext(iff) struct IFFHandle *iff; { LONG error = 0L; error = ParseIFF(iff, IFFPARSE_STEP); D(bug("nextcontext: Got through next step\n")); return(error); } /* findpropdata * * finds specified chunk parsed from IFF file, and * returns pointer to its sp_Data (or 0 for not found) */ UBYTE *findpropdata(iff, type, id) struct IFFHandle *iff; LONG type, id; { register struct StoredProperty *sp; if(sp = FindProp (iff, type, id)) return(sp->sp_Data); return(0); } /* * File I/O hook functions which the IFF library will call. * A return of 0 indicates success (no error). * * Iffparse.library calls this code via struct Hook and Hook.asm */ static LONG stdio_stream (hook, iff, actionpkt) struct Hook *hook; struct IFFHandle *iff; struct IFFStreamCmd *actionpkt; { register FILE *stream; register LONG nbytes; register int actual; register UBYTE *buf; long len; stream = (FILE *) iff->iff_Stream; if(!stream) return(1); nbytes = actionpkt->sc_NBytes; buf = (UBYTE *) actionpkt->sc_Buf; switch (actionpkt->sc_Command) { case IFFSCC_READ: do { actual = nbytes > 32767 ? 32767 : nbytes; if ((len=fread (buf, 1, actual, stream)) != actual) break; nbytes -= actual; buf += actual; } while (nbytes > 0); return (nbytes ? IFFERR_READ : 0 ); case IFFSCC_WRITE: do { actual = nbytes > 32767 ? 32767 : nbytes; if ((len=fwrite (buf, 1, actual, stream)) != actual) break; nbytes -= actual; buf += actual; } while (nbytes > 0); return (nbytes ? IFFERR_WRITE : 0); case IFFSCC_SEEK: return ((fseek (stream, nbytes, 1) == -1) ? IFFERR_SEEK : 0); default: /* No _INIT or _CLEANUP required. */ return (0); } } /* initiffasstdio (ie. init iff as stdio) * * sets up hook callback for the file stream handler above */ void initiffasstdio (iff) struct IFFHandle *iff; { extern LONG HookEntry(); static struct Hook stdiohook = { { NULL }, (ULONG (*)()) HookEntry, (ULONG (*)()) stdio_stream, NULL }; /* * Initialize the IFF structure to point to the buffered I/O * routines. Unbuffered I/O is terribly slow. */ InitIFF (iff, IFFF_FSEEK | IFFF_RSEEK, &stdiohook); } /* * IFFerr * * Returns pointer to IFF Error string or NULL (no error) */ UBYTE *IFFerr(error) LONG error; { /* * English error messages for possible IFFERR_#? returns from various * IFF routines. To get the index into this array, take your IFFERR * code, negate it, and subtract one. * idx = -error - 1; */ static UBYTE *errormsgs[] = { "End of file (not an error).", "End of context (not an error).", "No lexical scope.", "Insufficient memory.", "Stream read error.", "Stream write error.", "Stream seek error.", "File is corrupt.", "IFF syntax error.", "Not an IFF file.", "Required hook vector missing.", "Return to client." }; static UBYTE unknown[32]; static UBYTE client[] = "Client error"; static UBYTE nofile[] = "File not found or wrong type"; if (error < 0) { return(errormsgs[(-error) - 1]); } else if(error = CLIENT_ERROR) { return(client); } else if(error = NOFILE) { return(nofile); } else if(error) { sprintf(unknown,"Unknown error %ld",error); return(unknown); } else return(NULL); } /* * PutCk * * Writes one chunk of data to an iffhandle * */ long PutCk(struct IFFHandle *iff, long id, long size, void *data) { long error = 0, wlen; D(bug("PutCk: asked to push chunk \"%.4s\" ($%lx) length %ld\n",&id,id,size)); if(error=PushChunk(iff, 0, id, size)) { D(bug("PutCk: PushChunk of %.4s, error = %s, size = %ld\n", id, IFFerr(error), id)); } else { D(bug("PutCk: PushChunk of %.4s, error = %ld\n",&id, error)); /* Write the actual data */ if((wlen = WriteChunkBytes(iff,data,size)) != size) { D(bug("WriteChunkBytes error: size = %ld, wrote %ld\n",size,wlen)); error = IFFERR_WRITE; } else error = PopChunk(iff); D(bug("PutCk: After PopChunk - error = %ld\n",error)); } return(error); }
modules/saveilbm.c
/* saveilbm.c 05/91 C. Scheppner CBM * * High-level ILBM save routines */ #include "iffp/ilbm.h" #include "iffp/ilbmapp.h" extern struct Library *GfxBase; /* screensave.c * * Given an ILBMInfo with a currently available (not in use) * ParseInfo->iff IFFHandle, a screen pointer, filename, and * optional chunklist, will save screen as an ILBM * The struct Chunk *chunklist1 and 2 are for chunks you wish written * out other than BMHD, CMAP, and CAMG (they will be screened out * because they are computed and written separately). * * Note - screensave passes NULL for transparent color and mask * * Returns 0 for success or an IFFERR (libraries/iffparse.h) */ LONG screensave(struct ILBMInfo *ilbm, struct Screen *scr, struct Chunk *chunklist1, struct Chunk *chunklist2, UBYTE *filename) { extern struct Library *GfxBase; UWORD *colortable, count; ULONG modeid; LONG error; int k; if(GfxBase->lib_Version >= 36) modeid=GetVPModeID(&scr->ViewPort); else modeid = scr->ViewPort.Modes & OLDCAMGMASK; count = scr->ViewPort.ColorMap->Count; if(colortable = (UWORD *)AllocMem(count << 1, MEMF_CLEAR)) { for(k=0; k<count; k++) colortable[k]=GetRGB4(scr->ViewPort.ColorMap,k); error = saveilbm(ilbm, &scr->BitMap, modeid, scr->Width, scr->Height, scr->Width, scr->Height, colortable, count, 4, mskNone, 0, chunklist1, chunklist2, filename); FreeMem(colortable,count << 1); } else error = IFFERR_NOMEM; return(error); } /* saveilbm * * Given an ILBMInfo with a currently available (not-in-use) * ParseInfo->iff IFFHandle, a BitMap ptr, * modeid, widths/heights, colortable, ncolors, bitspergun, * masking, transparent color, optional chunklists, and filename, * will save the bitmap as an ILBM. * * if bitspergun=4, colortable is words, each with nibbles 0RGB * if bitspergun=8, colortable is byte guns of RGBRGB etc. (like a CMAP) * if bitspergun=32, colortable is ULONG guns of RGBRGB etc. * Only the high eight bits of each gun will be written to CMAP. * Four bit guns n will be saved as nn * * The struct Chunk *chunklist is for chunks you wish written * other than BMHD, CMAP, and CAMG (they will be screened out) * because they are calculated and written separately * * Returns 0 for success, or an IFFERR */ LONG saveilbm(struct ILBMInfo *ilbm, struct BitMap *bitmap, ULONG modeid, WORD width, WORD height, WORD pagewidth, WORD pageheight, APTR colortable, UWORD ncolors, UWORD bitspergun, WORD masking, WORD transparentColor, struct Chunk *chunklist1, struct Chunk *chunklist2, UBYTE *filename) { struct IFFHandle *iff; struct Chunk *chunk; ULONG chunkID; UBYTE *bodybuf; LONG size, error = 0L; #define BODYBUFSZ 4096 iff = ilbm->ParseInfo.iff; if(!(modeid & 0xFFFF0000)) modeid &= OLDCAMGMASK; if(!(bodybuf = AllocMem(BODYBUFSZ,MEMF_PUBLIC))) { message("Not enough memory\n"); return(IFFERR_NOMEM); } if(!(error = openifile(ilbm, filename, IFFF_WRITE))) { D(bug("Opened %s for write\n",filename)); error = PushChunk(iff, ID_ILBM, ID_FORM, IFFSIZE_UNKNOWN); D(bug("After PushChunk FORM ILBM - error = %ld\n", error)); initbmhd(&ilbm->Bmhd, bitmap, masking, cmpByteRun1, transparentColor, width, height, pagewidth, pageheight, modeid); D(bug("Error before putbmhd = %ld\n",error)); CkErr(putbmhd(iff,&ilbm->Bmhd)); if(colortable) CkErr(putcmap(iff,colortable,ncolors,bitspergun)); ilbm->camg = modeid; D(bug("before putcamg - error = %ld\n",error)); CkErr(putcamg(iff,&modeid)); D(bug("Past putBMHD, CMAP, CAMG - error = %ld\n",error)); /* Write out chunklists 1 & 2 (if any), except for * any BMHD, CMAP, or CAMG (computed/written separately) */ for(chunk = chunklist1; chunk; chunk = chunk->ch_Next) { D(bug("chunklist1 - have a %.4s\n",&chunk->ch_ID)); chunkID = chunk->ch_ID; if((chunkID != ID_BMHD)&&(chunkID != ID_CMAP)&&(chunkID != ID_CAMG)) { size = chunk->ch_Size==IFFSIZE_UNKNOWN ? strlen(chunk->ch_Data) : chunk->ch_Size; D(bug("Putting %.4s\n",&chunk->ch_ID)); CkErr(PutCk(iff, chunkID, size, chunk->ch_Data)); } } for(chunk = chunklist2; chunk; chunk = chunk->ch_Next) { chunkID = chunk->ch_ID; D(bug("chunklist2 - have a %.4s\n",&chunk->ch_ID)); if((chunkID != ID_BMHD)&&(chunkID != ID_CMAP)&&(chunkID != ID_CAMG)) { size = chunk->ch_Size==IFFSIZE_UNKNOWN ? strlen(chunk->ch_Data) : chunk->ch_Size; D(bug("Putting %.4s\n",&chunk->ch_ID)); CkErr(PutCk(iff, chunkID, size, chunk->ch_Data)); } } /* Write out the BODY */ CkErr(putbody(iff, bitmap, NULL, &ilbm->Bmhd, bodybuf, BODYBUFSZ)); D(bug("Past putbody - error = %ld\n",error)); CkErr(PopChunk(iff)); /* close out the FORM */ closeifile(ilbm); /* and the file */ } FreeMem(bodybuf,BODYBUFSZ); return(error); }
modules/screen.c
/* screen.c - 2.0 screen module for Display * based on scdemo, oscandemo, looki */ /* Copyright (c) 1989, 1990 Commodore-Amiga, Inc. Executables based on this information may be used in software for Commodore Amiga computers. All other rights reserved. This information is provided "as is"; no warranties are made. All use is at your own risk, and no liability or responsibility is assumed. */ #include "iffp/ilbmapp.h" BOOL VideoControlTags(struct ColorMap *,ULONG tags, ...); extern struct Library *GfxBase; extern struct Library *IntuitionBase; struct TextAttr SafeFont = { (UBYTE *) "topaz.font", 8, 0, 0, }; UWORD penarray[] = {~0}; /* default new window if none supplied in ilbm->nw */ struct NewWindow defnw = { 0, 0, /* LeftEdge and TopEdge */ 0, 0, /* Width and Height */ -1, -1, /* DetailPen and BlockPen */ VANILLAKEY|MOUSEBUTTONS, /* IDCMP Flags with Flags below */ BACKDROP|BORDERLESS|SMART_REFRESH|NOCAREREFRESH|ACTIVATE|RMBTRAP, NULL, NULL, /* Gadget and Image pointers */ NULL, /* Title string */ NULL, /* Screen ptr null till opened */ NULL, /* BitMap pointer */ 50, 20, /* MinWidth and MinHeight */ 0 , 0, /* MaxWidth and MaxHeight */ CUSTOMSCREEN /* Type of window */ }; /* opendisplay - passed ILBMInfo, dimensions, modeID * * Attempts to open correct 2.0 modeID screen and window, * else an old 1.3 mode screen and window. * * Returns *window or NULL. */ struct Window *opendisplay(struct ILBMInfo *ilbm, SHORT wide, SHORT high, SHORT deep, ULONG mode) { struct NewWindow newwin, *nw; closedisplay(ilbm); if(ilbm->scr = openidscreen(ilbm, wide, high, deep, mode)) { nw = &newwin; if(ilbm->windef) *nw = *(ilbm->windef); else *nw = *(&defnw); nw->Screen = ilbm->scr; D(bug("sizes: scr= %ld x %ld passed= %ld x %ld\n", ilbm->scr->Width,ilbm->scr->Height,wide,high)); nw->Width = wide; nw->Height = high; if (!(ilbm->win = OpenWindow(nw))) { closedisplay(ilbm); D(bug("Failed to open window.")); } else { if(ilbm->win->Flags & BACKDROP) { ShowTitle(ilbm->scr, FALSE); ilbm->TBState = FALSE; } } } if(ilbm->scr) /* nulled out by closedisplay if OpenWindow failed */ { ilbm->vp = &ilbm->scr->ViewPort; ilbm->srp = &ilbm->scr->RastPort; ilbm->wrp = ilbm->win->RPort; } return(ilbm->win); } void closedisplay(struct ILBMInfo *ilbm) { if(ilbm) { if (ilbm->win) CloseWindow(ilbm->win), ilbm->win = NULL; if (ilbm->scr) CloseScreen(ilbm->scr), ilbm->scr = NULL; ilbm->vp = NULL; ilbm->srp = ilbm->wrp = NULL; } } /* openidscreen - ILBMInfo, dimensions, modeID * * Attempts to open correct 2.0 modeID screen with centered * overscan based on user's prefs, * else old 1.3 mode screen. * * If ilbm->stype includes CUSTOMBITMAP, ilbm->brbitmap will be * used as the screen's bitmap. * If ilbm->stags is non-NULL, these tags will be added to the * end of the taglist. * * Returns *screen or NULL. */ struct Screen *openidscreen(struct ILBMInfo *ilbm, SHORT wide, SHORT high, SHORT deep, ULONG mode) { struct NewScreen ns; /* for old style OpenScreen */ struct Rectangle spos, dclip, txto, stdo, maxo, uclip; /* display rectangles */ struct Rectangle *uclipp; struct Screen *scr = NULL; LONG error, trynew; ULONG bitmaptag, passedtags; BOOL vctl; if (trynew = ((((struct Library *)GfxBase)->lib_Version >= 36)&& (((struct Library *)IntuitionBase)->lib_Version >= 36))) { /* if >= v36, see if mode is available */ if(error = ModeNotAvailable(mode)) { D(bug("Mode $%08lx not available, error=%ld:\n",mode,error)); /* if not available, try fall back mode */ mode = modefallback(mode,wide,high,deep); error = ModeNotAvailable(mode); D(bug("$%08lx ModeNotAvailable=%ld:\n",mode,error)); } if(error) trynew = FALSE; else trynew=((QueryOverscan(mode,&txto,OSCAN_TEXT))&& (QueryOverscan(mode,&stdo,OSCAN_STANDARD))&& (QueryOverscan(mode,&maxo,OSCAN_MAX))); } D(bug("\nILBM: w=%ld, h=%ld, d=%ld, mode=0x%08lx\n", wide,high,deep,mode)); D(bug("OPEN: %s.\n", trynew ? "Is >= 2.0 and mode available, trying OpenScreenTags" : "Not 2.0, doing old OpenScreen")); if(trynew) { /* If user clip type specified and available, use it */ if(ilbm->Video) ilbm->ucliptype = OSCAN_VIDEO; if((ilbm->ucliptype)&&(QueryOverscan(mode,&uclip,ilbm->ucliptype))) uclipp = &uclip; else uclipp = NULL; clipit(wide,high,&spos,&dclip,&txto,&stdo,&maxo,uclipp); D(bug("Using dclip %ld,%ld to %ld,%ld... width=%ld height=%ld\n", dclip.MinX,dclip.MinY,dclip.MaxX,dclip.MaxY, dclip.MaxX-dclip.MinX+1,dclip.MaxY-dclip.MinY+1)); D(bug("spos->minx = %ld, spos->miny = %ld\n",spos.MinX,spos.MinY)); D(bug("DEBUG: About to attempt OpenScreenTags\n")); bitmaptag = ((ilbm->brbitmap)&&(ilbm->stype & CUSTOMBITMAP)) ? SA_BitMap : TAG_IGNORE; passedtags = ilbm->stags ? TAG_MORE : TAG_IGNORE; scr=(struct Screen *)OpenScreenTags((struct NewScreen *)NULL, SA_DisplayID, mode, SA_Type, ilbm->stype, SA_Behind, TRUE, SA_Top, spos.MinY, SA_Left, spos.MinX, SA_Width, wide, SA_Height, high, SA_Depth, deep, SA_DClip, &dclip, SA_AutoScroll, ilbm->Autoscroll ? TRUE : FALSE, SA_Title, ilbm->stitle, SA_Font, &SafeFont, SA_Pens, penarray, SA_ErrorCode, &error, bitmaptag, ilbm->brbitmap, passedtags, ilbm->stags, TAG_DONE ); D(bug("DEBUG: OpenScreenTags scr at 0x%lx\n",scr)); if(scr) { if(ilbm->Notransb) { vctl=VideoControlTags(scr->ViewPort.ColorMap, VTAG_BORDERNOTRANS_SET, TRUE, TAG_DONE); D(bug("VideoControl to set bordernotrans, error = %ld\n",vctl)); MakeScreen(scr); RethinkDisplay(); } } else modeErrorMsg(mode,error); } if(!scr) { /* ns initialization for 1.3 old style OpenScreen only */ ns.LeftEdge = ns.TopEdge = 0; ns.Width = wide; ns.Height = high; ns.Depth = deep; ns.ViewModes = modefallback(mode,wide,high,deep); ns.DetailPen = 0; ns.BlockPen = 1; ns.Gadgets = NULL; ns.CustomBitMap = ((ilbm->brbitmap)&&(ilbm->stype & CUSTOMBITMAP)) ? ilbm->brbitmap : NULL; ns.Font = &SafeFont; ns.DefaultTitle = ilbm->stitle; ns.Type = ilbm->stype & 0x01FF; /* allow only 1.3 types */ scr=(struct Screen *)OpenScreen(&ns); D(bug("DEBUG: ns.ViewModes=0x%lx, vp->Modes=0x%lx\n", ns.ViewModes,scr->ViewPort.Modes)); D(bug("DEBUG: non-extended scr at 0x%lx (0=failure)\n",scr)); } return(scr); } /* * modefallback - passed a mode id, attempts to provide a * suitable old mode to use instead */ /* for old 1.3 screens */ #define MODE_ID_MASK (LACE|HIRES|HAM|EXTRA_HALFBRITE) ULONG modefallback(ULONG mode, SHORT wide, SHORT high, SHORT deep) { ULONG newmode; /* For now, simply masks out everything but old mode bits. * This is just a cheap way to get some kind of display open * and may be totally invalid for future modes. * Should search the display database for a suitable mode * based on the specific needs of your application. */ newmode = mode & MODE_ID_MASK; D(bug("Try 0x%08lx instead of 0x%08lx\n",newmode,mode)); return(newmode); } /* * clipit - passed width and height of a display, and the text, std, and * max overscan rectangles for the mode, clipit fills in the * spos (screen pos) and dclip rectangles to use in centering. * Centered around smallest containing user-editable oscan pref, * with dclip confined to legal maxoscan limits. * Screens which center such that their top is below text * oscan top, will be moved up. * If a non-null uclip is passed, that clip is used instead. */ void clipit(SHORT wide, SHORT high, struct Rectangle *spos, struct Rectangle *dclip, struct Rectangle *txto, struct Rectangle *stdo, struct Rectangle *maxo, struct Rectangle *uclip) { struct Rectangle *besto; SHORT minx, maxx, miny, maxy; SHORT txtw, txth, stdw, stdh, maxw, maxh, bestw, besth; /* get the txt, std and max widths and heights */ txtw = txto->MaxX - txto->MinX + 1; txth = txto->MaxY - txto->MinY + 1; stdw = stdo->MaxX - stdo->MinX + 1; stdh = stdo->MaxY - stdo->MinY + 1; maxw = maxo->MaxX - maxo->MinX + 1; maxh = maxo->MaxY - maxo->MinY + 1; if((wide <= txtw)&&(high <= txth)) { besto = txto; bestw = txtw; besth = txth; D(bug("Best clip is txto\n")); } else { besto = stdo; bestw = stdw; besth = stdh; D(bug("Best clip is stdo\n")); } D(bug("TXTO: mnx=%ld mny=%ld mxx=%ld mxy=%ld stdw=%ld stdh=%ld\n", txto->MinX,txto->MinY,txto->MaxX,txto->MaxY,txtw,txth)); D(bug("STDO: mnx=%ld mny=%ld mxx=%ld mxy=%ld stdw=%ld stdh=%ld\n", stdo->MinX,stdo->MinY,stdo->MaxX,stdo->MaxY,stdw,stdh)); D(bug("MAXO: mnx=%ld mny=%ld mxx=%ld mxy=%ld maxw=%ld maxh=%ld\n", maxo->MinX,maxo->MinY,maxo->MaxX,maxo->MaxY,maxw,maxh)); if(uclip) { *dclip = *uclip; spos->MinX = uclip->MinX; spos->MinY = uclip->MinY; D(bug("UCLIP: mnx=%ld mny=%ld maxx=%ld maxy=%ld\n", dclip->MinX,dclip->MinY,dclip->MaxX,dclip->MaxY)); } else { /* CENTER the screen based on best oscan prefs * but confine dclip within max oscan limits * * FIX MinX first */ spos->MinX = minx = besto->MinX - ((wide - bestw) >> 1); maxx = wide + minx - 1; if(maxx > maxo->MaxX) maxx = maxo->MaxX; /* too right */ if(minx < maxo->MinX) minx = maxo->MinX; /* too left */ D(bug("DCLIP: minx adjust from %ld to %ld\n",spos->MinX,minx)); /* FIX MinY */ spos->MinY = miny = besto->MinY - ((high - besth) >> 1); /* if lower than top of txto, move up */ spos->MinY = miny = MIN(spos->MinY,txto->MinY); maxy = high + miny - 1; if(maxy > maxo->MaxY) maxy = maxo->MaxY; /* too down */ if(miny < maxo->MinY) miny = maxo->MinY; /* too up */ D(bug("DCLIP: miny adjust from %ld to %ld\n",spos->MinY,miny)); /* SET up dclip */ dclip->MinX = minx; dclip->MinY = miny; dclip->MaxX = maxx; dclip->MaxY = maxy; D(bug("CENTER: mnx=%ld mny=%ld maxx=%ld maxy=%ld\n", dclip->MinX,dclip->MinY,dclip->MaxX,dclip->MaxY)); } } void modeErrorMsg(ULONG mode, ULONG errorcode) { UBYTE *s=NULL; D(bug("DEBUG: Can't open mode ID 0x%08lx screen: ",mode)); switch ( errorcode ) { case OSERR_NOMEM: s="Not enough memory."; break; case OSERR_NOCHIPMEM: s="Not enough chip memory."; break; #ifdef DEBUG case OSERR_NOMONITOR: s="monitor not available."; break; case OSERR_NOCHIPS: s="new chipset not available."; break; case OSERR_PUBNOTUNIQUE: s="public screen already open."; break; case OSERR_UNKNOWNMODE: s="mode ID is unknown."; break; default: message("unknown mode error %ld\n",errorcode); #endif } if(s) message("%s\n",s); } /*----------------------------------------------------------------------*/ BOOL VideoControlTags(struct ColorMap *cm, ULONG tags, ...) { return (VideoControl(cm, (struct TagItem *)&tags)); } /*----------------------------------------------------------------------*/
modules/screendump.c
/* * screendump.c - routine to dump rastport (iffparse not required) * */ #include <exec/types.h> #include <intuition/screens.h> #include <devices/printer.h> #ifndef NO_PROTOS #include <clib/exec_protos.h> #include <clib/alib_protos.h> #endif /* screendump * * Passed a screen pointer, source x, source y, width, height, * destcols and io_Special flags, will print part or all of a screen. * * If 0 is passed for BOTH destcols and special, screendump() * assumes you want IT to compute suitable values. * In this case: * 1. If srcx and srcy are 0, and srcw and srch are same as * screen width and height, screendump will set destcols=0, * and special = SPECIAL_FULLCOLS|SPECIAL_ASPECT * for a full width aspected dump. * * 2. If srcx or srcy are nonzero, or srcw or srch are different * from screen width or height, screendump will print a * fractional size dump relative to the size whole screendump * would have been. * * Returns 0 for success or printer io_Error (devices/printer.h) */ int screendump(struct Screen *scr, UWORD srcx, UWORD srcy, UWORD srcw, UWORD srch, LONG destcols, UWORD iospecial) { struct IODRPReq *iodrp; struct MsgPort *printerPort; struct ViewPort *vp; ULONG tmpl; int error = PDERR_BADDIMENSION; if(!scr) return(error); if((!destcols)&&(!iospecial)) { /* Then we compute what they should be */ if((!srcx)&&(!srcy)&&(srcw==scr->Width)&&(srch==scr->Height)) { iospecial = SPECIAL_FULLCOLS|SPECIAL_ASPECT; } else { iospecial = SPECIAL_FRACCOLS|SPECIAL_ASPECT; tmpl = srcw; tmpl = tmpl << 16; destcols = (tmpl / scr->Width) << 16; } } if(printerPort = CreatePort(0,0)) { if(iodrp= (struct IODRPReq *)CreateExtIO(printerPort,sizeof(struct IODRPReq))) { if(!(error=OpenDevice("printer.device",0,iodrp,0))) { vp = &scr->ViewPort; iodrp->io_Command = PRD_DUMPRPORT; iodrp->io_RastPort = &scr->RastPort; iodrp->io_ColorMap = vp->ColorMap; iodrp->io_Modes = (ULONG)vp->Modes; iodrp->io_SrcX = srcx; iodrp->io_SrcY = srcy; iodrp->io_SrcWidth = srcw; iodrp->io_SrcHeight = srch; iodrp->io_DestCols = destcols; /* iodrp->io_DestRows = 0; cleared by allocation */ iodrp->io_Special = iospecial; error = DoIO(iodrp); CloseDevice(iodrp); } DeleteExtIO(iodrp); } DeletePort(printerPort); } return(error); }
modules/unpacker.c
#include "iffp/ilbm.h" #include "iffp/packer.h" /*----------------------------------------------------------------------* * unpacker.c Convert data from "cmpByteRun1" run compression. 11/15/85 * * Based on code by Jerry Morrison and Steve Shaw, Electronic Arts. * This software is in the public domain. * * control bytes: * [0..127] : followed by n+1 bytes of data. * [-1..-127] : followed by byte to be repeated (-n)+1 times. * -128 : NOOP. * * This version for the Commodore-Amiga computer. *----------------------------------------------------------------------*/ /*----------- UnPackRow ------------------------------------------------*/ #define UGetByte() (*source++) #define UPutByte(c) (*dest++ = (c)) /* Given POINTERS to POINTER variables, unpacks one row, updating the source * and destination pointers until it produces dstBytes bytes. */ BOOL unpackrow(BYTE **pSource, BYTE **pDest, WORD srcBytes0, WORD dstBytes0) { register BYTE *source = *pSource; register BYTE *dest = *pDest; register WORD n; register BYTE c; register WORD srcBytes = srcBytes0, dstBytes = dstBytes0; BOOL error = TRUE; /* assume error until we make it through the loop */ WORD minus128 = -128; /* get the compiler to generate a CMP.W */ while( dstBytes > 0 ) { if ( (srcBytes -= 1) < 0 ) goto ErrorExit; n = UGetByte(); if (n >= 0) { n += 1; if ( (srcBytes -= n) < 0 ) goto ErrorExit; if ( (dstBytes -= n) < 0 ) goto ErrorExit; do { UPutByte(UGetByte()); } while (--n > 0); } else if (n != minus128) { n = -n + 1; if ( (srcBytes -= 1) < 0 ) goto ErrorExit; if ( (dstBytes -= n) < 0 ) goto ErrorExit; c = UGetByte(); do { UPutByte(c); } while (--n > 0); } } error = FALSE; /* success! */ ErrorExit: *pSource = source; *pDest = dest; return(error); } /* end */
other/clipftxt.c
;/* clipftxt.c - Execute me to compile me with SAS C 5.10 LC -b1 -cfistq -v -j73 clipftxt.c Blink FROM LIB:c.o,clipftxt.o TO clipftxt LIBRARY LIB:LC.lib,LIB:Amiga.lib quit * * clipftxt.c: Writes ASCII text to clipboard unit as FTXT * (All clipboard data must be IFF) * * Usage: clipftxt unitnumber * * To convert to an example of reading only, comment out #define WRITEREAD */ #include <exec/types.h> #include <exec/memory.h> #include <libraries/dos.h> #include <libraries/iffparse.h> #include <clib/exec_protos.h> #include <clib/dos_protos.h> #include <clib/iffparse_protos.h> #include <stdlib.h> #include <stdio.h> #include <string.h> #ifdef LATTICE int CXBRK(void) { return(0); } /* Disable Lattice CTRL/C handling */ int chkabort(void) { return(0); } /* really */ #endif /* Causes example to write FTXT first, then read it back * Comment out to create a reader only */ #define WRITEREAD #define MINARGS 2 /* 2.0 Version string for c:Version to find */ UBYTE vers[] = "\0$VER: clipftxt 37.2"; UBYTE usage[] = "Usage: clipftxt unitnumber (use zero for primary unit)"; /* * Text error messages for possible IFFERR_#? returns from various * IFF routines. To get the index into this array, take your IFFERR code, * negate it, and subtract one. * idx = -error - 1; */ char *errormsgs[] = { "End of file (not an error).", "End of context (not an error).", "No lexical scope.", "Insufficient memory.", "Stream read error.", "Stream write error.", "Stream seek error.", "File is corrupt.", "IFF syntax error.", "Not an IFF file.", "Required call-back hook missing.", "Return to client. You should never see this." }; #define RBUFSZ 512 #define ID_FTXT MAKE_ID('F','T','X','T') #define ID_CHRS MAKE_ID('C','H','R','S') struct Library *IFFParseBase; UBYTE mytext[]="This FTXT written to clipboard by clipftxt example.\n"; void main(int argc, char **argv) { struct IFFHandle *iff = NULL; struct ContextNode *cn; long error=0, unitnumber=0, rlen; int textlen; UBYTE readbuf[RBUFSZ]; /* if not enough args or '?', print usage */ if(((argc)&&(argc<MINARGS))||(argv[argc-1][0]=='?')) { printf("%s\n",usage); exit(RETURN_WARN); } unitnumber = atoi(argv[1]); if (!(IFFParseBase = OpenLibrary ("iffparse.library", 0L))) { puts("Can't open iff parsing library."); goto bye; } /* * Allocate IFF_File structure. */ if (!(iff = AllocIFF ())) { puts ("AllocIFF() failed."); goto bye; } /* * Set up IFF_File for Clipboard I/O. */ if (!(iff->iff_Stream = (ULONG) OpenClipboard (unitnumber))) { puts ("Clipboard open failed."); goto bye; } else printf("Opened clipboard unit %ld\n",unitnumber); InitIFFasClip (iff); #ifdef WRITEREAD /* * Start the IFF transaction. */ if (error = OpenIFF (iff, IFFF_WRITE)) { puts ("OpenIFF for write failed."); goto bye; } /* * Write our text to the clipboard as CHRS chunk in FORM FTXT * * First, write the FORM ID (FTXT) */ if(!(error=PushChunk(iff, ID_FTXT, ID_FORM, IFFSIZE_UNKNOWN))) { /* Now the CHRS chunk ID followed by the chunk data * We'll just write one CHRS chunk. * You could write more chunks. */ if(!(error=PushChunk(iff, 0, ID_CHRS, IFFSIZE_UNKNOWN))) { /* Now the actual data (the text) */ textlen = strlen(mytext); if(WriteChunkBytes(iff, mytext, textlen) != textlen) { puts("Error writing CHRS data."); error = IFFERR_WRITE; } } if(!error) error = PopChunk(iff); } if(!error) error = PopChunk(iff); if(error) { printf ("IFF write failed, error %ld: %s\n", error, errormsgs[-error - 1]); goto bye; } else printf("Wrote text to clipboard as FTXT\n"); /* * Now let's close it, then read it back * First close the write handle, then close the clipboard */ CloseIFF(iff); if (iff->iff_Stream) CloseClipboard ((struct ClipboardHandle *) iff->iff_Stream); if (!(iff->iff_Stream = (ULONG) OpenClipboard (unitnumber))) { puts ("Reopen of Clipboard failed."); goto bye; } else printf("Reopened clipboard unit %ld\n",unitnumber); #endif /* WRITEREAD */ if (error = OpenIFF (iff, IFFF_READ)) { puts ("OpenIFF for read failed."); goto bye; } /* Tell iffparse we want to stop on FTXT CHRS chunks */ if (error = StopChunk(iff, ID_FTXT, ID_CHRS)) { puts ("StopChunk failed."); goto bye; } /* Find all of the FTXT CHRS chunks */ while(1) { error = ParseIFF(iff,IFFPARSE_SCAN); if(error == IFFERR_EOC) continue; /* enter next context */ else if(error) break; /* We only asked to stop at FTXT CHRS chunks * If no error we've hit a stop chunk * Read the CHRS chunk data */ cn = CurrentChunk(iff); if((cn)&&(cn->cn_Type == ID_FTXT)&&(cn->cn_ID == ID_CHRS)) { printf("CHRS chunk contains:\n"); while((rlen = ReadChunkBytes(iff,readbuf,RBUFSZ)) > 0) { Write(Output(),readbuf,rlen); } if(rlen < 0) error = rlen; } } if((error)&&(error != IFFERR_EOF)) { printf ("IFF read failed, error %ld: %s\n", error, errormsgs[-error - 1]); } bye: if (iff) { /* * Terminate the IFF transaction with the stream. Free * all associated structures. */ CloseIFF (iff); /* * Close the clipboard stream */ if (iff->iff_Stream) CloseClipboard ((struct ClipboardHandle *) iff->iff_Stream); /* * Free the IFF_File structure itself. */ FreeIFF (iff); } if (IFFParseBase) CloseLibrary (IFFParseBase); exit (RETURN_OK); }
other/cycvb.c
/* * cycvb.c --- Dan Silva's DPaint color cycling interrupt code * * Use this fragment as an example for interrupt driven color cycling * If compiled with SAS, include flags -v -y on LC2 */ #include <exec/types.h> #include <exec/interrupts.h> #include <graphics/view.h> #include <iff/compiler.h> #define MAXNCYCS 4 #define NO FALSE #define YES TRUE #define LOCAL static typedef struct { SHORT count; SHORT rate; SHORT flags; UBYTE low, high; /* bounds of range */ } Range; /* Range flags values */ #define RNG_ACTIVE 1 #define RNG_REVERSE 2 #define RNG_NORATE 36 /* if rate == NORATE, don't cycle */ /* cycling frame rates */ #define OnePerTick 16384 #define OnePerSec OnePerTick/60 extern Range cycles[]; extern BOOL cycling[]; extern WORD cycols[]; extern struct ViewPort *vport; extern SHORT nColors; MyVBlank() { int i,j; LOCAL Range *cyc; LOCAL WORD temp; LOCAL BOOL anyChange; #ifdef IS_AZTEC #asm movem.l a2-a7/d2-d7,-(sp) move.l a1,a4 #endasm #endif if (cycling) { anyChange = NO; for (i=0; i<MAXNCYCS; i++) { cyc = &cycles[i]; if ( (cyc->low == cyc->high) || ((cyc->flags&RNG_ACTIVE) == 0) || (cyc->rate == RNG_NORATE) ) continue; cyc->count += cyc->rate; if (cyc->count >= OnePerTick) { anyChange = YES; cyc->count -= OnePerTick; if (cyc->flags&RNG_REVERSE) { temp = cycols[cyc->low]; for (j=cyc->low; j < cyc->high; j++) cycols[j] = cycols[j+1]; cycols[cyc->low] = temp; } else { temp = cycols[cyc->high]; for (j=cyc->high; j > cyc->low; j--) cycols[j] = cycols[j-1]; cycols[cyc->low] = temp; } } } if (anyChange) LoadRGB4(vport,cycols,nColors); } #ifdef IS_AZTEC ; /* this is necessary */ #asm movem.l (sp)+,a2-a7/d2-d7 #endasm #endif return(0); /* interrupt routines have to do this */ } /* * Code to install/remove cycling interrupt handler */ LOCAL char myname[] = "MyVB"; /* Name of interrupt handler */ LOCAL struct Interrupt intServ; typedef void (*VoidFunc)(); StartVBlank() { #ifdef IS_AZTEC intServ.is_Data = GETAZTEC(); /* returns contents of register a4 */ #else intServ.is_Data = NULL; #endif intServ.is_Code = (VoidFunc)&MyVBlank; intServ.is_Node.ln_Succ = NULL; intServ.is_Node.ln_Pred = NULL; intServ.is_Node.ln_Type = NT_INTERRUPT; intServ.is_Node.ln_Pri = 0; intServ.is_Node.ln_Name = myname; AddIntServer(5,&intServ); } StopVBlank() { RemIntServer(5,&intServ); } /**/
other/ilbmscan.c
;/* ilbmscan.c - Execute me to compile me with SAS C 5.10 LC -b1 -cfistq -v -j73 ilbmscan.c Blink FROM LIB:c.o,ilbmscan.o TO ilbmscan LIBRARY LIB:LC.lib,LIB:Amiga.lib quit * * ilbmscan.c: Prints the size, aspect, mode, etc. of ILBM's * Scans through an IFF file for all ILBM's * * Usage: ilbmscan -c ; For clipboard scanning * or ilbmscan <file> ; For DOS file scanning * * Based on sift.c by by Stuart Ferguson and Leo Schwab */ #include <exec/types.h> #include <exec/memory.h> #include <libraries/dos.h> #include <libraries/iffparse.h> #include <clib/exec_protos.h> #include <clib/dos_protos.h> #include <clib/iffparse_protos.h> #include <stdlib.h> #include <stdio.h> #include <string.h> #ifdef LATTICE int CXBRK(void) { return(0); } /* Disable Lattice CTRL/C handling */ int chkabort(void) { return(0); } /* really */ #endif /* The structure of a FORM ILBM 'BMHD' and 'CAMG' chunks * Such structures are defined in the spec for a FORM * and may also be provided in include files */ /* Bitmap header (BMHD) structure */ typedef struct { UWORD w, h; /* Width, height in pixels */ WORD x, y; /* x, y position for this bitmap */ UBYTE nplanes; /* # of planes */ UBYTE Masking; UBYTE Compression; UBYTE pad1; UWORD TransparentColor; UBYTE XAspect, YAspect; WORD PageWidth, PageHeight; } BitMapHeader; /* Commodore Amiga (CAMG) Viewmodes structure */ typedef struct { ULONG ViewModes; } CamgChunk; #define ID_ILBM MAKE_ID('I','L','B','M') #define ID_BMHD MAKE_ID('B','M','H','D') #define ID_CMAP MAKE_ID('C','M','A','P') #define ID_CAMG MAKE_ID('C','A','M','G') #define ID_BODY MAKE_ID('B','O','D','Y') void PrintILBMInfo(struct IFFHandle *); #define MINARGS 2 /* 2.0 Version string for c:Version to find */ UBYTE vers[] = "\0$VER: ilbmscan 37.3"; UBYTE usage[] = "Usage: ilbmscan IFFfilename (or -c for clipboard)"; /* * Text error messages for possible IFFERR_#? returns from various * IFF routines. To get the index into this array, take your IFFERR code, * negate it, and subtract one. * idx = -error - 1; */ char *errormsgs[] = { "End of file (not an error).", "End of context (not an error).", "No lexical scope.", "Insufficient memory.", "Stream read error.", "Stream write error.", "Stream seek error.", "File is corrupt.", "IFF syntax error.", "Not an IFF file.", "Required call-back hook missing.", "Return to client. You should never see this." }; struct Library *IFFParseBase; void main(int argc, char **argv) { struct IFFHandle *iff = NULL; long error; short cbio; /* if not enough args or '?', print usage */ if(((argc)&&(argc<MINARGS))||(argv[argc-1][0]=='?')) { printf("%s\n",usage); exit(RETURN_OK); } /* * Check to see if we are doing I/O to the Clipboard. */ cbio = (argv[1][0] == '-' && argv[1][1] == 'c'); if (!(IFFParseBase = OpenLibrary ("iffparse.library", 0L))) { printf("Can't open iff parsing library."); goto bye; } /* * Allocate IFF_File structure. */ if (!(iff = AllocIFF ())) { printf ("AllocIFF() failed."); goto bye; } /* * Internal support is provided for both AmigaDOS files, and the * clipboard.device. This bizarre 'if' statement performs the * appropriate machinations for each case. */ if (cbio) { /* * Set up IFF_File for Clipboard I/O. */ if (!(iff->iff_Stream = (ULONG) OpenClipboard (PRIMARY_CLIP))) { printf("Clipboard open failed."); goto bye; } InitIFFasClip (iff); } else { /* * Set up IFF_File for AmigaDOS I/O. */ if (!(iff->iff_Stream = Open (argv[1], MODE_OLDFILE))) { printf("File open failed."); goto bye; } InitIFFasDOS (iff); } /* * Start the IFF transaction. */ if (error = OpenIFF (iff, IFFF_READ)) { printf("OpenIFF failed."); goto bye; } /* We want to collect BMHD and CAMG */ PropChunk(iff, ID_ILBM, ID_BMHD); PropChunk(iff, ID_ILBM, ID_CAMG); PropChunk(iff, ID_ILBM, ID_CMAP); /* Stop at the BODY */ StopChunk(iff, ID_ILBM, ID_BODY); /* And let us know (IFFERR_EOC) when leaving a FORM ILBM */ StopOnExit(iff,ID_ILBM, ID_FORM); /* Do the scan. * The while(1) will let us delve into more complex formats * to find FORM ILBM's */ while (1) { error = ParseIFF(iff, IFFPARSE_SCAN); /* * Since we're only interested in when we enter a context, * we "discard" end-of-context (_EOC) events. */ if (error == IFFERR_EOC) { printf("Exiting FORM ILBM\n\n"); continue; } else if (error) /* * Leave the loop if there is any other error. */ break; /* * If we get here, error was zero * Since we did IFFPARSE_SCAN, zero error should mean * we are at our Stop Chunk (BODY) */ PrintILBMInfo(iff); } /* * If error was IFFERR_EOF, then the parser encountered the end of * the file without problems. Otherwise, we print a diagnostic. */ if (error == IFFERR_EOF) printf("File scan complete.\n"); else printf("File scan aborted, error %ld: %s\n", error, errormsgs[-error - 1]); bye: if (iff) { /* * Terminate the IFF transaction with the stream. Free * all associated structures. */ CloseIFF (iff); /* * Close the stream itself. */ if (iff->iff_Stream) if (cbio) CloseClipboard ((struct ClipboardHandle *) iff->iff_Stream); else Close (iff->iff_Stream); /* * Free the IFF_File structure itself. */ FreeIFF (iff); } if (IFFParseBase) CloseLibrary (IFFParseBase); exit (RETURN_OK); } void PrintILBMInfo(iff) struct IFFHandle *iff; { struct StoredProperty *sp; BitMapHeader *bmhd; CamgChunk *camg; /* * Get a pointer to the stored propery BMHD */ if (!(sp = FindProp(iff, ID_ILBM, ID_BMHD))) printf("No BMHD found\n"); else { /* If property is BMHD, sp->sp_Data is ptr to data in BMHD */ bmhd = (BitMapHeader *)sp->sp_Data; printf("BMHD: Width = %ld\n",bmhd->w); printf(" Height = %ld\n",bmhd->h); printf(" PageWidth = %ld\n",bmhd->PageWidth); printf(" PageHeight = %ld\n",bmhd->PageHeight); printf(" nplanes = %ld\n",bmhd->nplanes); printf(" Masking = %ld\n",bmhd->Masking); printf(" Compression= %ld\n",bmhd->Compression); printf(" TransColor = %ld\n",bmhd->TransparentColor); printf(" X/Y Aspect = %ld/%ld\n",bmhd->XAspect,bmhd->YAspect); } /* * Get a pointer to the stored propery CMAP */ if (!(sp = FindProp(iff, ID_ILBM, ID_CMAP))) printf("No CMAP found\n"); else { /* If property is CMAP, sp->sp_Data is ptr to data in CMAP */ printf("CMAP: contains RGB values for %ld registers\n", sp->sp_Size / 3); } /* * Get a pointer to the stored propery CAMG */ if (!(sp = FindProp(iff, ID_ILBM, ID_CAMG))) printf("No CAMG found\n"); else { /* If property is CAMG, sp->sp_Data is ptr to data in CAMG */ camg = (CamgChunk *)sp->sp_Data; printf("CAMG: ModeID = $%08lx\n\n",camg->ViewModes); } }
other/sift.c
;/* sift.c - Execute me to compile me with SAS C 5.10 LC -b1 -cfistq -v -j73 sift.c Blink FROM LIB:c.o,sift.o TO sift LIBRARY LIB:LC.lib,LIB:Amiga.lib quit * * sift.c: Takes any IFF file and tells you what's in it. Verifies * syntax and all that cool stuff. * * Usage: sift -c ; For clipboard scanning * or sift <file> ; For DOS file scanning * * Reads the specified stream and prints an IFFCheck-like listing of the * contents of the IFF file, if any. Stream is a DOS file for <file> * argument, or is the clipboard's primary clip for -c. * This program must be run from a CLI. * * Based on original sift.c by by Stuart Ferguson and Leo Schwab */ #include <exec/types.h> #include <exec/memory.h> #include <libraries/dos.h> #include <libraries/iffparse.h> #include <clib/exec_protos.h> #include <clib/dos_protos.h> #include <clib/iffparse_protos.h> #include <stdlib.h> #include <stdio.h> #include <string.h> #ifdef LATTICE int CXBRK(void) { return(0); } /* Disable Lattice CTRL/C handling */ int chkabort(void) { return(0); } /* really */ #endif #define MINARGS 2 /* 2.0 Version string for c:Version to find */ UBYTE vers[] = "\0$VER: sift 37.1"; UBYTE usage[] = "Usage: sift IFFfilename (or -c for clipboard)"; /* proto for our function */ void PrintTopChunk (struct IFFHandle *); /* * Text error messages for possible IFFERR_#? returns from various * IFF routines. To get the index into this array, take your IFFERR code, * negate it, and subtract one. * idx = -error - 1; */ char *errormsgs[] = { "End of file (not an error).", "End of context (not an error).", "No lexical scope.", "Insufficient memory.", "Stream read error.", "Stream write error.", "Stream seek error.", "File is corrupt.", "IFF syntax error.", "Not an IFF file.", "Required call-back hook missing.", "Return to client. You should never see this." }; struct Library *IFFParseBase; void main(int argc, char **argv) { struct IFFHandle *iff = NULL; long error; short cbio; /* if not enough args or '?', print usage */ if(((argc)&&(argc<MINARGS))||(argv[argc-1][0]=='?')) { printf("%s\n",usage); goto bye; } /* * Check to see if we are doing I/O to the Clipboard. */ cbio = (argv[1][0] == '-' && argv[1][1] == 'c'); if (!(IFFParseBase = OpenLibrary ("iffparse.library", 0L))) { puts("Can't open iff parsing library."); goto bye; } /* * Allocate IFF_File structure. */ if (!(iff = AllocIFF ())) { puts ("AllocIFF() failed."); goto bye; } /* * Internal support is provided for both AmigaDOS files, and the * clipboard.device. This bizarre 'if' statement performs the * appropriate machinations for each case. */ if (cbio) { /* * Set up IFF_File for Clipboard I/O. */ if (!(iff->iff_Stream = (ULONG) OpenClipboard (PRIMARY_CLIP))) { puts ("Clipboard open failed."); goto bye; } InitIFFasClip (iff); } else { /* * Set up IFF_File for AmigaDOS I/O. */ if (!(iff->iff_Stream = Open (argv[1], MODE_OLDFILE))) { puts ("File open failed."); goto bye; } InitIFFasDOS (iff); } /* * Start the IFF transaction. */ if (error = OpenIFF (iff, IFFF_READ)) { puts ("OpenIFF failed."); goto bye; } while (1) { /* * The interesting bit. IFFPARSE_RAWSTEP permits us to * have precision monitoring of the parsing process, which * is necessary if we wish to print the structure of an * IFF file. ParseIFF() with _RAWSTEP will return the * following things for the following reasons: * * Return code: Reason: * 0 Entered new context. * IFFERR_EOC About to leave a context. * IFFERR_EOF Encountered end-of-file. * <anything else> A parsing error. */ error = ParseIFF (iff, IFFPARSE_RAWSTEP); /* * Since we're only interested in when we enter a context, * we "discard" end-of-context (_EOC) events. */ if (error == IFFERR_EOC) continue; else if (error) /* * Leave the loop if there is any other error. */ break; /* * If we get here, error was zero. * Print out the current state of affairs. */ PrintTopChunk (iff); } /* * If error was IFFERR_EOF, then the parser encountered the end of * the file without problems. Otherwise, we print a diagnostic. */ if (error == IFFERR_EOF) puts ("File scan complete."); else printf ("File scan aborted, error %ld: %s\n", error, errormsgs[-error - 1]); bye: if (iff) { /* * Terminate the IFF transaction with the stream. Free * all associated structures. */ CloseIFF (iff); /* * Close the stream itself. */ if (iff->iff_Stream) if (cbio) CloseClipboard ((struct ClipboardHandle *) iff->iff_Stream); else Close (iff->iff_Stream); /* * Free the IFF_File structure itself. */ FreeIFF (iff); } if (IFFParseBase) CloseLibrary (IFFParseBase); exit (RETURN_OK); } void PrintTopChunk (iff) struct IFFHandle *iff; { struct ContextNode *top; short i; char idbuf[5]; /* * Get a pointer to the context node describing the current context. */ if (!(top = CurrentChunk (iff))) return; /* * Print a series of dots equivalent to the current nesting depth of * chunks processed so far. This will cause nested chunks to be * printed out indented. */ for (i = iff->iff_Depth; i--; ) printf (". "); /* * Print out the current chunk's ID and size. */ printf ("%s %ld ", IDtoStr (top->cn_ID, idbuf), top->cn_Size); /* * Print the current chunk's type, with a newline. */ puts (IDtoStr (top->cn_Type, idbuf)); }