Usermode/AxWin3 - Fixed scan-build complaints in libaxwin3.so
[tpg/acess2.git] / Usermode / Applications / axwin3_src / WM / image.c
1 /*
2  * Acess2 GUI (AxWin) Version 3
3  * - By John Hodge (thePowersGang)
4  * 
5  * image.c
6  * - Image loading
7  */
8 #include <common.h>
9 #include <stdlib.h>
10 #include <stdio.h>
11 #include <string.h>
12 #include <uri.h>
13 #include "include/image.h"
14
15 // === IMPORTS ===
16 extern tImage *Image_SIF_Parse(void *Buffer, size_t Size);
17
18 // === PROTOTYPES ===
19  int    UnBase64(uint8_t *Dest, char *Src, int BufSize);
20
21 // === CODE ===
22 /**
23  * \brief Open an image from a URI
24  */
25 tImage *Image_Load(const char *URI)
26 {
27         tURI    *uri;
28          int    filesize;
29         char    *buf;
30         tImage  *img;
31         
32         uri = URI_Parse(URI);
33         if( !uri ) {
34                 _SysDebug("Image_Load: Unable parse as URI '%s'", URI);
35                 return NULL;
36         }
37         
38         if( strcmp(uri->Proto, "file") == 0 )
39         {
40                 FILE    *fp;
41                  int    tmp;
42                 fp = fopen(uri->Path, "rb");
43                 if(!fp) {
44                         _SysDebug("Image_Load: Unable to open '%s'", uri->Path);
45                         free(uri);
46                         return NULL;
47                 }
48                 
49                 fseek(fp, 0, SEEK_END);
50                 filesize = ftell(fp);
51                 fseek(fp, 0, SEEK_SET);
52                 buf = malloc( filesize );
53                 if(!buf) {
54                         _SysDebug("Image_Load: malloc() failed!");
55                         fclose(fp);
56                         free(uri);
57                         return NULL;
58                 }
59                 
60                 tmp = fread(buf, 1, filesize, fp);
61                 if(tmp != filesize) {
62                         _SysDebug("Image_Load: fread() failed - %i != filesize (%i)", tmp, filesize);
63                 }
64                 fclose(fp);
65         }
66         else if( strcmp(uri->Proto, "base64") == 0 )
67         {
68                 // 4 bytes of base64 = 3 bytes of binary (base 256)
69                 filesize = strlen( uri->Path ) * 3 / 4;
70                 buf = malloc(filesize);
71                 if(!buf) {
72                         _SysDebug("Image_Load: malloc() failed!");
73                         free(uri);
74                         return NULL;
75                 }
76                 
77                 filesize = UnBase64((uint8_t*)buf, uri->Path, filesize);
78         }
79         else
80         {
81                 _SysDebug("Image_Load: Unknow protocol '%s'", uri->Proto);
82                 free(uri);
83                 return NULL;
84         }
85         
86         img = Image_SIF_Parse(buf, filesize);
87         free(buf);
88         free(uri);
89         if( !img ) {
90                 _SysDebug("Image_Load: Unable to parse SIF from '%s'\n", URI);
91                 return NULL;
92         }
93         
94         return img;
95 }
96
97 /**
98  * \brief Decode a Base64 value
99  */
100 int UnBase64(uint8_t *Dest, char *Src, int BufSize)
101 {
102         uint32_t        val;
103          int    i, j;
104         char    *start_src = Src;
105         
106         for( i = 0; i+2 < BufSize; i += 3 )
107         {
108                 val = 0;
109                 for( j = 0; j < 4; j++, Src ++ ) {
110                         if('A' <= *Src && *Src <= 'Z')
111                                 val |= (*Src - 'A') << ((3-j)*6);
112                         else if('a' <= *Src && *Src <= 'z')
113                                 val |= (*Src - 'a' + 26) << ((3-j)*6);
114                         else if('0' <= *Src && *Src <= '9')
115                                 val |= (*Src - '0' + 52) << ((3-j)*6);
116                         else if(*Src == '+')
117                                 val |= 62 << ((3-j)*6);
118                         else if(*Src == '/')
119                                 val |= 63 << ((3-j)*6);
120                         else if(!*Src)
121                                 break;
122                         else if(*Src != '=')
123                                 j --;   // Ignore invalid characters
124                 }
125                 Dest[i  ] = (val >> 16) & 0xFF;
126                 Dest[i+1] = (val >> 8) & 0xFF;
127                 Dest[i+2] = val & 0xFF;
128                 if(j != 4)      break;
129         }
130         
131         // Finish things off
132         if(i   < BufSize)
133                 Dest[i] = (val >> 16) & 0xFF;
134         if(i+1 < BufSize)
135                 Dest[i+1] = (val >> 8) & 0xFF;
136         
137         return Src - start_src;
138 }

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