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

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