Just cleaning up some things that may be needed in the tree
[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_SIF      *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         
50         // Allocate space
51         ret = calloc(1, sizeof(tImage) + w * h * sampleSize);
52         ret->Width = w;
53         ret->Height = h;
54         
55         // Get image format
56         switch(fmt)
57         {
58         case 0: // ARGB
59                 ret->Format = IMGFMT_ARGB;
60                 sampleSize = 4;
61                 break;
62         case 1: // RGB
63                 ret->Format = IMGFMT_RGB;
64                 sampleSize = 3;
65                 break;
66         default:
67                 free(ret);
68                 return NULL;
69         }
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                         if(len & 0x80) {
93                                 len &= 0x7F;
94                                 if( fileOfs + len*sampleSize > Size ) {
95                                         memcpy(ret->Data + ofs*sampleSize, Buffer+fileOfs, Size-fileOfs);
96                                         return ret;
97                                 }
98                                 else {
99                                         memcpy(ret->Data + ofs*sampleSize, Buffer+fileOfs, len*sampleSize);
100                                 }
101                                 ofs += len;
102                         }
103                         else {
104                                 uint8_t tmp[sampleSize];
105                                 
106                                 if( fileOfs + sampleSize > Size )       return ret;
107                                 
108                                 for(i=0;i<sampleSize;i++)
109                                         tmp[i] = *(uint8_t*)Buffer+fileOfs;     fileOfs += 1;
110                                 
111                                 i = 0;
112                                 while(len--) {
113                                         for(i=0;i<sampleSize;i++)
114                                                 ret->Data[ofs++] = tmp[i];
115                                 }
116                         }
117                 }
118                 return ret;
119         
120         // Channel 1.7.8 RLE
121         case 3:
122                 // Alpha, Red, Green, Blue
123                 for( i = 0; i < sampleSize; i++ )
124                 {
125                         ofs = i;
126                         while( ofs < w*h*sampleSize )
127                         {
128                                 uint8_t len, val;
129                                 if( fileOfs + 1 > Size )        return ret;
130                                 len = *(uint8_t*)Buffer+fileOfs;        fileOfs += 1;
131                                 if(len & 0x80) {
132                                         len &= 0x7F;
133                                         while(len--) {
134                                                 if( fileOfs + 1 > Size )        return ret;
135                                                 val = *(uint8_t*)Buffer+fileOfs;        fileOfs += 1;
136                                                 if(i == 0)
137                                                         ret->Data[ofs] = val;
138                                                 else
139                                                         ret->Data[ofs] |= val;
140                                                 ofs += sampleSize;
141                                         }
142                                 }
143                                 else {
144                                         if( fileOfs + 1 > Size )        return ret;
145                                         val = *(uint8_t*)Buffer+fileOfs;        fileOfs += 1;
146                                         if(i == 0) {
147                                                 while(len--) {
148                                                         ret->Data[ofs] = val;           ofs += sampleSize;
149                                                 }
150                                         }
151                                         else {
152                                                 while(len--) {
153                                                         ret->Data[ofs] |= val;  ofs += sampleSize;
154                                                 }
155                                         }
156                                 }
157                         }
158                 }
159                 return ret;
160         
161         default:
162                 fprintf(stderr, "Warning: Unknown compression scheme %i for SIF\n", comp);
163                 return NULL;
164         }
165 }

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