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

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