diff options
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] = { | |||
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); |