Difference between revisions of "User:Steven/flip frame decode.c"
Jump to navigation
Jump to search
m (Steven/flip frame decode.c moved to User:Steven/flip frame decode.c: Lets try this again - Wiki NOOB ALERT XD) |
(GCC gave me errors which were caused by "wise" M$ thinking that typecast isn't neccessary :() |
||
Line 99: | Line 99: | ||
{ | { | ||
printf( "Magic Number : %c%c%c%c\n", ptr->magic[0], ptr->magic[1], ptr->magic[2], ptr->magic[3] ); | printf( "Magic Number : %c%c%c%c\n", ptr->magic[0], ptr->magic[1], ptr->magic[2], ptr->magic[3] ); | ||
− | printf( "File Size : %d (%08X)\n", ptr->fileSize, ptr->fileSize ); | + | printf( "File Size : %d (%08X)\n", (int)ptr->fileSize, (unsigned int)ptr->fileSize ); |
− | printf( "Audio offset : %d (%08X)\n", ptr->audioOffset, ptr->audioOffset ); | + | printf( "Audio offset : %d (%08X)\n", (int)ptr->audioOffset, (unsigned int)ptr->audioOffset ); |
printf( "# Frames : %d\n", ptr->numberOfFrames ); | printf( "# Frames : %d\n", ptr->numberOfFrames ); | ||
printf( "Unknown : 0x%04X\n", ptr->unk0 ); | printf( "Unknown : 0x%04X\n", ptr->unk0 ); | ||
Line 237: | Line 237: | ||
if( buf == NULL ) | if( buf == NULL ) | ||
{ | { | ||
− | printf( "Error unable to allocate buffer for frame %d\n", frmBuf ); | + | printf( "Error unable to allocate buffer for frame %d\n", (int)frmBuf ); |
return; | return; | ||
} | } | ||
Line 243: | Line 243: | ||
frmOffset = getFrameOffset( frmBuf, 1 ); | frmOffset = getFrameOffset( frmBuf, 1 ); | ||
− | printf( "Frame #%d offset %08X\n", frmNum, frmOffset ); | + | printf( "Frame #%d offset %08X\n", frmNum, (unsigned int)frmOffset ); |
colPaper = frmBuf[ frmOffset ] & 0x01; | colPaper = frmBuf[ frmOffset ] & 0x01; | ||
Line 294: | Line 294: | ||
case 0: // Skip this line | case 0: // Skip this line | ||
byteUse = 0; | byteUse = 0; | ||
− | printf( "Line %3d(%04X), Layer 1, Skip Frame [%08X]\toffset %08X\n", lnePos, lnePos, byteUse, frmOffset + 0x6a0 ); | + | printf( "Line %3d(%04X), Layer 1, Skip Frame [%08X]\toffset %08X\n", lnePos, lnePos, (unsigned int)byteUse, (unsigned int)frmOffset + 0x6a0 ); |
break; | break; | ||
case 1: // Coded | case 1: // Coded | ||
byteUse = getu32inv( &frmBuf[ frmOffset ] ); | byteUse = getu32inv( &frmBuf[ frmOffset ] ); | ||
− | printf( "Line %3d(%04X), Layer 1, Coded [%08X]\toffset %08X\n", lnePos, lnePos, byteUse, frmOffset + 0x6a0 ); | + | printf( "Line %3d(%04X), Layer 1, Coded [%08X]\toffset %08X\n", lnePos, lnePos, (unsigned int)byteUse, (unsigned int)frmOffset + 0x6a0 ); |
frmOffset += 4; | frmOffset += 4; | ||
frmOffset += decodeLine( &buf[ lnePos << 8 ], &frmBuf[ frmOffset ], byteUse, outFrameG[ 0 ], outFrameG[ colLayer1 ], 0 ); | frmOffset += decodeLine( &buf[ lnePos << 8 ], &frmBuf[ frmOffset ], byteUse, outFrameG[ 0 ], outFrameG[ colLayer1 ], 0 ); | ||
Line 304: | Line 304: | ||
case 2: // Inv Coded | case 2: // Inv Coded | ||
byteUse = getu32inv( &frmBuf[ frmOffset ] ); | byteUse = getu32inv( &frmBuf[ frmOffset ] ); | ||
− | printf( "Line %3d(%04X), Layer 1, Inv Coded [%08X]\toffset %08X\n", lnePos, lnePos, byteUse, frmOffset + 0x6a0 ); | + | printf( "Line %3d(%04X), Layer 1, Inv Coded [%08X]\toffset %08X\n", lnePos, lnePos, (unsigned int)byteUse, (unsigned int)frmOffset + 0x6a0 ); |
frmOffset += 4; | frmOffset += 4; | ||
frmOffset += decodeLine( &buf[ lnePos << 8 ], &frmBuf[ frmOffset ], byteUse, outFrameG[ colLayer1 ], outFrameG[ 0 ], 1 ); | frmOffset += decodeLine( &buf[ lnePos << 8 ], &frmBuf[ frmOffset ], byteUse, outFrameG[ colLayer1 ], outFrameG[ 0 ], 1 ); | ||
Line 310: | Line 310: | ||
case 3: // Full Line | case 3: // Full Line | ||
byteUse = 0xFFFFFFFF; | byteUse = 0xFFFFFFFF; | ||
− | printf( "Line %3d(%04X), Layer 1, Full Frame [%08X]\toffset %08X\n", lnePos, lnePos, byteUse, frmOffset + 0x6a0 ); | + | printf( "Line %3d(%04X), Layer 1, Full Frame [%08X]\toffset %08X\n", lnePos, lnePos, (unsigned int)byteUse, (unsigned int)frmOffset + 0x6a0 ); |
frmOffset += decodeLine( &buf[ lnePos << 8 ], &frmBuf[ frmOffset ], byteUse, outFrameG[ 0 ], outFrameG[ colLayer1 ], 0 ); | frmOffset += decodeLine( &buf[ lnePos << 8 ], &frmBuf[ frmOffset ], byteUse, outFrameG[ 0 ], outFrameG[ colLayer1 ], 0 ); | ||
break; | break; |
Latest revision as of 20:18, 15 February 2010
Please note that there is very little comments and this application just outputs to the text console at the moment, but the code used here can be expanded to produce any other image file formats you wanted. I'm still working on the sound format and as such there is no functions for the sound yet.
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <string.h>
// Disable MS VC's "unsecure / depricated" code warning
#pragma warning( disable : 4996 )
// setup some file types for set sizes
typedef signed char s8;
typedef signed short s16;
typedef signed long s32;
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned long u32;
typedef struct PPM_HEADER
{
u8 magic[4];
u32 fileSize;
u32 audioOffset;
u16 numberOfFrames;
u16 unk0;
u16 flags;
u16 previewFrameNumber;
u16 originalAuthorName[11];
u16 authorName[11];
u16 userName[11];
u8 originalAuthorID[8];
u8 editAuthorID[8];
u8 originalFileName[18];
u8 fileName[18];
u8 authorID[8];
u8 unk1[8];
u8 unk2[6];
u8 previewBitmap[1536];
} ppmHeader;
int flength(FILE *f)
{
int pos,end;
pos = ftell (f);
fseek (f, 0, SEEK_END);
end = ftell (f);
fseek (f, pos, SEEK_SET);
return end;
}
char *idFromStr( u8 is[8] )
{
static char retVal[32];
int i;
memset( retVal, 0, 32 );
for( i = 7; i >= 0; i -- )
sprintf( retVal, "%s%02X", retVal, ( is[ i ] & 0xFF ) );
return retVal;
}
char *filenameFromStr( u8 fn[18] )
{
static char retVal[64];
int i;
memset( retVal, 0, 32 );
for( i = 0; i < 3; i ++ )
sprintf( retVal, "%s%02X", retVal, ( fn[ i ] & 0xFF ) );
strcat( retVal, "_" );
for( i = 3; i < 16; i ++ )
sprintf( retVal, "%s%c", retVal, ( fn[ i ] & 0xFF ) );
sprintf( retVal, "%s_%03d", retVal, ( fn[ 16 ] & 0xFF ) + ( ( fn[ 17 ] & 0xFF ) << 8 ) );
return retVal;
}
char *hexFromStr( u8 is[8], int len )
{
static char retVal[256];
int i;
memset( retVal, 0, 256 );
for( i = 0; i < len; i ++ )
sprintf( retVal, "%s%02X ", retVal, ( is[ i ] & 0xFF ) );
return retVal;
}
void printHeaderInfo( ppmHeader *ptr )
{
printf( "Magic Number : %c%c%c%c\n", ptr->magic[0], ptr->magic[1], ptr->magic[2], ptr->magic[3] );
printf( "File Size : %d (%08X)\n", (int)ptr->fileSize, (unsigned int)ptr->fileSize );
printf( "Audio offset : %d (%08X)\n", (int)ptr->audioOffset, (unsigned int)ptr->audioOffset );
printf( "# Frames : %d\n", ptr->numberOfFrames );
printf( "Unknown : 0x%04X\n", ptr->unk0 );
printf( "Flags? : 0x%04X - 0 = open, 1 = locked\n", ptr->flags );
printf( "Preview Frame # : %d\n", ptr->previewFrameNumber );
printf( "Orig Author : UCS-2 string \n" );
printf( "Author : UCS-2 string \n" );
printf( "Edit Author : UCS-2 string \n" );
printf( "Orig Author ID : %s\n", idFromStr( ptr->originalAuthorID ) );
printf( "Edit Author ID : %s\n", idFromStr( ptr->editAuthorID ) );
printf( "Orig Filename : %s\n", filenameFromStr( ptr->originalFileName ) );
printf( "Curr Filename : %s\n", filenameFromStr( ptr->fileName ) );
printf( "Author ID : %s\n", idFromStr( ptr->authorID ) );
printf( "Unknown 8 bytes : %s\n", hexFromStr( ptr->unk1, 8 ) ) ;
printf( "Unknown 6 bytes : %s\n", hexFromStr( ptr->unk2, 6 ) ) ;
}
static char outPreviewG[] = { ' ', 176, 219, 178, 'r', 'R', 'p', 'X', 'B', 'P', 'b', 'x', 'M', '.', '.', '.' };
static char outFrameG0[] = { 32, 219, 176, 178 };
static char outFrameG1[] = { 219, 32, 176, 178 };
void displayPreviewImage( u8 img[1536] )
{
int x, y, cellOffset;
int xp, xc;
u8 c;
for( y = 0; y < 48; y ++ )
{
cellOffset = ( ( y >> 3 ) * 256 ) + ( ( y & 0x7 ) << 2 );
for( x = 0; x < 64; x ++ )
{
xp = ( x & 7 ) >> 1;
xc = ( ( x >> 3 ) << 5 );
c = img[ cellOffset + xp + xc ];
printf( "%c", outPreviewG[ ( x & 1 ? c >> 4 : c ) & 0xF ] );
}
printf( "\n" );
}
}
u32 getu32( u8 *buf )
{
u32 retVal = 0;
retVal = retVal | ( buf[ 0 ] << 0 );
retVal = retVal | ( buf[ 1 ] << 8 );
retVal = retVal | ( buf[ 2 ] << 16 );
retVal = retVal | ( buf[ 3 ] << 24 );
return retVal;
}
u32 getu32inv( u8 *buf )
{
u32 retVal = 0;
retVal = retVal | ( buf[ 3 ] << 0 );
retVal = retVal | ( buf[ 2 ] << 8 );
retVal = retVal | ( buf[ 1 ] << 16 );
retVal = retVal | ( buf[ 0 ] << 24 );
return retVal;
}
u32 getFrameOffset( u8 *buf, u16 frm )
{
u32 numBytes;
numBytes = getu32( buf );
if( frm > ( numBytes >> 2 ) )
return 0;
return ( getu32( &buf[ 4 + ( frm << 2 ) ] ) + 8 + numBytes );
}
u32 decodeLine( u8 *outB, u8 *inB, u32 useByte, u8 paper, u8 pen, u8 invflag )
{
u32 offset = 0;
u16 x = 0, i;
u8 data;
if( useByte == 0 ) // Set the full line to the current paper colour
memset( outB, paper, 256 );
else // Bytes in this line, read and deal with them
{
while( useByte != 0 )
{
if( ( useByte & 0x80000000 ) == 0x80000000 )
{
// This byte exists...
data = inB[ offset++ ];
for( i = 0; i < 8; i ++ )
{
if( ( data & 0x01 ) == 0x01 )
outB[ x ] = invflag == 0 ? pen : paper;
else
outB[ x ] = invflag == 0 ? paper : pen;
x ++;
data >>= 1;
}
}
else
{
memset( &outB[ x ], paper, 8 );
x += 8;
}
useByte <<= 1;
}
if( x < 256 )
memset( &outB[ x ], paper, 256 - x );
}
return offset;
}
void displayFrame( u8 *frmBuf, u16 frmNum )
{
u8 colPaper, colLayer1, colLayer2;
u32 frmOffset;
u8 lEnc[192];
u8 *buf;
u8 lnePos, lneCount;
u8 *outFrameG;
u16 x, y;
u32 byteUse;
buf = (u8*) malloc( 256 * 192 );
if( buf == NULL )
{
printf( "Error unable to allocate buffer for frame %d\n", (int)frmBuf );
return;
}
frmOffset = getFrameOffset( frmBuf, 1 );
printf( "Frame #%d offset %08X\n", frmNum, (unsigned int)frmOffset );
colPaper = frmBuf[ frmOffset ] & 0x01;
colLayer1 = ( frmBuf[ frmOffset ] >> 1 ) & 0x03;
colLayer2 = ( frmBuf[ frmOffset ] >> 3 ) & 0x03;
printf( "Paper colour: %s\n", ( colPaper == 0 ? "Black" : "White" ) );
printf( "Layer 1 colour: %d\n", colLayer1 );
printf( "Layer 2 colour: %d\n", colLayer2 );
if( colPaper == 0 )
outFrameG = outFrameG0;
else
outFrameG = outFrameG1;
memset( buf, outFrameG[0], 192 << 8 );
lnePos = 0;
frmOffset ++;
// Read layer 1 line information into lower nibble
for( lneCount = 0; lneCount < 48; lneCount ++ )
{
lEnc[ lnePos++ ] = ( frmBuf[ frmOffset ] >> 0 ) & 0x03;
lEnc[ lnePos++ ] = ( frmBuf[ frmOffset ] >> 2 ) & 0x03;
lEnc[ lnePos++ ] = ( frmBuf[ frmOffset ] >> 4 ) & 0x03;
lEnc[ lnePos++ ] = ( frmBuf[ frmOffset ] >> 6 ) & 0x03;
frmOffset ++;
}
lnePos = 0;
// Read layer 2 line information into upper nibble
for( lneCount = 0; lneCount < 48; lneCount ++ )
{
lEnc[ lnePos++ ] |= ( frmBuf[ frmOffset ] << 4 ) & 0x30;
lEnc[ lnePos++ ] |= ( frmBuf[ frmOffset ] << 2 ) & 0x30;
lEnc[ lnePos++ ] |= ( frmBuf[ frmOffset ] >> 0 ) & 0x30;
lEnc[ lnePos++ ] |= ( frmBuf[ frmOffset ] >> 2 ) & 0x30;
frmOffset ++;
}
//read frame here...
// First read layer 1.
lnePos = 0;
while( lnePos < 192 )
{
switch( lEnc[ lnePos ] & 0x03 )
{
case 0: // Skip this line
byteUse = 0;
printf( "Line %3d(%04X), Layer 1, Skip Frame [%08X]\toffset %08X\n", lnePos, lnePos, (unsigned int)byteUse, (unsigned int)frmOffset + 0x6a0 );
break;
case 1: // Coded
byteUse = getu32inv( &frmBuf[ frmOffset ] );
printf( "Line %3d(%04X), Layer 1, Coded [%08X]\toffset %08X\n", lnePos, lnePos, (unsigned int)byteUse, (unsigned int)frmOffset + 0x6a0 );
frmOffset += 4;
frmOffset += decodeLine( &buf[ lnePos << 8 ], &frmBuf[ frmOffset ], byteUse, outFrameG[ 0 ], outFrameG[ colLayer1 ], 0 );
break;
case 2: // Inv Coded
byteUse = getu32inv( &frmBuf[ frmOffset ] );
printf( "Line %3d(%04X), Layer 1, Inv Coded [%08X]\toffset %08X\n", lnePos, lnePos, (unsigned int)byteUse, (unsigned int)frmOffset + 0x6a0 );
frmOffset += 4;
frmOffset += decodeLine( &buf[ lnePos << 8 ], &frmBuf[ frmOffset ], byteUse, outFrameG[ colLayer1 ], outFrameG[ 0 ], 1 );
break;
case 3: // Full Line
byteUse = 0xFFFFFFFF;
printf( "Line %3d(%04X), Layer 1, Full Frame [%08X]\toffset %08X\n", lnePos, lnePos, (unsigned int)byteUse, (unsigned int)frmOffset + 0x6a0 );
frmOffset += decodeLine( &buf[ lnePos << 8 ], &frmBuf[ frmOffset ], byteUse, outFrameG[ 0 ], outFrameG[ colLayer1 ], 0 );
break;
}
lnePos ++;
}
//output frame here...
for( y = 0; y < 192; y ++ )
{
for( x = 0; x < 256; x ++ )
{
printf( "%c", buf[ x + ( y << 8 ) ] );
}
printf( "\n" );
}
}
void hexOut( char *buf, int len )
{
int i;
for( i = 0 ; i < len ; i ++ )
{
printf( "%02X ", buf[i] & 0xFF );
if( ( i & 0xF ) == 0xF )
printf( "\n" );
}
}
int main(int argc, char* argv[])
{
ppmHeader *pHead;
FILE *fp;
int f_len;
char *f_buf;
if(argc != 2)
{
printf("usage: %s <anim.ppm>\n", argv[0]);
exit(0);
}
fp = fopen(argv[1],"rb");
if(fp == NULL)
{
printf("input file not found\n");
exit(1);
}
f_len = flength(fp);
f_buf = malloc(f_len);
if(f_buf == NULL)
{
fprintf(stderr, "not enough memory\n");
exit(1);
}
if(fread(f_buf, f_len, 1, fp) != 1)
{
fprintf(stderr, "file read failure\n");
exit(1);
}
pHead = (ppmHeader *) f_buf;
printHeaderInfo( pHead );
displayPreviewImage( pHead->previewBitmap );
printf( "\n" );
displayFrame( &f_buf[ 0x6a0 ], 1 );
printf( "\n" );
hexOut( &f_buf[ 0x6a0 ], 256 );
printf( "\n" );
hexOut( &f_buf[ f_len - 256 ], 256 );
printf("finished..\n");
free( f_buf);
fclose(fp);
return 0;
}