summaryrefslogtreecommitdiffstats
path: root/apps/plugins/imageviewer/image_decoder.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins/imageviewer/image_decoder.c')
-rw-r--r--apps/plugins/imageviewer/image_decoder.c68
1 files changed, 58 insertions, 10 deletions
diff --git a/apps/plugins/imageviewer/image_decoder.c b/apps/plugins/imageviewer/image_decoder.c
index 553632e559..0088eb4873 100644
--- a/apps/plugins/imageviewer/image_decoder.c
+++ b/apps/plugins/imageviewer/image_decoder.c
@@ -32,8 +32,14 @@ static const char *decoder_names[MAX_IMAGE_TYPES] = {
#endif
};
-/* check file type by extention */
-enum image_type get_image_type(const char *name)
+/* Check file type by magic number or file extension
+ *
+ * If the file contains magic number, use it to determine image type.
+ * Otherwise use file extension to determine image type.
+ * If the file contains magic number and file extension is not correct,
+ * informs user that something is wrong.
+ */
+enum image_type get_image_type(const char *name, bool quiet)
{
static const struct {
char *ext;
@@ -48,18 +54,60 @@ enum image_type get_image_type(const char *name)
{ ".ppm", IMAGE_PPM },
#endif
};
+ static const struct {
+ char *magic; /* magic number */
+ int length; /* length of the magic number */
+ enum image_type type;
+ } magic_list[] = {
+ { "BM", 2, IMAGE_BMP },
+ { "\xff\xd8\xff\xe0", 4, IMAGE_JPEG },
+ { "\x89\x50\x4e\x47\x0d\x0a\x1a\x0a", 8, IMAGE_PNG },
+#ifdef HAVE_LCD_COLOR
+ { "P3", 2, IMAGE_PPM },
+ { "P6", 2, IMAGE_PPM },
+#endif
+ };
+ enum image_type type = IMAGE_UNKNOWN;
const char *ext = rb->strrchr(name, '.');
- int i;
- if (!ext)
- return IMAGE_UNKNOWN;
+ int i, fd;
+ char buf[12];
+
+ /* check file extention */
+ if (ext)
+ {
+ for (i = 0; i < (int)ARRAYLEN(ext_list); i++)
+ {
+ if (!rb->strcasecmp(ext, ext_list[i].ext))
+ {
+ type = ext_list[i].type;
+ break;
+ }
+ }
+ }
- for (i = 0; i < (int)ARRAYLEN(ext_list); i++)
+ /* check magic value in the file */
+ fd = rb->open(name, O_RDONLY);
+ if (fd >= 0)
{
- if (!rb->strcasecmp(ext, ext_list[i].ext))
- return ext_list[i].type;
+ rb->memset(buf, 0, sizeof buf);
+ rb->read(fd, buf, sizeof buf);
+ rb->close(fd);
+ for (i = 0; i < (int)ARRAYLEN(magic_list); i++)
+ {
+ if (!rb->memcmp(buf, magic_list[i].magic, magic_list[i].length))
+ {
+ if (!quiet && type != magic_list[i].type)
+ {
+ /* file extension is wrong. */
+ rb->splashf(HZ*1, "Note: File extension is not correct");
+ }
+ type = magic_list[i].type;
+ break;
+ }
+ }
}
- return IMAGE_UNKNOWN;
+ return type;
}
static void *decoder_handle = NULL;
@@ -79,7 +127,7 @@ const struct image_decoder *load_decoder(struct loader_info *loader_info)
release_decoder();
name = decoder_names[loader_info->type];
- rb->snprintf(filename, MAX_PATH, VIEWERS_DIR "/%s.ovl", name);
+ rb->snprintf(filename, MAX_PATH, "/rockbox/rocks/viewers" "/%s.ovl", name);
/* load decoder to the buffer. */
decoder_handle = rb->lc_open(filename, loader_info->buffer, loader_info->size);