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

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