I have some source code I'm trying to compile on my iBook but I think I'm having a problem because the code contains a 'fcloseall()' and I've read that gcc under OSX doesn't support it. I figure substituting fclose() but I'm not sure on the arguements to use. Would someone take a look and tell me what to use to replace fcloseall() with? fclose(??)
Thanks.
Code:
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "bmp2palm.h"
#undef WINDOWS
#ifdef __GNUCC__
#define STRICMP strcasecmp
#else
#define STRICMP strcasecmp
#endif
#define resourceAttribute 0x0001
FILE *in = NULL;
FILE *out = NULL;
int interactive = true;
UInt8* inBitmap;
UInt8* outBitmap;
void SafeFree( void** p )
{
if ( *p != NULL ) {
free( *p );
*p = NULL;
}
}
void CleanUp( void )
{
SafeFree( ( void** )&inBitmap );
SafeFree( ( void** )&outBitmap );
fcloseall();
}
void msg(char* title, char *s, ...)
{
char out[ 2048 ];
va_list argptr;
if ( ! interactive )
return;
va_start(argptr,s);
vsprintf(out,s,argptr);
va_end(argptr);
#ifdef WINDOWS
MessageBox( NULL, out, title, MB_OK );
#else
fprintf( stderr, "%s\n", out );
#endif
CleanUp();
exit(1);
}
void err(char *s, ...)
{
char out[ 2048 ];
va_list argptr;
va_start(argptr,s);
vsprintf(out,s,argptr);
va_end(argptr);
#ifdef WINDOWS
MessageBox( NULL, out, "Error", MB_OK );
#else
fprintf( stderr, "Fatal error: %s.\n", out );
#endif
CleanUp();
exit(1);
}
FILE *myfopen(char *s,char *m)
{
FILE *f=fopen(s,m);
if(f==NULL) err("Cannot open %s.",s);
return f;
}
int myfgetc(FILE *f)
{
int c=fgetc(f);
if(c==-1) err("Error reading font!");
return c;
}
void* mymalloc( int n )
{
void* p = malloc( n );
if ( p == NULL ) err("Error allocating %ld bytes.", n );
return p;
}
int myfread( void* p, int n, int m, FILE* f )
{
if ( m != fread( p, n, m, f ) )
err("Error reading %d x %d bytes.", n, m );
return m;
}
void myseek(FILE *f, unsigned long x)
{
if(fseek(f,x,SEEK_SET)<0 ||
ftell(f)!=(long)x) err("Error seeking!");
return;
}
UInt32 UInt32LE( UInt32 in )
{
UInt8* p;
UInt32 n;
int i;
p = ( UInt8* )&n;
for ( i = 0 ; i < 4 ; i++ ) {
p[ i ] = in % 256;
in /= 256;
}
return n;
}
UInt32 UInt32BE( UInt32 in )
{
UInt8* p;
UInt32 n;
int i;
p = ( UInt8* )&n;
for ( i = 0 ; i < 4 ; i++ ) {
p[ 3 - i ] = in % 256;
in /= 256;
}
return n;
}
UInt16 UInt16LE( UInt16 in )
{
UInt8* p;
int i;
p = ( UInt8* )∈
return p[ 0 ] + 256 * p[ 1 ];
}
UInt16 UInt16BE( UInt16 in )
{
UInt8* p;
int i;
p = ( UInt8* )∈
return 256 * p[ 0 ] + p[ 1 ];
}
UInt32 UInt32LEP( UInt16* inP )
{
return UInt16LE( inP[ 0 ] ) + 65536 * UInt16LE( inP[ 1 ] );
}
#ifdef WINDOWS
int getname(char *s)
{
int r;
OPENFILENAME ofn;
*s=0;
ZeroMemory(&ofn, sizeof(OPENFILENAME));
ofn.lStructSize = sizeof(OPENFILENAME);
ofn.hwndOwner = NULL;
ofn.lpstrFile = s;
ofn.nMaxFile = MAX_PATH;
ofn.lpstrFilter = "Palm databases\0*.prc;*.pdb\0All files\0*.*\0";
ofn.lpstrTitle = "Select database to compress";
ofn.nFilterIndex = 1;
ofn.lpstrFileTitle = NULL;
ofn.nMaxFileTitle = 0;
ofn.lpstrInitialDir = NULL;
ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;
return GetOpenFileName(&ofn);
}
#endif
static void WrongFormat( void )
{
err("Unsupported input format");
}
static UInt16 Convert888To565( UInt8* c )
{
return ( ( c[ 2 ] >> 3 ) << 11 ) | ( ( c[ 1 ] >> 2 ) << 5 ) | ( c[ 0 ] >> 3 );
}
static void ConvertRow( UInt8* dest, UInt8* src, UInt16 width )
{
int x;
UInt16* dest16;
dest16 = ( void* )dest;
for ( x = 0 ; x < width ; x++ ) {
dest16[ x ] = UInt16LE( Convert888To565( src + x * 3 ) );
}
}
#define SEQUENCE_LIMIT 126
Int16 GetRunLength( UInt16* data, UInt16 cols )
{
UInt16 i;
for ( i = 1 ; i < cols && data[ i ] == data[ 0 ] && i < SEQUENCE_LIMIT ; i++ ) ;
return i;
}
UInt8* PackRow( UInt8* out, UInt16* in, UInt16 cols )
{
UInt16 x;
UInt16* inEnd;
while ( cols ) {
Int16 count;
count = GetRunLength( in, cols );
if ( 2 <= count ) {
*out++ = ( UInt8 )( 1 - count );
*out++ = *( UInt8* )in;
*out++ = *( 1 + ( UInt8* )in );
in += count;
cols -= count;
}
else {
UInt16 i;
for ( i = 1 ; i < cols && i < SEQUENCE_LIMIT && ( i + 1 == cols || in[ i ] != in[ i + 1 ] ) ; i++ );
*out++ = ( UInt8 )( i - 1 );
while ( i-- ) {
*out++ = *( UInt8* )in;
*out++ = *( 1 + ( UInt8* )in );
in++;
cols--;
}
}
}
return out;
}
void* PackData( UInt16* inData, UInt16 cols, UInt16 rows, UInt32* newSizeP )
{
UInt8* outData;
UInt8* p;
UInt16 row;
/* Implement packbits compression */
//return NULL;
outData = mymalloc( rows * cols * ( sizeof( UInt16 ) + 1 ) + 4 );
if ( outData == NULL )
return NULL;
p = outData + 4;
for ( row = 0 ; row < rows ; row++ ) {
p = PackRow( p, inData + row * cols, cols );
}
if ( rows * cols * sizeof( UInt16 ) <= p - outData ) {
free( outData );
return NULL;
}
*newSizeP = ( p - outData );
*( UInt32* )outData = UInt32BE( *newSizeP - 4 );
return outData;
}
UInt8* ScanLineCompressRow( Boolean firstLine, UInt8* out, UInt8* in, UInt16 rowBytes )
{
UInt8* startOut;
UInt8* endIn;
static UInt8* prevLine;
UInt8* startIn;
startIn = in;
startOut = out;
endIn = in + rowBytes;
while ( in < endIn ) {
UInt8* octupleMarker;
UInt8 mask;
octupleMarker = out;
*octupleMarker = 0;
out++;
for ( mask = 0x80 ; mask != 0 && in < endIn ; mask >>= 1 ) {
if ( firstLine || *in != *prevLine ) {
*octupleMarker |= mask;
*out++ = *in;
}
in++;
prevLine++;
}
}
prevLine = startIn;
return out;
}
void* ScanLineData( UInt8* inData, UInt16 byteWidth, UInt16 rows, UInt32* newSizeP )
{
UInt8* outData;
UInt8* p;
UInt16 row;
/* Implement scanline compression */
outData = malloc( rows * byteWidth * 2 + 4 );
if ( outData == NULL )
return NULL;
p = outData + 4;
for ( row = 0 ; row < rows ; row++ ) {
p = ScanLineCompressRow( row == 0, p, inData + row * byteWidth, byteWidth );
}
if ( rows * byteWidth <= p - outData + 4 ) {
free( outData );
return NULL;
}
*newSizeP = ( p - outData );
*( UInt32* )outData = UInt32BE( *newSizeP - 4 );
return outData;
}
void* CompressData( void* bitmap, UInt16 cols, UInt16 rows, UInt32* newSizeP, UInt8* type )
{
void* scanLine;
UInt32 scanLineSize;
void* pack;
UInt32 packSize;
pack = PackData( bitmap, cols, rows, &packSize );
scanLine = ScanLineData( bitmap, cols * sizeof( UInt16 ), rows, &scanLineSize );
if ( pack == NULL ) {
if ( scanLine != NULL ) {
*type = palmBitmapCompressionTypeScanLine;
*newSizeP = scanLineSize;
}
return scanLine;
}
if ( scanLine == NULL ) {
if ( pack != NULL ) {
*type = palmBitmapCompressionTypePackBits;
*newSizeP = packSize;
}
return pack;
}
if ( packSize < scanLineSize ) {
free( scanLine );
*type = palmBitmapCompressionTypePackBits;
*newSizeP = packSize;
return pack;
}
else {
free( pack );
*type = palmBitmapCompressionTypeScanLine;
*newSizeP = scanLineSize;
return scanLine;
}
}
int main(int argc, char **argv)
{
int i;
int x;
int y;
UInt32 pos,pos2,pos3;
UInt32 inLength;
UInt32 outLength;
UInt16 width;
UInt16 height;
UInt16 outHeight;
UInt32 inRowLen;
UInt16 outRowLen;
void* compressedBitmap;
UInt32 compressedSize;
int yStart;
int yEnd;
BMPHeaderType inH;
PalmBitmapTypeV3 outH;
interactive = 1;
inBitmap = NULL;
outBitmap = NULL;
if ( argc != 3 && argc != 5 ) {
msg("usage", "bmp2abmp inFileName outFileName [y0 height].\n");
return 1;
}
in = myfopen( argv[ 1 ], "rb" );
myfread( &inH, sizeof( inH ), 1, in );
if ( inH.magic != ( UInt8 )'B' + 256 * ( UInt8 )'M' ||
UInt16LE( inH.bitsPerPixel ) != 24 ||
UInt32LEP( inH.compressionType ) != 0 ||
UInt16LE( inH.planes ) != 1 ) {
WrongFormat();
}
width = UInt32LEP( inH.width );
height = UInt32LEP( inH.height );
if ( argc == 3 ) {
yStart = 0;
yEnd = height - 1;
}
else {
yStart = atoi( argv[ 3 ] );
yEnd = yStart + atoi( argv[ 4 ] ) - 1;
}
outHeight = yEnd - yStart + 1;
outH.width = UInt16BE( width );
outH.height = UInt16BE( outHeight );
outRowLen = width * 2;
outH.rowBytes = UInt16BE( outRowLen );
outH.flags = 0; // directColorLE;
outH.reserved0 = 0;
outH.pixelSize = 16;
outH.version = 3;
outH.size = sizeof( PalmBitmapTypeV3 );
outH.pixelFormat = palmPixelFormat565LE;
outH.unused = 0;
outH.compressionType = 0;
outH.density = UInt16BE( 144 );
outH.transparentValue = 0;
outH.nextBitmapOffset = 0;
/* Ensure inRowLen is 0 mod 4. */
inRowLen = width * 3 + width % 4;
inBitmap = mymalloc( inRowLen * height );
outBitmap = mymalloc( outRowLen * outHeight );
myseek( in, UInt32LEP( inH.offset ) );
myfread( inBitmap, 1, inRowLen * height, in );
out = myfopen( argv[ 2 ], "wb" );
for ( y = yStart ; y <= yEnd ; y++ ) {
int x;
ConvertRow( outBitmap + outRowLen * ( y - yStart ),
inBitmap + inRowLen * ( height - 1 - y ), width );
}
compressedBitmap = CompressData( ( void* )outBitmap, width, outHeight, &compressedSize,
&( outH.compressionType ) );
if ( compressedBitmap != NULL ) {
outH.flags |= compressedBE;
}
/*
{ int i; for ( i = 0 ; i < 8 ; i++ ) fputc( 0, out );
fputc( 0xFF, out );
fputc( 0x81, out );
for ( i = 0 ; i < 6 ; i++ ) fputc( 0, out ); }
*/
fwrite( &outH, 1, sizeof( outH ), out );
if ( compressedBitmap != NULL ) {
fwrite( compressedBitmap, 1, compressedSize, out );
free( compressedBitmap );
}
else {
fwrite( outBitmap, 1, outRowLen * outHeight, out );
}
CleanUp();
return 0;
}