Index: apps/plugins/imageviewer/imageviewer.c =================================================================== --- apps/plugins/imageviewer/imageviewer.c (リビジョン 28871) +++ apps/plugins/imageviewer/imageviewer.c (作業コピー) @@ -148,8 +148,9 @@ for (i = 0; i < tree->filesindir && buf_size > sizeof(char**); i++) { - if (!(dircache[i].attr & ATTR_DIRECTORY) - && get_image_type(dircache[i].name) != IMAGE_UNKNOWN) + /* add all files (i.e. exclude all directory). will be filtered out + when loading. */ + if (!(dircache[i].attr & ATTR_DIRECTORY)) { file_pt[entries] = dircache[i].name; /* Set Selected File. */ @@ -722,6 +723,11 @@ rb->lcd_clear_display(); status = get_image_type(filename); + if (status == IMAGE_UNKNOWN) { + /* file isn't supported image file, skip this. */ + file_pt[curfile] = NULL; + return change_filename(direction); + } if (image_type != status) /* type of image is changed, load decoder. */ { struct loader_info loader_info = { Index: apps/plugins/imageviewer/image_decoder.c =================================================================== --- apps/plugins/imageviewer/image_decoder.c (リビジョン 28871) +++ apps/plugins/imageviewer/image_decoder.c (作業コピー) @@ -29,7 +29,13 @@ "png", }; -/* check file type by extention */ +/* 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 file extension is one of supported image but magic number is not correct, + * error message will be shown and user will know something is wrong. + */ enum image_type get_image_type(const char *name) { static const struct { @@ -42,18 +48,63 @@ { ".jpeg", IMAGE_JPEG }, { ".png", IMAGE_PNG }, }; + static const struct { + char *magic; /* magic number */ + int length; /* length of the magic number */ + enum image_type type; + } magic_list[] = { + { "\x42\x4d", 2, IMAGE_BMP }, + { "\xff\xd8\xff\xe0", 4, IMAGE_JPEG }, + { "\x89\x50\x4e\x47\x0d\x0a\x1a\x0a", 8, IMAGE_PNG }, + }; + 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]; - for (i = 0; i < (int)ARRAYLEN(ext_list); i++) + /* check file extention */ + if (ext) { - if (!rb->strcasecmp(ext, ext_list[i].ext)) - return ext_list[i].type; + for (i = 0; i < (int)ARRAYLEN(ext_list); i++) + { + if (!rb->strcasecmp(ext, ext_list[i].ext)) + { + type = ext_list[i].type; + break; + } + } + ext++; /* skip dot */ } - return IMAGE_UNKNOWN; + else + { + ext = "???"; + } + + /* check magic value in the file */ + fd = rb->open(name, O_RDONLY); + if (fd >= 0) + { + 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 (type != magic_list[i].type) + { + /* file extension is wrong. */ + rb->splashf(HZ*1, + "File extension is not correct: %s -> %s", + ext, decoder_names[magic_list[i].type]); + } + type = magic_list[i].type; + break; + } + } + } + return type; } static void *decoder_handle = NULL; Index: apps/plugins/imageviewer/image_decoder.h =================================================================== --- apps/plugins/imageviewer/image_decoder.h (リビジョン 28871) +++ apps/plugins/imageviewer/image_decoder.h (作業コピー) @@ -39,8 +39,11 @@ size_t size; }; +/* check file type by magic number or file extension */ enum image_type get_image_type(const char *name); +/* load image decoder */ const struct image_decoder *load_decoder(struct loader_info *loader_info); +/* release the loaded decoder */ void release_decoder(void); #endif /* _IMAGE_DECODER_H */