Usermode - Slight changes, debug/commenting only
[tpg/acess2.git] / Usermode / Libraries / libimage_sif.so_src / main.c
1 /*
2  */
3 #include <stdint.h>
4 #include <stdlib.h>
5 #include <stdio.h>
6 #include <string.h>
7 #include <image.h>
8 //#include <image_sif.h>
9
10 // === STRUCTURES ===
11 struct sHeader
12 {
13         uint16_t        Magic;
14         uint16_t        Flags;
15         uint16_t        Width;
16         uint16_t        Height;
17 };
18
19 // === CONSTANTS ===
20
21 // === CODE ===
22 int SoMain(void)
23 {
24         return 0;
25 }
26
27 /**
28  */
29 tImage *Image_SIF_Parse(void *Buffer, size_t Size)
30 {
31         uint16_t        w, h;
32          int    ofs, i;
33         tImage  *ret;
34          int    bRevOrder;
35          int    fileOfs = 0;
36          int    comp, fmt;
37          int    sampleSize = 4;
38         struct sHeader  *hdr = Buffer;
39          
40         _SysDebug("Image_SIF_Parse: (Buffer=%p, Size=0x%x)", Buffer, Size);
41         
42         // Get magic word and determine byte ordering
43         if(hdr->Magic == 0x51F0)        // Little Endian
44                 bRevOrder = 0;
45         else if(hdr->Magic == 0xF051)   // Big Endian
46                 bRevOrder = 1;
47         else {
48                 _SysDebug(" Image_SIF_Parse: Magic invalid (0x%x)", hdr->Magic);
49                 return NULL;
50         }
51         
52         _SysDebug(" Image_SIF_Parse: bRevOrder = %i", bRevOrder);
53         
54         // Read flags
55         comp = hdr->Flags & 7;
56         fmt = (hdr->Flags >> 3) & 7;
57         
58         // Read dimensions
59         w = hdr->Width;
60         h = hdr->Height;
61         
62         _SysDebug(" Image_SIF_Parse: Dimensions %ix%i", w, h);
63         
64         // Get image format
65         switch(fmt)
66         {
67         case 0: // ARGB 32-bit Little Endian
68                 fmt = IMGFMT_BGRA;
69                 sampleSize = 4;
70                 break;
71         case 1: // RGB 24-bit big endian
72                 fmt = IMGFMT_RGB;
73                 sampleSize = 3;
74                 break;
75         default:
76                 return NULL;
77         }
78         
79         _SysDebug(" Image_SIF_Parse: sampleSize = %i, fmt = %i", sampleSize, fmt);
80         
81         fileOfs = sizeof(struct sHeader);
82         
83         // Allocate space
84         ret = calloc(1, sizeof(tImage) + w * h * sampleSize);
85         ret->Width = w;
86         ret->Height = h;
87         ret->Format = fmt;
88         
89         switch(comp)
90         {
91         // Uncompressed 32-bpp data
92         case 0:
93                 if( fileOfs + w*h*sampleSize > Size ) {
94                         memcpy(ret->Data, Buffer+fileOfs, Size-fileOfs);
95                 }
96                 else {
97                         memcpy(ret->Data, Buffer+fileOfs, w*h*sampleSize);
98                 }
99                 return ret;
100         
101         // 1.7.n*8 RLE
102         // (1 Flag, 7-bit size, 32-bit value)
103         case 1:
104                 ofs = 0;
105                 while( ofs < w*h )
106                 {
107                         uint8_t len;
108                         if( fileOfs + 1 > Size )        return ret;
109                         len = *(uint8_t*)Buffer+fileOfs;        fileOfs += 1;
110                         // Verbatim
111                         if(len & 0x80) {
112                                 len &= 0x7F;
113                                 if( fileOfs + len*sampleSize > Size ) {
114                                         memcpy(ret->Data + ofs*sampleSize, Buffer+fileOfs, Size-fileOfs);
115                                         return ret;
116                                 }
117                                 else {
118                                         memcpy(ret->Data + ofs*sampleSize, Buffer+fileOfs, len*sampleSize);
119                                 }
120                                 ofs += len;
121                         }
122                         // RLE
123                         else {
124                                 uint8_t tmp[sampleSize];
125                                 
126                                 if( fileOfs + sampleSize > Size )       return ret;
127                                 
128                                 for(i=0;i<sampleSize;i++)
129                                         tmp[i] = *(uint8_t*)Buffer+fileOfs;     fileOfs += 1;
130                                 
131                                 i = 0;
132                                 while(len--) {
133                                         for(i=0;i<sampleSize;i++)
134                                                 ret->Data[ofs++] = tmp[i];
135                                 }
136                         }
137                 }
138                 return ret;
139         
140         // Channel 1.7.8 RLE
141         // - Each channel is separately 1.7 RLE compressed
142         case 3:
143                 // Alpha, Red, Green, Blue
144                 for( i = 0; i < sampleSize; i++ )
145                 {
146                         ofs = i;
147                         while( ofs < w*h*sampleSize )
148                         {
149                                 uint8_t len, val;
150                                 if( fileOfs + 1 > Size )        return ret;
151                                 len = *(uint8_t*)Buffer+fileOfs;        fileOfs += 1;
152                                 if(len & 0x80) {
153                                         len &= 0x7F;
154                                         while(len--) {
155                                                 if( fileOfs + 1 > Size )        return ret;
156                                                 val = *(uint8_t*)Buffer+fileOfs;        fileOfs += 1;
157                                                 if(i == 0)
158                                                         ret->Data[ofs] = val;
159                                                 else
160                                                         ret->Data[ofs] |= val;
161                                                 ofs += sampleSize;
162                                         }
163                                 }
164                                 else {
165                                         if( fileOfs + 1 > Size )        return ret;
166                                         val = *(uint8_t*)Buffer+fileOfs;        fileOfs += 1;
167                                         if(i == 0) {
168                                                 while(len--) {
169                                                         ret->Data[ofs] = val;           ofs += sampleSize;
170                                                 }
171                                         }
172                                         else {
173                                                 while(len--) {
174                                                         ret->Data[ofs] |= val;  ofs += sampleSize;
175                                                 }
176                                         }
177                                 }
178                         }
179                 }
180                 return ret;
181         
182         default:
183                 fprintf(stderr, "Warning: Unknown compression scheme %i for SIF\n", comp);
184                 return NULL;
185         }
186 }

UCC git Repository :: git.ucc.asn.au