home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Fresh Fish 8
/
FreshFishVol8-CD1.bin
/
new
/
gfx
/
misc
/
getilbm
/
getilbm.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-11-11
|
32KB
|
882 lines
//===========================================================================
// GETILBM.C -- for AmigaDOS 2.0/3.0 (and maybe 1.3 with iffparse.library)
// Rev: 30 September 1994, Alex Matulich matulich_alex@SEAA.NAVSEA.NAVY.MIL
//
// For SAS C/C++ 6.xx. Compile with IGNORE=51 to disable warnings for
// C++ comments (I got addicted to those C++ comments...)
//
// This module is for loading IFF ILBM pictures. The *only* functions you
// need to call are loadilbmScreen() and freeilbmScreen(), or if you are
// just loading into bitmaps, call loadilbmBitMap() and freeBitMap().
//
// The iffparse.library must be opened prior to calling these routines.
// SAS C 6.xx does this automatically for you.
//
// This module was adapted from the confusing plethora of functions in the
// Amiga Developer's package for AmigaDOS 3.1. All adaptations and excerpts
// are indicated in the comments.
//===========================================================================
//---------------------------------------------------------------------------
// To make the demo ILBM file reader, compile with only the symbol DEMO
// defined. Example: sc optimize optsize def=DEMO link getilbm.c
//
// You might have your own versions of getBitMap() and freeBitMap() external
// to this module (I do, for example, in my video buffering module). If so,
// then make sure the following two #defines are commented out. If you wish
// to use the getBitMap() and freeBitMap() functions contained in this
// module, then uncomment the following two #defines.
// #define USE_GETBM // comment out if you already have a getBitMap()
// #define USE_FREEBM // comment out if you already have a freeBitMap()
// These functions, if external, should be compatible with the prototypes
// in getilbm_proto.h.
//
// Defining TIMECHECK enables calls to a user-supplied external function
// check_for_switch() while the IFF file is loading. The purpose of this
// function is to allow the program to do time-critical things while a
// large ILBM file is loading. Sort of a pseudo-multitasking technique.
// #define TIMECHECK // only if you need a check_for_switch() function
// Often it is more useful to simply load an IFF file into a bitmap, rather
// than create a whole screen for it. If you want to do just this, and you
// never need to load an IFF file into a screen, then uncomment this line:
// #define NOILBMSCREEN // only compile loadilbmBitMap() and associates
// This will cause the functions loadilbmScreen() and associated functions
// and declarations to be skipped during compililation.
//
// Conversely, if you don't need loadilbmBitMap(), but only loadilbmScreen(),
// then uncomment this line:
//
// #define ILBMSCREENONLY // only compile loadilbmScreen() and associates
//
// The existence of getBitMap() and freeBitMap() are still controlled by
// USE_GETBM and USE_FREEBM.
// Do not define both NOILBMSCREEN and ILBMSCREENONLY at the same time.
// Do not define either of them if you need *both* loadilbmScreen() and
// loadilbmBitMap().
//---------------------------------------------------------------------------
#ifdef NOTIMECHECK // for compatibility with previous versions
#undef TIMECHECK
#endif
#ifdef DEMO // re-set definitions if compiling the demo
#ifdef USE_GETBM
#undef USE_GETBM // demo doesn't need getBitMap()
#endif
#ifdef USE_FREEBM
#undef USE_FREEBM // demo doesn't need freeBitMap()
#endif
#ifdef TIMECHECK
#undef TIMECHECK // demo doesn't need check_for_switch()
#endif
#ifdef NOILBMSCREEN
#undef NOILBMSCREEN // demo doesn't need loadilbmBitmap()
#endif
#ifndef ILBMSCREENONLY
#define ILBMSCREENONLY // demo DOES need loadilbmScreen()
#endif
#endif
#include <exec/memory.h>
#include <exec/libraries.h>
#include <graphics/gfx.h>
#include <libraries/dos.h>
#include <libraries/iffparse.h>
#include <proto/exec.h>
#include <proto/graphics.h>
#include <proto/dos.h>
#include <proto/iffparse.h>
#ifndef NOILBMSCREEN
#define USE_BUILTIN_MATH 1 // to use built-in min() and max() in string.h
#include <string.h>
#include <graphics/display.h>
#include <intuition/intuition.h>
#include <proto/intuition.h>
#endif // !NOILBMSCREEN
#include <stdlib.h>
#include "getilbm_proto.h" // prototypes for user-callable functions
extern struct Library *IFFParseBase;
// definitions from iffp/iff.h
#define ChunkMoreBytes(cn) (cn->cn_Size - cn->cn_Scan)
struct Chunk {
struct Chunk *ch_Next;
long ch_Type, ch_ID, ch_Size;
void *ch_Data;
};
// definitions from iffp/ilbm.h
#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_BODY MAKE_ID('B','O','D','Y')
#define ID_CAMG MAKE_ID('C','A','M','G')
// sizeof(a 3-byte structure) returns 16 due to word alignment, so we use:
#define sizeofColorRegister 3
#define MAXAMDEPTH 8 // used for OS<V37, screen.c maxdisplaydepth(ID)
#define MAXAMCOLORREG 32 // should use ViewPort->ColorMap.Count instead
#define RowBytes(w) ((((w) + 15) >> 4) << 1)
#define RowBits(w) ((((w) + 15) >> 4) << 4)
#define mskNone 0 // masking techniques
#define mskHasMask 1
#define cmpNone 0 // compression techniques
#define cmpByteRun1 1
typedef struct {
UWORD w, h; // raster width and height
WORD x, y; // pixel position for this image
UBYTE nPlanes, masking, // # source bitplanes, masking (?)
compression, flags; // compression, Commodore-defined flags
UWORD transparentColor; // transparent color number (sort of)
UBYTE xAspect, yAspect; // pixel aspect ratio width/height
WORD pageWidth, pageHeight; // source page size in pixels
} BitMapHeader;
typedef struct { UBYTE red, green, blue; } ColorRegister;
typedef struct { ULONG ViewModes; } CamgChunk;
#define BMHDB_CMAPOK 7
#define BMHDF_CMAPOK (1 << BMHDB_CMAPOK)
// from iffp/packer.h
#define MaxPackedSize(rowsize) ((rowsize)+(((rowsize)+127)>>7))
//---------------------------------------------------------------------------
// Skip following five declarations if you don't need loadilbmScreen().
#ifndef NOILBMSCREEN
static UWORD __far ins_pens[] = { 0xffff }; // minimal pen definitions
long li_errcode; // error code returned by OpenScreen()
// You will want to expand the following tag list if you decide to
// substitute OpenScreenTagList() for OpenScreen() in loadilbmScreen().
// OpenScreen() works with all video modes, and is used here for
// compatibility with AmigaDOS 1.3, just in case such an OS happens to
// have a compatible iffparse.library.
static struct TagItem __far ins_ext[] = {
SA_DisplayID, 0L, // tag needed for display mode
SA_DClip, 0L, // needed for screen centering
SA_AutoScroll, TRUE, // not really needed, but who cares?
SA_Pens, (ULONG)ins_pens, // minimal tags needed for 2.0
SA_ErrorCode, (ULONG)&li_errcode, // examine li_errcode for error codes
TAG_DONE
};
// Instead of opening a screen with functions specific to AmigaDOS 2.0,
// we define an ExtNewScreen structure for use with OpenScreen() to
// maintain compatibility with earlier OS versions. The ins_ext[] taglist
// above provides the enhancements necessary for OS 2.0 or greater.
static struct ExtNewScreen __far ins = {
0, 0, ~0, ~0, // left, top, width & height
2, 0, 1, // depth, DetailPen, BlockPen
0, // ViewModes
CUSTOMSCREEN | SCREENQUIET | SCREENBEHIND | NS_EXTENDED,
NULL, // font
NULL, NULL, NULL, // title, gadgets, bitmap
ins_ext // tag extensions
};
static struct NewWindow __far inw = {
0, 0, ~0, ~0, // left, top, width, height
0, 1, // DetailPen, BlockPen
IDCMP_RAWKEY | IDCMP_VANILLAKEY, // IDCMP flags (whatever you like)
SIMPLE_REFRESH | BORDERLESS | BACKDROP |