diff options
author | Teruaki Kawashima <teru@rockbox.org> | 2011-01-22 13:41:53 +0000 |
---|---|---|
committer | Teruaki Kawashima <teru@rockbox.org> | 2011-01-22 13:41:53 +0000 |
commit | 68cc564c9bd327743896cded4a49aad7af0b1d37 (patch) | |
tree | 4a9225f4ec586ba69818bc90d74630581c8ec1f2 /apps/plugins/imageviewer/image_decoder.c | |
parent | 060609a2023bfcc99472cfe4e94a2cc3704bd92c (diff) |
FS#11819: image viewer: use magick number in file to determine image type.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@29110 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/plugins/imageviewer/image_decoder.c')
-rw-r--r-- | apps/plugins/imageviewer/image_decoder.c | 68 |
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); |