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 | |
parent | 060609a2023bfcc99472cfe4e94a2cc3704bd92c (diff) | |
download | rockbox-68cc564c9bd327743896cded4a49aad7af0b1d37.tar.gz rockbox-68cc564c9bd327743896cded4a49aad7af0b1d37.zip |
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
-rw-r--r-- | apps/plugins/imageviewer/image_decoder.c | 68 | ||||
-rw-r--r-- | apps/plugins/imageviewer/image_decoder.h | 5 | ||||
-rw-r--r-- | apps/plugins/imageviewer/imageviewer.c | 14 |
3 files changed, 72 insertions, 15 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] = { | |||
32 | #endif | 32 | #endif |
33 | }; | 33 | }; |
34 | 34 | ||
35 | /* check file type by extention */ | 35 | /* Check file type by magic number or file extension |
36 | enum image_type get_image_type(const char *name) | 36 | * |
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. | ||
41 | */ | ||
42 | enum image_type get_image_type(const char *name, bool quiet) | ||
37 | { | 43 | { |
38 | static const struct { | 44 | static const struct { |
39 | char *ext; | 45 | char *ext; |
@@ -48,18 +54,60 @@ enum image_type get_image_type(const char *name) | |||
48 | { ".ppm", IMAGE_PPM }, | 54 | { ".ppm", IMAGE_PPM }, |
49 | #endif | 55 | #endif |
50 | }; | 56 | }; |
57 | static const struct { | ||
58 | char *magic; /* magic number */ | ||
59 | int length; /* length of the magic number */ | ||
60 | enum image_type type; | ||
61 | } magic_list[] = { | ||
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 }, | ||
65 | #ifdef HAVE_LCD_COLOR | ||
66 | { "P3", 2, IMAGE_PPM }, | ||
67 | { "P6", 2, IMAGE_PPM }, | ||
68 | #endif | ||
69 | }; | ||
51 | 70 | ||
71 | enum image_type type = IMAGE_UNKNOWN; | ||
52 | const char *ext = rb->strrchr(name, '.'); | 72 | const char *ext = rb->strrchr(name, '.'); |
53 | int i; | 73 | int i, fd; |
54 | if (!ext) | 74 | char buf[12]; |
55 | return IMAGE_UNKNOWN; | 75 | |
76 | /* check file extention */ | ||
77 | if (ext) | ||
78 | { | ||
79 | for (i = 0; i < (int)ARRAYLEN(ext_list); i++) | ||
80 | { | ||
81 | if (!rb->strcasecmp(ext, ext_list[i].ext)) | ||
82 | { | ||
83 | type = ext_list[i].type; | ||
84 | break; | ||
85 | } | ||
86 | } | ||
87 | } | ||
56 | 88 | ||
57 | for (i = 0; i < (int)ARRAYLEN(ext_list); i++) | 89 | /* check magic value in the file */ |
90 | fd = rb->open(name, O_RDONLY); | ||
91 | if (fd >= 0) | ||
58 | { | 92 | { |
59 | if (!rb->strcasecmp(ext, ext_list[i].ext)) | 93 | rb->memset(buf, 0, sizeof buf); |
60 | return ext_list[i].type; | 94 | rb->read(fd, buf, sizeof buf); |
95 | rb->close(fd); | ||
96 | for (i = 0; i < (int)ARRAYLEN(magic_list); i++) | ||
97 | { | ||
98 | if (!rb->memcmp(buf, magic_list[i].magic, magic_list[i].length)) | ||
99 | { | ||
100 | if (!quiet && type != magic_list[i].type) | ||
101 | { | ||
102 | /* file extension is wrong. */ | ||
103 | rb->splashf(HZ*1, "Note: File extension is not correct"); | ||
104 | } | ||
105 | type = magic_list[i].type; | ||
106 | break; | ||
107 | } | ||
108 | } | ||
61 | } | 109 | } |
62 | return IMAGE_UNKNOWN; | 110 | return type; |
63 | } | 111 | } |
64 | 112 | ||
65 | static void *decoder_handle = NULL; | 113 | static void *decoder_handle = NULL; |
@@ -79,7 +127,7 @@ const struct image_decoder *load_decoder(struct loader_info *loader_info) | |||
79 | release_decoder(); | 127 | release_decoder(); |
80 | 128 | ||
81 | name = decoder_names[loader_info->type]; | 129 | name = decoder_names[loader_info->type]; |
82 | rb->snprintf(filename, MAX_PATH, VIEWERS_DIR "/%s.ovl", name); | 130 | rb->snprintf(filename, MAX_PATH, "/rockbox/rocks/viewers" "/%s.ovl", name); |
83 | 131 | ||
84 | /* load decoder to the buffer. */ | 132 | /* load decoder to the buffer. */ |
85 | decoder_handle = rb->lc_open(filename, loader_info->buffer, loader_info->size); | 133 | decoder_handle = rb->lc_open(filename, loader_info->buffer, loader_info->size); |
diff --git a/apps/plugins/imageviewer/image_decoder.h b/apps/plugins/imageviewer/image_decoder.h index 1ccf9cabf2..3267d2af6e 100644 --- a/apps/plugins/imageviewer/image_decoder.h +++ b/apps/plugins/imageviewer/image_decoder.h | |||
@@ -42,8 +42,11 @@ struct loader_info { | |||
42 | size_t size; | 42 | size_t size; |
43 | }; | 43 | }; |
44 | 44 | ||
45 | enum image_type get_image_type(const char *name); | 45 | /* Check file type by magic number or file extension */ |
46 | enum image_type get_image_type(const char *name, bool quiet); | ||
47 | /* Load image decoder */ | ||
46 | const struct image_decoder *load_decoder(struct loader_info *loader_info); | 48 | const struct image_decoder *load_decoder(struct loader_info *loader_info); |
49 | /* Release the loaded decoder */ | ||
47 | void release_decoder(void); | 50 | void release_decoder(void); |
48 | 51 | ||
49 | #endif /* _IMAGE_DECODER_H */ | 52 | #endif /* _IMAGE_DECODER_H */ |
diff --git a/apps/plugins/imageviewer/imageviewer.c b/apps/plugins/imageviewer/imageviewer.c index 37610b7bf6..6cc2192cb9 100644 --- a/apps/plugins/imageviewer/imageviewer.c +++ b/apps/plugins/imageviewer/imageviewer.c | |||
@@ -148,8 +148,8 @@ static void get_pic_list(void) | |||
148 | 148 | ||
149 | for (i = 0; i < tree->filesindir && buf_size > sizeof(char**); i++) | 149 | for (i = 0; i < tree->filesindir && buf_size > sizeof(char**); i++) |
150 | { | 150 | { |
151 | if (!(dircache[i].attr & ATTR_DIRECTORY) | 151 | /* Add all files. Non-image files will be filtered out while loading. */ |
152 | && get_image_type(dircache[i].name) != IMAGE_UNKNOWN) | 152 | if (!(dircache[i].attr & ATTR_DIRECTORY)) |
153 | { | 153 | { |
154 | file_pt[entries] = dircache[i].name; | 154 | file_pt[entries] = dircache[i].name; |
155 | /* Set Selected File. */ | 155 | /* Set Selected File. */ |
@@ -742,7 +742,13 @@ static int load_and_show(char* filename, struct image_info *info) | |||
742 | 742 | ||
743 | rb->lcd_clear_display(); | 743 | rb->lcd_clear_display(); |
744 | 744 | ||
745 | status = get_image_type(filename); | 745 | /* suppress warning while running slideshow */ |
746 | status = get_image_type(filename, iv_api.running_slideshow); | ||
747 | if (status == IMAGE_UNKNOWN) { | ||
748 | /* file isn't supported image file, skip this. */ | ||
749 | file_pt[curfile] = NULL; | ||
750 | return change_filename(direction); | ||
751 | } | ||
746 | if (image_type != status) /* type of image is changed, load decoder. */ | 752 | if (image_type != status) /* type of image is changed, load decoder. */ |
747 | { | 753 | { |
748 | struct loader_info loader_info = { | 754 | struct loader_info loader_info = { |
@@ -914,7 +920,7 @@ enum plugin_status plugin_start(const void* parameter) | |||
914 | if(!parameter) return PLUGIN_ERROR; | 920 | if(!parameter) return PLUGIN_ERROR; |
915 | 921 | ||
916 | rb->strcpy(np_file, parameter); | 922 | rb->strcpy(np_file, parameter); |
917 | if (get_image_type(np_file) == IMAGE_UNKNOWN) | 923 | if (get_image_type(np_file, false) == IMAGE_UNKNOWN) |
918 | { | 924 | { |
919 | rb->splash(HZ*2, "Unsupported file"); | 925 | rb->splash(HZ*2, "Unsupported file"); |
920 | return PLUGIN_ERROR; | 926 | return PLUGIN_ERROR; |