home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Club Amiga de Montreal - CAM
/
CAM_CD_1.iso
/
files
/
274.lha
/
SimGen_Src
/
MYILBMR.c
< prev
next >
Wrap
C/C++ Source or Header
|
1989-07-26
|
7KB
|
252 lines
/*----------------------------------------------------------------------*
* ILBMR.C Support routines for reading ILBM files. 11/27/85
* (IFF is Interchange Format File.)
*
* By Jerry Morrison and Steve Shaw, Electronic Arts.
* This software is in the public domain.
*
* This version for the Commodore-Amiga computer.
*----------------------------------------------------------------------*/
#include <exec/memory.h>
#include <graphics/rastport.h>
#include <iff/packer.h>
#include <iff/ilbm.h>
#include <iff/readpict.h>
#include "picture.h"
#include <mymacros.h>
/* ---------- GetCMAP ------------------------------------------------*/
/* pNColorRegs is passed in as a pointer to the number of ColorRegisters
* caller has space to hold. GetCMAP sets to the number actually read.*/
IFFP GetCMAP(ilbmContext, colorMap, pNColorRegs)
GroupContext *ilbmContext;
WORD *colorMap;
WORD *pNColorRegs;
{
register int nColorRegs;
register IFFP iffp;
ColorRegister colorReg;
nColorRegs = ilbmContext->ckHdr.ckSize / sizeofColorRegister;
if (*pNColorRegs < nColorRegs) {
nColorRegs = *pNColorRegs;
}
*pNColorRegs = nColorRegs; /* Set to the number actually there.*/
for ( ; nColorRegs > 0; --nColorRegs) {
iffp = IFFReadBytes(ilbmContext, (BYTE *)&colorReg,sizeofColorRegister);
CheckIFFP();
*colorMap++ = ( ( colorReg.red >> 4 ) << 8 ) |
( ( colorReg.green >> 4 ) << 4 ) |
( ( colorReg.blue >> 4 ) );
}
return(IFF_OKAY);
}
/*---------- GetBODY ---------------------------------------------------*/
/* NOTE: This implementation could be a LOT faster if it used more of the
* supplied buffer. It would make far fewer calls to IFFReadBytes (and
* therefore to DOS Read) and to movemem. */
IFFP GetBODY(context, ilbmframe, mask, buffer, bufsize, srcbm)
GroupContext *context;
ILBMFrame *ilbmframe;
BYTE *mask;
BYTE *buffer;
LONG bufsize;
struct BitMap *srcbm;
{
register IFFP iffp;
BitMapHeader *bmHdr = &ilbmframe->bmHdr;
UBYTE srcPlaneCnt = bmHdr->nPlanes;
WORD srcRowBytes = RowBytes(bmHdr->w);
LONG bufRowBytes = MaxPackedSize(srcRowBytes);
int nRows = bmHdr->h;
Compression compression = bmHdr->compression;
register int iPlane, iRow, nEmpty;
register WORD nFilled;
BYTE *buf, *nullDest, *nullBuf, **pDest;
BYTE *planes[MaxSrcPlanes]; /* array of ptrs to planes & mask */
long gtemp;
NewImage *ni = ilbmframe->ni;
struct BitMap *bitmap = (struct BitMap *)ni->ImagePtr;
struct RastPort *rp = (struct RastPort *)ni->ImagePtr;
BYTE *gDest;
/**********************
**
** Added for SimGen.
**
*********************/
AboutToLoadBody (ilbmframe);
if (compression > cmpByteRun1)
return(CLIENT_ERROR);
/*
* if mode = CREATEPIC
* Allocate and Initialize a bitmap for this picture
*/
if (ni->Flags & (NI_CREATEPIC | NI_CREATESHAPE)) {
int i;
int w;
int h;
if (ni->Flags & NI_CLIPIMAGE) {
w = ni->Width;
h = ni->Height;
} else {
w = bmHdr->w;
h = bmHdr->h;
}
ni->Flags |= NI_USEBITMAP;
bitmap = &ilbmframe->pic->BitMap;
ni->ImagePtr = (APTR)bitmap;
InitBitMap (bitmap, bmHdr->nPlanes, w, h);
for (i=0; i<bmHdr->nPlanes; i++) {
if (!( bitmap->Planes[i] =
(*ilbmframe->allocmem)(RASSIZE(w, h), MEMF_CHIP|MEMF_CLEAR))) {
return (CLIENT_ERROR);
}
}
} else {
if (!(ni->Flags & NI_USEBITMAP)) {
bitmap = rp->BitMap;
}
}
/* Complain if client asked for a conversion GetBODY doesn't handle.*/
if (!ni->Flags & NI_CLIPIMAGE) {
if (srcPlaneCnt > MaxSrcPlanes ||
srcRowBytes > bitmap->BytesPerRow ||
nRows > bitmap->Rows)
return (CLIENT_ERROR);
}
/* Initialize array "planes" with bitmap ptrs; NULL in empty slots.*/
for (iPlane = 0; iPlane < srcbm->Depth; iPlane++)
planes[iPlane] = (BYTE *)srcbm->Planes[iPlane];
for ( ; iPlane < MaxSrcPlanes; iPlane++)
planes[iPlane] = NULL;
/* Copy any mask plane ptr into corresponding "planes" slot.*/
if (bmHdr->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 = 0; iRow < nRows; iRow++) {
for (iPlane = 0; iPlane < srcPlaneCnt; iPlane++) {
gDest = (BYTE *)srcbm->Planes[iPlane];
pDest = &gDest;
/* 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(context)) {
/* There aren't enough bytes left to fill the buffer.*/
nEmpty = ChunkMoreBytes(context);
bufsize = nFilled + nEmpty; /* heh-heh */
}
/* Append new data to the existing data.*/
iffp = IFFReadBytes(context, &buffer[nFilled], nEmpty);
CheckIFFP();
buf = buffer;
nFilled = bufsize;
nEmpty = 0;
}
/* Copy uncompressed row to destination plane.*/
if (compression == cmpNone) {
if (nFilled < srcRowBytes) return(BAD_FORM);
movmem(buf, *pDest, srcRowBytes);
buf += srcRowBytes;
} else {
/* Decompress row to destination plane.*/
if ( UnPackRow(&buf, pDest, nFilled, srcRowBytes) )
/* pSource, pDest, srcBytes, dstBytes */
return(BAD_FORM);
}
}
if (ni->Flags & NI_USEBITMAP) {
if (ni->Flags & NI_CLIPIMAGE) {
if (iRow >= ni->FTop &&
iRow < ni->FTop + ni->Height) {
BltBitMap (srcbm,
ni->FLeft,
0,
bitmap,
ni->Left,
ni->Top + iRow - ni->FTop,
min(ni->Width, bmHdr->w), 1,
0xC0, 0xFF, NULL);
}
} else {
BltBitMap (srcbm, 0, 0,
bitmap, 0, iRow, bmHdr->w, 1,
0xC0, 0xFF, NULL);
}
} else {
if (ni->Flags & NI_CLIPIMAGE) {
if (iRow >= ni->FTop &&
iRow < ni->FTop + ni->Height) {
BltBitMapRastPort (srcbm,
ni->FLeft,
0,
rp,
ni->Left,
ni->Top + iRow - ni->FTop,
ni->Width, 1,
0xC0, 0xFF, NULL);
}
} else {
BltBitMapRastPort (srcbm, 0, 0,
rp, 0, iRow, bmHdr->w, 1,
0xC0, 0xFF, NULL);
}
}
}
return(IFF_OKAY);
}