1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
23 #include "imageviewer.h"
24 #include "image_decoder.h"
26 static const char *decoder_names
[MAX_IMAGE_TYPES
] = {
35 /* Check file type by magic number or file extension
37 * If the file contains magic number, use it to determine image type.
38 * Otherwise use file extension to determine image type.
39 * If the file contains magic number and file extension is not correct,
40 * informs user that something is wrong.
42 enum image_type
get_image_type(const char *name
, bool quiet
)
48 { ".bmp", IMAGE_BMP
},
49 { ".jpg", IMAGE_JPEG
},
50 { ".jpe", IMAGE_JPEG
},
51 { ".jpeg", IMAGE_JPEG
},
52 { ".png", IMAGE_PNG
},
54 { ".ppm", IMAGE_PPM
},
58 char *magic
; /* magic number */
59 int length
; /* length of the magic number */
62 { "BM", 2, IMAGE_BMP
},
63 { "\xff\xd8\xff\xe0", 4, IMAGE_JPEG
},
64 { "\x89\x50\x4e\x47\x0d\x0a\x1a\x0a", 8, IMAGE_PNG
},
66 { "P3", 2, IMAGE_PPM
},
67 { "P6", 2, IMAGE_PPM
},
71 enum image_type type
= IMAGE_UNKNOWN
;
72 const char *ext
= rb
->strrchr(name
, '.');
76 /* check file extention */
79 for (i
= 0; i
< (int)ARRAYLEN(ext_list
); i
++)
81 if (!rb
->strcasecmp(ext
, ext_list
[i
].ext
))
83 type
= ext_list
[i
].type
;
89 /* check magic value in the file */
90 fd
= rb
->open(name
, O_RDONLY
);
93 rb
->memset(buf
, 0, sizeof buf
);
94 rb
->read(fd
, buf
, sizeof buf
);
96 for (i
= 0; i
< (int)ARRAYLEN(magic_list
); i
++)
98 if (!rb
->memcmp(buf
, magic_list
[i
].magic
, magic_list
[i
].length
))
100 if (!quiet
&& type
!= magic_list
[i
].type
)
102 /* file extension is wrong. */
103 rb
->splashf(HZ
*1, "Note: File extension is not correct");
105 type
= magic_list
[i
].type
;
113 static void *decoder_handle
= NULL
;
114 const struct image_decoder
*load_decoder(struct loader_info
*loader_info
)
117 char filename
[MAX_PATH
];
118 struct imgdec_header
*hdr
;
119 struct lc_header
*lc_hdr
;
121 if (loader_info
->type
< 0 || loader_info
->type
>= MAX_IMAGE_TYPES
)
123 rb
->splashf(2*HZ
, "Unknown type: %d", loader_info
->type
);
129 name
= decoder_names
[loader_info
->type
];
130 rb
->snprintf(filename
, MAX_PATH
, VIEWERS_DIR
"/%s.ovl", name
);
132 /* load decoder to the buffer. */
133 decoder_handle
= rb
->lc_open(filename
, loader_info
->buffer
, loader_info
->size
);
136 rb
->splashf(2*HZ
, "Can't open %s", filename
);
140 hdr
= rb
->lc_get_header(decoder_handle
);
143 rb
->splash(2*HZ
, "Can't get header");
146 lc_hdr
= &hdr
->lc_hdr
;
148 if (lc_hdr
->magic
!= PLUGIN_MAGIC
|| lc_hdr
->target_id
!= TARGET_ID
)
150 rb
->splashf(2*HZ
, "%s decoder: Incompatible model.", name
);
154 if (lc_hdr
->api_version
!= IMGDEC_API_VERSION
)
156 rb
->splashf(2*HZ
, "%s decoder: Incompatible version.", name
);
161 *(hdr
->img_api
) = loader_info
->iv
;
163 /* set remaining buffer size to loader_info. decoder will
164 * be loaded to the end of the buffer, so fix size only. */
165 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
166 loader_info
->size
= lc_hdr
->load_addr
- loader_info
->buffer
;
177 void release_decoder(void)
179 if (decoder_handle
!= NULL
)
181 rb
->lc_close(decoder_handle
);
182 decoder_handle
= NULL
;