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

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