SBSPSS/Utils/Libs/GLib/Ilbm.cpp
2000-12-04 14:13:40 +00:00

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 */