//#include <image_sif.h>
#include <acess/sys.h> // _SysDebug
+#define _SysDebug(...) do{}while(0)
+
// === STRUCTURES ===
struct sHeader
{
return 0;
}
+static uint32_t flipendian32(uint32_t val)
+{
+ return ((val >> 24) & 0xFF) << 0
+ | ((val >> 16) & 0xFF) << 8
+ | ((val >> 8) & 0xFF) << 16
+ | ((val >> 0) & 0xFF) << 24;
+}
+
+static void flip_buffer_endian(void *Data, size_t SampleSize, size_t Pixels)
+{
+ if( SampleSize == 3 )
+ return ;
+
+ if( SampleSize == 4 )
+ {
+ uint32_t *data32 = Data;
+ while( Pixels -- ) {
+ *data32 = flipendian32(*data32);
+ data32 ++;
+ }
+ }
+}
+
/**
*/
tImage *Image_SIF_Parse(void *Buffer, size_t Size)
int bRevOrder;
int fileOfs = 0;
int comp, fmt;
- int sampleSize = 4;
+ int sampleSize;
struct sHeader *hdr = Buffer;
_SysDebug("Image_SIF_Parse: (Buffer=%p, Size=0x%x)", Buffer, Size);
ret->Width = w;
ret->Height = h;
ret->Format = fmt;
+ for( ofs = 0; ofs < w*h*sampleSize; ofs ++ )
+ ret->Data[ofs] = 255;
switch(comp)
{
// Uncompressed 32-bpp data
- case 0:
- if( fileOfs + w*h*sampleSize > Size ) {
- memcpy(ret->Data, Buffer+fileOfs, Size-fileOfs);
- }
- else {
- memcpy(ret->Data, Buffer+fileOfs, w*h*sampleSize);
- }
+ case 0: {
+ size_t idatsize = w*h*sampleSize;
+ if( idatsize > Size - fileOfs )
+ idatsize = Size - fileOfs;
+ memcpy(ret->Data, Buffer+fileOfs, idatsize);
+ if(bRevOrder)
+ flip_buffer_endian(ret->Data, sampleSize, w*h);
return ret;
+ }
// 1.7.n*8 RLE
// (1 Flag, 7-bit size, 32-bit value)
case 1:
ofs = 0;
- while( ofs < w*h )
+ while( ofs < w*h*sampleSize )
{
uint8_t len;
- if( fileOfs + 1 > Size ) return ret;
- len = *(uint8_t*)Buffer+fileOfs; fileOfs += 1;
+ if( fileOfs + 1 > Size )
+ return ret;
+ len = ((uint8_t*)Buffer)[fileOfs++];
// Verbatim
if(len & 0x80) {
len &= 0x7F;
- if( fileOfs + len*sampleSize > Size ) {
- memcpy(ret->Data + ofs*sampleSize, Buffer+fileOfs, Size-fileOfs);
- return ret;
+ while( len -- )
+ {
+ if( fileOfs + sampleSize > Size )
+ return ret;
+ memcpy(ret->Data+ofs, Buffer+fileOfs, sampleSize);
+ ofs += sampleSize;
+ fileOfs += sampleSize;
}
- else {
- memcpy(ret->Data + ofs*sampleSize, Buffer+fileOfs, len*sampleSize);
- }
- ofs += len;
}
// RLE
else {
- uint8_t tmp[sampleSize];
-
- if( fileOfs + sampleSize > Size ) return ret;
-
- for(i=0;i<sampleSize;i++)
- tmp[i] = *(uint8_t*)Buffer+fileOfs; fileOfs += 1;
+ if( fileOfs + sampleSize > Size )
+ return ret;
- i = 0;
- while(len--) {
- for(i=0;i<sampleSize;i++)
- ret->Data[ofs++] = tmp[i];
+ while( len -- )
+ {
+ memcpy(ret->Data+ofs, Buffer+fileOfs, sampleSize);
+ ofs += sampleSize;
}
+ fileOfs += sampleSize;
}
}
+ if(bRevOrder)
+ flip_buffer_endian(ret->Data, sampleSize, w*h);
+ _SysDebug("Image_SIF_Parse: Complete at %i bytes", fileOfs);
return ret;
// Channel 1.7.8 RLE
{
uint8_t len, val;
if( fileOfs + 1 > Size ) return ret;
- len = *(uint8_t*)Buffer+fileOfs; fileOfs += 1;
+ len = ((uint8_t*)Buffer)[fileOfs++];
if(len & 0x80) {
len &= 0x7F;
while(len--) {
if( fileOfs + 1 > Size ) return ret;
- val = *(uint8_t*)Buffer+fileOfs; fileOfs += 1;
- if(i == 0)
- ret->Data[ofs] = val;
- else
- ret->Data[ofs] |= val;
+ val = ((uint8_t*)Buffer)[fileOfs++];
+ ret->Data[ofs] = val;
ofs += sampleSize;
}
}
else {
if( fileOfs + 1 > Size ) return ret;
- val = *(uint8_t*)Buffer+fileOfs; fileOfs += 1;
- if(i == 0) {
- while(len--) {
- ret->Data[ofs] = val; ofs += sampleSize;
- }
- }
- else {
- while(len--) {
- ret->Data[ofs] |= val; ofs += sampleSize;
- }
+ val = ((uint8_t*)Buffer)[fileOfs++];
+ while(len--) {
+ ret->Data[ofs] = val;
+ ofs += sampleSize;
}
}
}