447 lines
8.1 KiB
C++
447 lines
8.1 KiB
C++
/*=========================================================================
|
|
|
|
ILBM.HPP
|
|
|
|
Author: Gary Liddon @ Watford
|
|
Created: 30/03/92
|
|
Purpose: Crappy ilbm reader
|
|
|
|
Copyright (c) 1992 - 1997 Gary Liddon
|
|
|
|
===========================================================================*/
|
|
|
|
/* -----------------------------------------------------------
|
|
Includes
|
|
-------- */
|
|
|
|
/* Std Lib
|
|
------- */
|
|
#include <string.h>
|
|
|
|
/* Glib
|
|
---- */
|
|
#include "gutils.h"
|
|
|
|
/* Local
|
|
----- */
|
|
#include "ilbm.hpp"
|
|
#include "iff.hpp"
|
|
|
|
/* Graphics
|
|
-------- */
|
|
|
|
/*----------------------------------------------------------------------
|
|
Tyepdefs && Defines
|
|
------------------- */
|
|
|
|
/*----------------------------------------------------------------------
|
|
Structure defintions
|
|
-------------------- */
|
|
|
|
/*----------------------------------------------------------------------
|
|
Positional Vars
|
|
--------------- */
|
|
|
|
/*----------------------------------------------------------------------
|
|
Function Prototypes
|
|
------------------- */
|
|
|
|
/*----------------------------------------------------------------------
|
|
Vars
|
|
---- */
|
|
|
|
/*----------------------------------------------------------------------
|
|
Data
|
|
---- */
|
|
|
|
/*----------------------------------------------------------------------
|
|
Function:
|
|
Purpose:
|
|
Params:
|
|
Returns:
|
|
---------------------------------------------------------------------- */
|
|
nilbm::nilbm(char const *name) : niff(name,ILBM)
|
|
{
|
|
if (err_no==NOT_FORM)
|
|
{
|
|
if (open(name,PBM))
|
|
{
|
|
err_no=NO_ERROR;
|
|
}
|
|
}
|
|
|
|
if (!err_no)
|
|
starta();
|
|
}
|
|
|
|
/*----------------------------------------------------------------------
|
|
Function:
|
|
Purpose:
|
|
Params:
|
|
Returns:
|
|
---------------------------------------------------------------------- */
|
|
nilbm::nilbm(FILE *fp) : niff(fp,ILBM)
|
|
{
|
|
if (err_no==PASSED_ERR)
|
|
if (mount_form(PBM))
|
|
err_no=NO_ERROR;
|
|
|
|
starta();
|
|
}
|
|
|
|
/*----------------------------------------------------------------------
|
|
Function:
|
|
Purpose:
|
|
Params:
|
|
Returns:
|
|
---------------------------------------------------------------------- */
|
|
nilbm::~nilbm()
|
|
{
|
|
DiscardCmap();
|
|
DiscardBmap();
|
|
}
|
|
|
|
|
|
/*----------------------------------------------------------------------
|
|
Function:
|
|
Purpose:
|
|
Params:
|
|
Returns:
|
|
---------------------------------------------------------------------- */
|
|
void nilbm::starta()
|
|
{
|
|
cmap=NULL;
|
|
Bmap=NULL;
|
|
|
|
if (err_no)
|
|
return;
|
|
|
|
if ((!file_opened) && (!form_mounted))
|
|
return;
|
|
|
|
GetBmHeadFromDisk();
|
|
|
|
|
|
if (goto_hunk(CMAP))
|
|
cmap=get_hunk();
|
|
|
|
Bmap=GetBmapFromDisk();
|
|
}
|
|
|
|
/*----------------------------------------------------------------------
|
|
Function:
|
|
Purpose:
|
|
Params:
|
|
Returns:
|
|
---------------------------------------------------------------------- */
|
|
U8 *nilbm::TakeBmap()
|
|
{
|
|
U8* Retp=Bmap;
|
|
Bmap=NULL;
|
|
return Retp;
|
|
}
|
|
|
|
/*----------------------------------------------------------------------
|
|
Function:
|
|
Purpose:
|
|
Params:
|
|
Returns:
|
|
---------------------------------------------------------------------- */
|
|
U8 *nilbm::TakeCmap()
|
|
{
|
|
U8* Retp=cmap;
|
|
cmap=NULL;
|
|
return Retp;
|
|
}
|
|
|
|
|
|
/*----------------------------------------------------------------------
|
|
Function:
|
|
Purpose:
|
|
Params:
|
|
Returns:
|
|
---------------------------------------------------------------------- */
|
|
void nilbm::DiscardBmap()
|
|
{
|
|
if (Bmap)
|
|
delete Bmap;
|
|
|
|
Bmap=NULL;
|
|
}
|
|
|
|
/*----------------------------------------------------------------------
|
|
Function:
|
|
Purpose:
|
|
Params:
|
|
Returns:
|
|
---------------------------------------------------------------------- */
|
|
void nilbm::DiscardCmap()
|
|
{
|
|
if (cmap)
|
|
delete cmap;
|
|
|
|
cmap=NULL;
|
|
}
|
|
|
|
/*----------------------------------------------------------------------
|
|
Function:
|
|
Purpose:
|
|
Params:
|
|
Returns:
|
|
---------------------------------------------------------------------- */
|
|
void nilbm::GetBmHeadFromDisk()
|
|
{
|
|
if (goto_hunk(BMHD))
|
|
{
|
|
GetIntelLong();
|
|
GetIntelLong();
|
|
|
|
w=GetIntelWord();
|
|
h=GetIntelWord();
|
|
|
|
GetIntelWord();
|
|
GetIntelWord();
|
|
|
|
planes=fgetc(fp);
|
|
|
|
fgetc(fp);
|
|
comp=fgetc(fp);
|
|
|
|
rh = h;
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/*----------------------------------------------------------------------
|
|
Function:
|
|
Purpose:
|
|
Params:
|
|
Returns:
|
|
---------------------------------------------------------------------- */
|
|
U8 *nilbm::GetBmapFromDisk()
|
|
{
|
|
U8 *buffa=NULL;
|
|
U8 *Ptr;
|
|
|
|
if (file_opened)
|
|
{
|
|
if (goto_hunk(BODY))
|
|
{
|
|
long temp;
|
|
|
|
fread(&temp,1,sizeof(ULONG),fp);
|
|
fread(&temp,1,sizeof(ULONG),fp);
|
|
|
|
if (!(buffa=new U8[w*h]))
|
|
Error(ERR_FATAL,"Allocating ILBM body (%ld)",(long)w*(long)h);
|
|
|
|
U8 *line_buffer;
|
|
|
|
int NormWidth=((w+7)&(0xfff8));
|
|
|
|
int bwidth=NormWidth/8;
|
|
|
|
if (!(line_buffer=new U8[NormWidth*4])) //MA increased for safety incase of bad encoding
|
|
return NULL;
|
|
else
|
|
{
|
|
int z,dest; // Init source count
|
|
|
|
for (int line=0;line<(h);line++)
|
|
{
|
|
dest=0; // Destination count
|
|
|
|
memset(line_buffer,0,NormWidth); // Clear out buffer
|
|
|
|
if (form_name==PBM)
|
|
{
|
|
if (comp)
|
|
{
|
|
dest=0;
|
|
|
|
while (dest < w)
|
|
{
|
|
s8 val = fgetc(fp);
|
|
|
|
if (val<0)
|
|
{
|
|
val=(0-val)+1;
|
|
U8 ch=fgetc(fp);
|
|
|
|
while (val--)
|
|
{
|
|
line_buffer[dest]=ch;
|
|
dest++;
|
|
}
|
|
}
|
|
else if (val>=0)
|
|
{
|
|
val++;
|
|
|
|
while (val--)
|
|
{
|
|
line_buffer[dest]=fgetc(fp);
|
|
dest++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
int WidthToRead = GU_AlignVal(w, 2);
|
|
fread(line_buffer,WidthToRead,1,fp);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for (int p=0;p<planes;p++)
|
|
{
|
|
dest=0;
|
|
|
|
if (comp)
|
|
{
|
|
while (dest < bwidth)
|
|
{
|
|
S8 val = fgetc(fp);
|
|
Ptr=&line_buffer[dest*8];
|
|
|
|
if (val<0)
|
|
{
|
|
val=(0-val)+1;
|
|
U8 ch=fgetc(fp);
|
|
|
|
while (val--)
|
|
{
|
|
|
|
for (z=7;z>=0;z--)
|
|
*Ptr++ |= ((ch>>(z))&1)<<p;
|
|
|
|
dest++;
|
|
}
|
|
}
|
|
else if (val>=0)
|
|
{
|
|
val++;
|
|
|
|
while (val--)
|
|
{
|
|
U8 ch=fgetc(fp);
|
|
|
|
for (z=7;z>=0;z--)
|
|
*Ptr++ |= ((ch>>(z))&1)<<p;
|
|
|
|
dest++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for (int x=0;x<bwidth;x++)
|
|
{
|
|
Ptr=&line_buffer[dest*8];
|
|
|
|
U8 ch=fgetc(fp);
|
|
for (z=7;z>=0;z--)
|
|
*Ptr++ |= ((ch>>(z))&1)<<p;
|
|
dest++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
memcpy(&buffa[line*w],line_buffer,w);
|
|
}
|
|
}
|
|
delete line_buffer;
|
|
}
|
|
}
|
|
return buffa;
|
|
}
|
|
|
|
/*----------------------------------------------------------------------
|
|
Function:
|
|
Purpose:
|
|
Params:
|
|
Returns:
|
|
---------------------------------------------------------------------- */
|
|
void nilbm::SavePbm(char *Name,U8 *Palette,U8 *Body,int W,int H)
|
|
{
|
|
if (Palette && Body)
|
|
{
|
|
IFF_FILE outfile;
|
|
|
|
if (outfile.write(Name) != 0)
|
|
{
|
|
int i, j;
|
|
|
|
outfile.form("PBM ");
|
|
|
|
outfile.chunk("BMHD");
|
|
outfile.writeword(W);
|
|
outfile.writeword(H);
|
|
outfile.writeword(0); // xpos
|
|
outfile.writeword(0); // ypos
|
|
outfile.writechar(8); // num-planes
|
|
outfile.writechar(mskNone); // masking
|
|
outfile.writechar(cmpNone); // compression
|
|
outfile.writechar(0); // Pad byte
|
|
outfile.writeword(0); // Transparent colour
|
|
outfile.writechar(1); // xAspect
|
|
outfile.writechar(1); // yAspect
|
|
outfile.writeword(320);
|
|
outfile.writeword(200);
|
|
outfile.endchunk();
|
|
|
|
if (256)
|
|
{
|
|
outfile.chunk("CMAP");
|
|
for (i = 0; i < 3*256; i++)
|
|
outfile.writechar(Palette[i]);
|
|
|
|
outfile.endchunk();
|
|
}
|
|
|
|
U8 *ptr;
|
|
|
|
outfile.chunk("BODY");
|
|
|
|
for (i = 0; i < H; i++)
|
|
{
|
|
// Save out a planar scanline
|
|
ptr = &Body[(long) i * (long) W];
|
|
|
|
j = W;
|
|
while (j--)
|
|
outfile.writechar(*ptr++);
|
|
|
|
if (W&1)
|
|
{
|
|
int l = W&1;
|
|
for (int k=0; k<l; k++)
|
|
outfile.writechar(0xfe);
|
|
}
|
|
}
|
|
|
|
outfile.endchunk();
|
|
|
|
outfile.endform();
|
|
outfile.close();
|
|
}
|
|
else
|
|
Error(ERR_FATAL,"Error trying to write %s",Name);
|
|
}
|
|
else
|
|
Error(ERR_FATAL,"Image not defined so can't write %s",Name);
|
|
|
|
}
|
|
|
|
/*===========================================================================
|
|
end */
|
|
|
|
|
|
|
|
|