/*----------------------------------------------------------------------* rim.c Version 2.0 - © Copyright 1990 Jaba Development Author : Jan van den Baard Purpose : reading routines for IFF ILBM images and ColorMaps *----------------------------------------------------------------------*/ extern struct ge_prefs prefs; extern struct Screen *MainScreen; extern struct MemoryChain Memory; /* * check to see if there are bit-planes that doesn't contain data */ static BOOL check(data,size) UBYTE *data; ULONG size; { register UBYTE *pointer; register UCOUNT counter; pointer = data; for(counter=0;counterWidth,image->Height); data = (UBYTE *)image->ImageData; for(counter = 0; counter < image->Depth; counter++) { planes[counter] = (UBYTE *)(data + (counter * plane_size)); if(check(planes[counter],plane_size)) depth++; } if(depth == image->Depth) return; if(NOT(data1 = (UBYTE *) AllocMem((ULONG)depth * plane_size,MEMF_CHIP+MEMF_CLEAR))) return; for(counter = 0; counter < image->Depth; counter++) { if(check(planes[counter],plane_size)) CopyMem((char *)planes[counter],(char *)(data1+(ptc++ * plane_size)),plane_size); } image->PlanePick = NULL; for(counter = 0; counter < depth; counter++ ) image->PlanePick |= (1 << counter); FreeMem(data,(plane_size * image->Depth)); image->Depth = depth; image->ImageData = (USHORT *)data1; } /* * check to see if the file opened is an IFF ILBM file */ static BOOL CheckIFF(file) BPTR file; { struct FORMChunk fchunk; char *str = NULL; if(Read(file,(char *)&fchunk,sizeof(struct FORMChunk)) <= 0) str = "Error during Image Read !"; else if(fchunk.fc_Type != 'FORM') str = "File is not an IFF FORM !"; else if(fchunk.fc_SubType != 'ILBM') str = "IFF FORM is not an ILBM !"; if(str) { enable_window(); Error(str); return(FALSE); } return(TRUE); } /* * read the IFF ILBM file into memory and if no errors occur * return the pointer to an image structure containing the image */ struct Image *ReadImage(ilbmname) UBYTE *ilbmname; { struct IFFChunk ichunk; struct BitMapHeader header; BPTR infile = NULL; ULONG length, offset = NULL, unpacked; struct Image *image = NULL; ULONG planes_size,ps; COUNT plane,row; BYTE *s1,i; BYTE *source, *dest, *planedata = NULL, *planes[8], byte, byte1; BOOL GotBODY = FALSE; char *str; buisy(); if(NOT(image = (struct Image *)Alloc(&Memory,(ULONG)sizeof(struct Image)))) { str = "Out of memory !"; goto Err; } if(NOT(infile = Open((char *)ilbmname,MODE_OLDFILE))) { str = "Can't open IFF file !"; goto Err; } if(NOT CheckIFF(infile)) { FreeItem(&Memory,image,(long)sizeof(struct Image)); Close(infile); return(NULL); } while(GotBODY == FALSE) { if(Read(infile,(char *)&ichunk,sizeof(struct IFFChunk)) <= 0) { str = "Error during Image Read !"; } length = ichunk.ic_Length; if(length & 1) length++; switch(ichunk.ic_Type) { case 'BMHD': if(Read(infile,(char *)&header,length) <= 0) { str = "Error during Image Read !"; goto Err; } image->Width = header.w; image->Height = header.h; image->Depth = header.nPlanes; for(i=0;iDepth;i++) image->PlanePick += (1 << i); image->PlaneOnOff = 0x00; ps = RASSIZE(image->Width,image->Height); planes_size = ps * image->Depth; break; case 'BODY': GotBODY = TRUE; if(NOT(planedata = (BYTE *)AllocMem(planes_size,MEMF_CHIP+MEMF_CLEAR))) { str = "Out of CHIP memory !"; goto Err; } for(i=0;iDepth;i++) planes[i] = (BYTE *)(planedata + (i * ps)); if(header.compression == 0) { for(row=0;rowHeight;row++) { for(plane=0;planeDepth;plane++) { if(Read(infile,(char *)planes[plane]+offset, bpr(image->Width)) <= 0) { str = "Error during Image Read !"; goto Err; } } offset += bpr(image->Width); } } else if(header.compression == 1) { if(NOT(s1 = source = (BYTE *)AllocMem(length,MEMF_PUBLIC+MEMF_CLEAR))) { str = "Out of memory !"; goto Err; } if(Read(infile,(char *)source,length) <= 0) { FreeMem(source,length); str = "Error during Image Read !"; goto Err; } for(row=0;rowHeight;row++) { for(plane=0;planeDepth;plane++) { dest = (BYTE *)planes[plane]+offset; unpacked = bpr(image->Width); while(unpacked > 0) { byte = *source++; if(byte == 128) {} else if(byte > 0) { byte += 1; unpacked -= byte; while(--byte >= 0) *dest++ = *source++; } else { byte = -byte + 1; unpacked -= byte; byte1 = *source++; while(--byte >= 0) *dest++ = byte1; } } } offset += bpr(image->Width); } FreeMem(s1,length); } else { str = "Unknown Image compression !"; goto Err; } break; default: Seek(infile,length,OFFSET_CURRENT); break; } } image->ImageData = (USHORT *)planedata; if(prefs.skip_zero_planes) skip_zero_planes(image); Close(infile); ok(); return(image); Err: enable_window(); Error(str); if(infile) Close(infile); if(image) FreeItem(&Memory,image,(long)sizeof(struct Image)); if(planedata) FreeMem(planedata,planes_size); return(NULL); } /* * read and set the CMAP of an IFF ILBM file */ VOID ReadCMAP(ilbmname) UBYTE *ilbmname; { struct IFFChunk ichunk; BPTR infile; LONG length; register COUNT reg,i=0; BOOL GotIt = FALSE, GotCMAP = FALSE; UBYTE colors[96],count; buisy(); if(NOT(infile = Open((char *)ilbmname,MODE_OLDFILE))) { enable_window(); Error("Can't open IFF file !"); return; } if(NOT CheckIFF(infile)) { Close(infile); return; } while(GotIt == FALSE) { if(Read(infile,(char *)&ichunk,sizeof(struct IFFChunk)) <= 0) { enable_window(); Error("Error during CMAP read !"); Close(infile); return; } length = ichunk.ic_Length; if(length & 1) length++; switch(ichunk.ic_Type) { case 'CMAP': GotCMAP = TRUE; if(Read(infile,(char *)&colors,length) <= 0) { enable_window(); Error("Error during CMAP read !"); break; } count = (1 << MainScreen->BitMap.Depth); for(reg=0;regViewPort, reg, ((colors[i] >> 4) & 0x0f), ((colors[i+1] >> 4) & 0x0f), ((colors[i+2] >> 4) & 0x0f)); } break; case 'BODY': GotIt = TRUE; break; default: Seek(infile,length,OFFSET_CURRENT); break; } } Close(infile); if(GotCMAP == FALSE) { enable_window(); Error("No CMAP chunk found !"); } ok(); return; }