8 //#include <image_sif.h>
9 #include <acess/sys.h> // _SysDebug
11 #define _SysDebug(...) do{}while(0)
30 static uint32_t flipendian32(uint32_t val)
32 return ((val >> 24) & 0xFF) << 0
33 | ((val >> 16) & 0xFF) << 8
34 | ((val >> 8) & 0xFF) << 16
35 | ((val >> 0) & 0xFF) << 24;
38 static void flip_buffer_endian(void *Data, size_t SampleSize, size_t Pixels)
45 uint32_t *data32 = Data;
47 *data32 = flipendian32(*data32);
55 tImage *Image_SIF_Parse(void *Buffer, size_t Size)
64 struct sHeader *hdr = Buffer;
66 _SysDebug("Image_SIF_Parse: (Buffer=%p, Size=0x%x)", Buffer, Size);
68 // Get magic word and determine byte ordering
69 if(hdr->Magic == 0x51F0) // Little Endian
71 else if(hdr->Magic == 0xF051) // Big Endian
74 _SysDebug(" Image_SIF_Parse: Magic invalid (0x%x)", hdr->Magic);
78 _SysDebug(" Image_SIF_Parse: bRevOrder = %i", bRevOrder);
81 comp = hdr->Flags & 7;
82 fmt = (hdr->Flags >> 3) & 7;
88 _SysDebug(" Image_SIF_Parse: Dimensions %ix%i", w, h);
93 case 0: // ARGB 32-bit Little Endian
97 case 1: // RGB 24-bit big endian
105 _SysDebug(" Image_SIF_Parse: sampleSize = %i, fmt = %i", sampleSize, fmt);
107 fileOfs = sizeof(struct sHeader);
110 ret = calloc(1, sizeof(tImage) + w * h * sampleSize);
114 for( ofs = 0; ofs < w*h*sampleSize; ofs ++ )
115 ret->Data[ofs] = 255;
119 // Uncompressed 32-bpp data
121 size_t idatsize = w*h*sampleSize;
122 if( idatsize > Size - fileOfs )
123 idatsize = Size - fileOfs;
124 memcpy(ret->Data, Buffer+fileOfs, idatsize);
126 flip_buffer_endian(ret->Data, sampleSize, w*h);
131 // (1 Flag, 7-bit size, 32-bit value)
134 while( ofs < w*h*sampleSize )
137 if( fileOfs + 1 > Size )
139 len = ((uint8_t*)Buffer)[fileOfs++];
145 if( fileOfs + sampleSize > Size )
147 memcpy(ret->Data+ofs, Buffer+fileOfs, sampleSize);
149 fileOfs += sampleSize;
154 if( fileOfs + sampleSize > Size )
159 memcpy(ret->Data+ofs, Buffer+fileOfs, sampleSize);
162 fileOfs += sampleSize;
166 flip_buffer_endian(ret->Data, sampleSize, w*h);
167 _SysDebug("Image_SIF_Parse: Complete at %i bytes", fileOfs);
171 // - Each channel is separately 1.7 RLE compressed
173 // Alpha, Red, Green, Blue
174 for( i = 0; i < sampleSize; i++ )
177 while( ofs < w*h*sampleSize )
180 if( fileOfs + 1 > Size ) return ret;
181 len = ((uint8_t*)Buffer)[fileOfs++];
185 if( fileOfs + 1 > Size ) return ret;
186 val = ((uint8_t*)Buffer)[fileOfs++];
187 ret->Data[ofs] = val;
192 if( fileOfs + 1 > Size ) return ret;
193 val = ((uint8_t*)Buffer)[fileOfs++];
195 ret->Data[ofs] = val;
204 fprintf(stderr, "Warning: Unknown compression scheme %i for SIF\n", comp);