summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTeruaki Kawashima <teru@rockbox.org>2011-01-22 13:41:53 +0000
committerTeruaki Kawashima <teru@rockbox.org>2011-01-22 13:41:53 +0000
commit68cc564c9bd327743896cded4a49aad7af0b1d37 (patch)
tree4a9225f4ec586ba69818bc90d74630581c8ec1f2
parent060609a2023bfcc99472cfe4e94a2cc3704bd92c (diff)
downloadrockbox-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.c68
-rw-r--r--apps/plugins/imageviewer/image_decoder.h5
-rw-r--r--apps/plugins/imageviewer/imageviewer.c14
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
36enum 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 */
42enum 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
65static void *decoder_handle = NULL; 113static 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
45enum image_type get_image_type(const char *name); 45/* Check file type by magic number or file extension */
46enum image_type get_image_type(const char *name, bool quiet);
47/* Load image decoder */
46const struct image_decoder *load_decoder(struct loader_info *loader_info); 48const struct image_decoder *load_decoder(struct loader_info *loader_info);
49/* Release the loaded decoder */
47void release_decoder(void); 50void 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;