Index: apps/plugins/imageviewer/imageviewer.c =================================================================== --- apps/plugins/imageviewer/imageviewer.c (リビジョン 28900) +++ 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. */ @@ -721,7 +722,13 @@ rb->lcd_clear_display(); - status = get_image_type(filename); + /* suppress warning while running slideshow */ + status = get_image_type(filename, !iv_api.running_slideshow); + 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 = { @@ -893,7 +900,7 @@ if(!parameter) return PLUGIN_ERROR; rb->strcpy(np_file, parameter); - if (get_image_type(np_file) == IMAGE_UNKNOWN) + if (get_image_type(np_file, false) == IMAGE_UNKNOWN) { rb->splash(HZ*2, "Unsupported file"); return PLUGIN_ERROR; Index: apps/plugins/imageviewer/image_decoder.c =================================================================== --- apps/plugins/imageviewer/image_decoder.c (リビジョン 28900) +++ apps/plugins/imageviewer/image_decoder.c (作業コピー) @@ -29,8 +29,14 @@ "png", }; -/* 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, + * error message will be shown and user will know something is wrong. + */ +enum image_type get_image_type(const char *name, bool warn) { static const struct { char *ext; @@ -42,18 +48,61 @@ { ".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; + } + } } - 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 (warn && type != magic_list[i].type) + { + /* file extension is wrong. */ + rb->splashf(HZ*1, + "File extension might not be correct: %s", ext); + } + 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 (リビジョン 28900) +++ apps/plugins/imageviewer/image_decoder.h (作業コピー) @@ -39,8 +39,11 @@ size_t size; }; -enum image_type get_image_type(const char *name); +/* check file type by magic number or file extension */ +enum image_type get_image_type(const char *name, bool warn); +/* 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 */