home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Fresh Fonts 1
/
freshfonts1.bin
/
programs
/
amiga
/
pastex
/
pastex14-beta-6
/
specialhost
/
source
/
readimage.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-05-27
|
48KB
|
2,275 lines
/*
** SpecialHost for PasTeX
**
** Copyright © by Olaf Barthel & Georg Heßmann
*/
#include "Global.h"
enum { CLUT_MONO,CLUT_RED,CLUT_GREEN,CLUT_BLUE,CLUT_HUE,CLUT_SAT };
#define ID_CLUT MAKE_ID('C','L','U','T')
#define ID_DPI MAKE_ID('D','P','I',' ')
#define CACHE_SIZE 16384
struct DPIHeader
{
UWORD DPI_X,
DPI_Y;
};
struct CLUT
{
ULONG Type;
ULONG Reserved;
UBYTE LUT[256];
};
struct BufferHandle
{
struct IFFHandle *Handle;
UBYTE *Index,
Buffer[CACHE_SIZE];
LONG Length;
BOOL FromClip;
};
struct PictureInfo
{
struct BitMapHeader BitMapHeader;
ULONG *ColourMap,
ViewModes;
LONG NumColours;
struct CLUT *CLUT[CLUT_HUE];
struct BitMap *BitMap[3];
UBYTE *TempLine[3];
struct GreyImage *GreyImage;
LONG *Error;
struct RastPort *TempRPort,
DummyRPort;
BOOL GotCLUT;
};
extern LONG HookEntry();
STATIC BOOL __regargs GetClipID(STRPTR Name,LONG *ID);
STATIC LONG __saveds StreamHandler(struct Hook *Hook,struct IFFHandle *Handle,struct IFFStreamCmd *ActionPkt);
STATIC LONG __regargs BufferFill(struct BufferHandle *Handle);
STATIC LONG __regargs BufferGet(struct BufferHandle *Handle);
STATIC LONG __regargs BufferRead(struct BufferHandle *Handle,UBYTE *Buffer,LONG Size);
STATIC LONG __regargs BufferSeek(struct BufferHandle *Handle,LONG Size);
STATIC VOID __regargs BufferClose(struct BufferHandle *Handle);
STATIC struct BufferHandle * __regargs BufferOpen(STRPTR Name);
STATIC struct GreyImage * __regargs CreateImage(LONG Width,LONG Height);
STATIC UBYTE * __regargs AddLine(struct GreyImage *Image);
STATIC struct BufferHandle * __regargs ReadImageHeader(STRPTR Name,BOOL PatchColour,struct PictureInfo *PictureInfo);
STATIC VOID __regargs ReadHAM6Data(struct BufferHandle *Handle,struct PictureInfo *PictureInfo);
STATIC VOID __regargs ReadHAM8Data(struct BufferHandle *Handle,struct PictureInfo *PictureInfo);
STATIC VOID __regargs ReadVanillaData(struct BufferHandle *Handle,struct PictureInfo *PictureInfo);
STATIC VOID __regargs ReadDeepData(struct BufferHandle *Handle,struct PictureInfo *PictureInfo);
STATIC VOID __regargs ConvertHAM6Data(struct PictureInfo *PictureInfo);
STATIC VOID __regargs ConvertHAM8Data(struct PictureInfo *PictureInfo);
STATIC VOID __regargs ConvertVanillaData(struct PictureInfo *PictureInfo);
STATIC struct GreyImage * __regargs ReadPicture(STRPTR Name,BOOL PatchColours,LONG *Error);
STATIC struct GreyImage * __regargs ReadILBM(STRPTR Name,BOOL PatchColours,LONG *Error);
STATIC BOOL __regargs GetPictureSize(STRPTR Name,LONG *Width,LONG *Height,LONG *Error);
STATIC BOOL __regargs GetILBMSize(STRPTR Name,LONG *Width,LONG *Height,LONG *Error);
STATIC BOOL __regargs GetPicture_DPI(STRPTR Name,LONG *DPI_X,LONG *DPI_Y,LONG *Error);
STATIC BOOL __regargs GetILBM_DPI(STRPTR Name,LONG *DPI_X,LONG *DPI_Y,LONG *Error);
STATIC struct Hook StreamHook =
{
{NULL},
(ULONG (*)())HookEntry,
(ULONG (*)())StreamHandler,
NULL
};
STATIC BOOL __regargs
GetClipID(STRPTR Name,LONG *ID)
{
if(!Strnicmp(Name,"CLIPBOARD:",10))
{
if(ID)
StrToLong(Name + 10,ID);
return(TRUE);
}
else
return(FALSE);
}
STATIC LONG __saveds
StreamHandler(struct Hook *Hook,struct IFFHandle *Handle,struct IFFStreamCmd *ActionPkt)
{
struct AsyncFile *Stream = (struct AsyncFile *)Handle -> iff_Stream;
LONG Bytes = ActionPkt -> sc_NBytes;
switch(ActionPkt -> sc_Command)
{
case IFFCMD_READ:
return(ReadAsync(Stream,ActionPkt -> sc_Buf,Bytes) != Bytes);
case IFFCMD_WRITE:
return(WriteAsync(Stream,ActionPkt -> sc_Buf,Bytes) != Bytes);
case IFFCMD_SEEK:
return(SeekAsync(Stream,Bytes,MODE_CURRENT) == -1);
default:
return(0);
}
}
STATIC LONG __regargs
BufferFill(struct BufferHandle *Handle)
{
Handle -> Index = Handle -> Buffer;
return(Handle -> Length = ReadChunkBytes(Handle -> Handle,Handle -> Buffer,CACHE_SIZE));
}
STATIC LONG __regargs
BufferGet(struct BufferHandle *Handle)
{
if(!Handle -> Length)
{
if(BufferFill(Handle) < 1)
return(-1);
}
Handle -> Length--;
return(*Handle -> Index++);
}
STATIC LONG __regargs
BufferRead(struct BufferHandle *Handle,UBYTE *Buffer,LONG Size)
{
LONG BytesRead = 0,Count;
while(Size)
{
if(!Handle -> Length)
{
if(BufferFill(Handle) < 1)
return(BytesRead);
}
if(Size > Handle -> Length)
Count = Handle -> Length;
else
Count = Size;
CopyMem(Handle -> Index,Buffer,Count);
BytesRead += Count;
Size -= Count;
Buffer += Count;
Handle -> Index += Count;
Handle -> Length -= Count;
}
return(BytesRead);
}
STATIC LONG __regargs
BufferSeek(struct BufferHandle *Handle,LONG Size)
{
LONG BytesRead = 0,Count;
while(Size)
{
if(!Handle -> Length)
{
if(BufferFill(Handle) < 1)
return(BytesRead);
}
if(Size > Handle -> Length)
Count = Handle -> Length;
else
Count = Size;
BytesRead += Count;
Size -= Count;
Handle -> Index += Count;
Handle -> Length -= Count;
}
return(BytesRead);
}
STATIC VOID __regargs
BufferClose(struct BufferHandle *Handle)
{
CloseIFF(Handle -> Handle);
if(Handle -> FromClip)
CloseClipboard((struct ClipboardHandle *)Handle -> Handle -> iff_Stream);
else
CloseAsync((struct AsyncFile *)Handle -> Handle -> iff_Stream);
FreeIFF(Handle -> Handle);
FreeVecPooled(Handle);
}
STATIC struct BufferHandle * __regargs
BufferOpen(STRPTR Name)
{
struct BufferHandle *Handle;
LONG Error;
if(Handle = (struct BufferHandle *)AllocVecPooled(sizeof(struct BufferHandle),MEMF_ANY | MEMF_CLEAR))
{
if(Handle -> Handle = AllocIFF())
{
LONG ClipID;
if(GetClipID(Name,&ClipID))
{
if(Handle -> Handle -> iff_Stream = (ULONG)OpenClipboard(ClipID))
{
InitIFFasClip(Handle -> Handle);
if(!(Error = OpenIFF(Handle -> Handle,IFFF_READ)))
{
Handle -> Length = 0;
Handle -> FromClip = TRUE;
return(Handle);
}
CloseClipboard((struct ClipboardHandle *)Handle -> Handle -> iff_Stream);
}
else
Error = IoErr();
}
else
{
if(Handle -> Handle -> iff_Stream = (ULONG)OpenAsync(Name,MODE_READ,2 * CACHE_SIZE))
{
InitIFF(Handle -> Handle,IFFF_FSEEK | IFFF_RSEEK,&StreamHook);
if(!(Error = OpenIFF(Handle -> Handle,IFFF_READ)))
{
Handle -> Length = 0;
Handle -> FromClip = FALSE;
return(Handle);
}
CloseAsync((struct AsyncFile *)Handle -> Handle -> iff_Stream);
}
else
Error = IoErr();
}
FreeIFF(Handle -> Handle);
}
else
Error = ERROR_NO_FREE_STORE;
FreeVecPooled(Handle);
}
else
Error = ERROR_NO_FREE_STORE;
if(Error)
SetIoErr(Error);
return(NULL);
}
STATIC struct GreyImage * __regargs
CreateImage(LONG Width,LONG Height)
{
struct GreyImage *Image;
if(Image = (struct GreyImage *)AllocVecPooled(sizeof(struct GreyImage) + sizeof(UBYTE *) * Height,MEMF_ANY | MEMF_CLEAR))
{
LONG Size = (Width < 16384 ? 16384 : Width);
Image -> Width = Width;
Image -> Height = Height;
Image -> Lines = (UBYTE **)(Image + 1);
if(!(Image -> Pool = LibCreatePool(MEMF_ANY,Size,Size)))
{
FreeVecPooled(Image);
return(NULL);
}
}
return(Image);
}
STATIC UBYTE * __regargs
AddLine(struct GreyImage *Image)
{
if(Image -> Index < Image -> Height)
{
UBYTE *Line;
if(Line = (UBYTE *)LibAllocPooled(Image -> Pool,(Image -> Width + 3) & ~3))
Image -> Lines[Image -> Index++] = Line;
return(Line);
}
else
return(NULL);
}
STATIC struct BufferHandle * __regargs
ReadImageHeader(STRPTR Name,BOOL PatchColours,struct PictureInfo *PictureInfo)
{
struct BufferHandle *Handle;
*PictureInfo -> Error = 0;
if(Handle = BufferOpen(Name))
{
STATIC LONG Stops[] =
{
ID_ILBM,ID_BMHD,
ID_ILBM,ID_CMAP,
ID_ILBM,ID_CAMG,
ID_ILBM,ID_CLUT,
ID_ILBM,ID_BODY
};
LONG Error;
if(!(Error = StopChunks(Handle -> Handle,Stops,5)))
{
struct ContextNode *Chunk;
BOOL GotBody = FALSE,
Terminated = FALSE;
struct CLUT LocalCLUT;
while(!Terminated && !(Error = ParseIFF(Handle -> Handle,IFFPARSE_SCAN)))
{
Chunk = CurrentChunk(Handle -> Handle);
switch(Chunk -> cn_ID)
{
case ID_BMHD:
if(ReadChunkByte