// === IMPORTS ===
extern tImage *Image_SIF_Parse(void *Buffer, size_t Size);
+// === PROTOTYPES ===
+ int UnBase64(uint8_t *Dest, char *Src, int BufSize);
+
// === CODE ===
/**
* \brief Open an image from a URI
*/
tImage *Image_Load(const char *URI)
{
- #if 0
tURI *uri;
int filesize;
void *buf;
tImage *img;
- void *fp;
uri = URI_Parse(URI);
-
- fp = URI_Open(URI_MODE_READ, uri);
- if(!fp) return NULL;
- free(uri);
-
- filesize = URI_GetSize(fp);
- buf = malloc( filesize );
- if(!buf) {
- URI_Close(fp);
+ if( !uri ) {
+ _SysDebug("Image_Load: Unable parse as URI '%s'\n", URI);
return NULL;
}
- URI_Read(fp, filesize, buf);
- URI_Close(fp);
+ if( strcmp(uri->Proto, "file") == 0 )
+ {
+ FILE *fp;
+ fp = fopen(uri->Path, "rb");
+ if(!fp) {
+ _SysDebug("Image_Load: Unable to open '%s'\n", uri->Path);
+ free(uri);
+ return NULL;
+ }
+
+ fseek(fp, 0, SEEK_END);
+ filesize = ftell(fp);
+ buf = malloc( filesize );
+ if(!buf) {
+ _SysDebug("Image_Load: malloc() failed!\n");
+ fclose(fp);
+ free(uri);
+ return NULL;
+ }
+
+ fread(buf, filesize, 1, buf);
+ fclose(fp);
+ }
+ else if( strcmp(uri->Proto, "base64") == 0 )
+ {
+ // 4 bytes of base64 = 3 bytes of binary (base 256)
+ filesize = strlen( uri->Path ) * 3 / 4;
+ buf = malloc(filesize);
+ if(!buf) {
+ _SysDebug("Image_Load: malloc() failed!\n");
+ free(uri);
+ return NULL;
+ }
+
+ filesize = UnBase64(buf, uri->Path, filesize);
+ }
+ else
+ {
+ _SysDebug("Image_Load: Unknow protocol '%s'\n", uri->Proto);
+ free(uri);
+ return NULL;
+ }
img = Image_SIF_Parse(buf, filesize);
free(buf);
+ free(uri);
+ if( !img ) {
+ _SysDebug("Image_Load: Unable to parse SIF from '%s'\n", URI);
+ return NULL;
+ }
return img;
- #else
- return NULL;
- #endif
+}
+
+/**
+ * \brief Decode a Base64 value
+ */
+int UnBase64(uint8_t *Dest, char *Src, int BufSize)
+{
+ uint32_t val;
+ int i, j;
+ char *start_src = Src;
+
+ for( i = 0; i+2 < BufSize; i += 3 )
+ {
+ val = 0;
+ for( j = 0; j < 4; j++, Src ++ ) {
+ if('A' <= *Src && *Src <= 'Z')
+ val |= (*Src - 'A') << ((3-j)*6);
+ else if('a' <= *Src && *Src <= 'z')
+ val |= (*Src - 'a' + 26) << ((3-j)*6);
+ else if('0' <= *Src && *Src <= '9')
+ val |= (*Src - '0' + 52) << ((3-j)*6);
+ else if(*Src == '+')
+ val |= 62 << ((3-j)*6);
+ else if(*Src == '/')
+ val |= 63 << ((3-j)*6);
+ else if(!*Src)
+ break;
+ else if(*Src != '=')
+ j --; // Ignore invalid characters
+ }
+ Dest[i ] = (val >> 16) & 0xFF;
+ Dest[i+1] = (val >> 8) & 0xFF;
+ Dest[i+2] = val & 0xFF;
+ if(j != 4) break;
+ }
+
+ // Finish things off
+ if(i < BufSize)
+ Dest[i] = (val >> 16) & 0xFF;
+ if(i+1 < BufSize)
+ Dest[i+1] = (val >> 8) & 0xFF;
+
+ return Src - start_src;
}