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

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