ef08150b790156d8960fa7a738a1cdbb8065bd49
[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                 _SysDebug("Image_Load: fread() returned %i",tmp);
62                 fclose(fp);
63         }
64         else if( strcmp(uri->Proto, "base64") == 0 )
65         {
66                 // 4 bytes of base64 = 3 bytes of binary (base 256)
67                 filesize = strlen( uri->Path ) * 3 / 4;
68                 buf = malloc(filesize);
69                 if(!buf) {
70                         _SysDebug("Image_Load: malloc() failed!");
71                         free(uri);
72                         return NULL;
73                 }
74                 
75                 filesize = UnBase64((uint8_t*)buf, uri->Path, filesize);
76         }
77         else
78         {
79                 _SysDebug("Image_Load: Unknow protocol '%s'", uri->Proto);
80                 free(uri);
81                 return NULL;
82         }
83         
84         img = Image_SIF_Parse(buf, filesize);
85         free(buf);
86         free(uri);
87         if( !img ) {
88                 _SysDebug("Image_Load: Unable to parse SIF from '%s'\n", URI);
89                 return NULL;
90         }
91         
92         return img;
93 }
94
95 /**
96  * \brief Decode a Base64 value
97  */
98 int UnBase64(uint8_t *Dest, char *Src, int BufSize)
99 {
100         uint32_t        val;
101          int    i, j;
102         char    *start_src = Src;
103         
104         for( i = 0; i+2 < BufSize; i += 3 )
105         {
106                 val = 0;
107                 for( j = 0; j < 4; j++, Src ++ ) {
108                         if('A' <= *Src && *Src <= 'Z')
109                                 val |= (*Src - 'A') << ((3-j)*6);
110                         else if('a' <= *Src && *Src <= 'z')
111                                 val |= (*Src - 'a' + 26) << ((3-j)*6);
112                         else if('0' <= *Src && *Src <= '9')
113                                 val |= (*Src - '0' + 52) << ((3-j)*6);
114                         else if(*Src == '+')
115                                 val |= 62 << ((3-j)*6);
116                         else if(*Src == '/')
117                                 val |= 63 << ((3-j)*6);
118                         else if(!*Src)
119                                 break;
120                         else if(*Src != '=')
121                                 j --;   // Ignore invalid characters
122                 }
123                 Dest[i  ] = (val >> 16) & 0xFF;
124                 Dest[i+1] = (val >> 8) & 0xFF;
125                 Dest[i+2] = val & 0xFF;
126                 if(j != 4)      break;
127         }
128         
129         // Finish things off
130         if(i   < BufSize)
131                 Dest[i] = (val >> 16) & 0xFF;
132         if(i+1 < BufSize)
133                 Dest[i+1] = (val >> 8) & 0xFF;
134         
135         return Src - start_src;
136 }

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