forked from len0rd/rockbox
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
This commit is contained in:
parent
060609a202
commit
68cc564c9b
3 changed files with 72 additions and 15 deletions
|
@ -32,8 +32,14 @@ static const char *decoder_names[MAX_IMAGE_TYPES] = {
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
/* check file type by extention */
|
/* Check file type by magic number or file extension
|
||||||
enum image_type get_image_type(const char *name)
|
*
|
||||||
|
* 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,
|
||||||
|
* informs user that something is wrong.
|
||||||
|
*/
|
||||||
|
enum image_type get_image_type(const char *name, bool quiet)
|
||||||
{
|
{
|
||||||
static const struct {
|
static const struct {
|
||||||
char *ext;
|
char *ext;
|
||||||
|
@ -48,18 +54,60 @@ enum image_type get_image_type(const char *name)
|
||||||
{ ".ppm", IMAGE_PPM },
|
{ ".ppm", IMAGE_PPM },
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
static const struct {
|
||||||
|
char *magic; /* magic number */
|
||||||
|
int length; /* length of the magic number */
|
||||||
|
enum image_type type;
|
||||||
|
} magic_list[] = {
|
||||||
|
{ "BM", 2, IMAGE_BMP },
|
||||||
|
{ "\xff\xd8\xff\xe0", 4, IMAGE_JPEG },
|
||||||
|
{ "\x89\x50\x4e\x47\x0d\x0a\x1a\x0a", 8, IMAGE_PNG },
|
||||||
|
#ifdef HAVE_LCD_COLOR
|
||||||
|
{ "P3", 2, IMAGE_PPM },
|
||||||
|
{ "P6", 2, IMAGE_PPM },
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
enum image_type type = IMAGE_UNKNOWN;
|
||||||
const char *ext = rb->strrchr(name, '.');
|
const char *ext = rb->strrchr(name, '.');
|
||||||
int i;
|
int i, fd;
|
||||||
if (!ext)
|
char buf[12];
|
||||||
return IMAGE_UNKNOWN;
|
|
||||||
|
|
||||||
for (i = 0; i < (int)ARRAYLEN(ext_list); i++)
|
/* check file extention */
|
||||||
|
if (ext)
|
||||||
{
|
{
|
||||||
if (!rb->strcasecmp(ext, ext_list[i].ext))
|
for (i = 0; i < (int)ARRAYLEN(ext_list); i++)
|
||||||
return ext_list[i].type;
|
{
|
||||||
|
if (!rb->strcasecmp(ext, ext_list[i].ext))
|
||||||
|
{
|
||||||
|
type = ext_list[i].type;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return IMAGE_UNKNOWN;
|
|
||||||
|
/* 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 (!quiet && type != magic_list[i].type)
|
||||||
|
{
|
||||||
|
/* file extension is wrong. */
|
||||||
|
rb->splashf(HZ*1, "Note: File extension is not correct");
|
||||||
|
}
|
||||||
|
type = magic_list[i].type;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *decoder_handle = NULL;
|
static void *decoder_handle = NULL;
|
||||||
|
@ -79,7 +127,7 @@ const struct image_decoder *load_decoder(struct loader_info *loader_info)
|
||||||
release_decoder();
|
release_decoder();
|
||||||
|
|
||||||
name = decoder_names[loader_info->type];
|
name = decoder_names[loader_info->type];
|
||||||
rb->snprintf(filename, MAX_PATH, VIEWERS_DIR "/%s.ovl", name);
|
rb->snprintf(filename, MAX_PATH, "/rockbox/rocks/viewers" "/%s.ovl", name);
|
||||||
|
|
||||||
/* load decoder to the buffer. */
|
/* load decoder to the buffer. */
|
||||||
decoder_handle = rb->lc_open(filename, loader_info->buffer, loader_info->size);
|
decoder_handle = rb->lc_open(filename, loader_info->buffer, loader_info->size);
|
||||||
|
|
|
@ -42,8 +42,11 @@ struct loader_info {
|
||||||
size_t size;
|
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 quiet);
|
||||||
|
/* Load image decoder */
|
||||||
const struct image_decoder *load_decoder(struct loader_info *loader_info);
|
const struct image_decoder *load_decoder(struct loader_info *loader_info);
|
||||||
|
/* Release the loaded decoder */
|
||||||
void release_decoder(void);
|
void release_decoder(void);
|
||||||
|
|
||||||
#endif /* _IMAGE_DECODER_H */
|
#endif /* _IMAGE_DECODER_H */
|
||||||
|
|
|
@ -148,8 +148,8 @@ static void get_pic_list(void)
|
||||||
|
|
||||||
for (i = 0; i < tree->filesindir && buf_size > sizeof(char**); i++)
|
for (i = 0; i < tree->filesindir && buf_size > sizeof(char**); i++)
|
||||||
{
|
{
|
||||||
if (!(dircache[i].attr & ATTR_DIRECTORY)
|
/* Add all files. Non-image files will be filtered out while loading. */
|
||||||
&& get_image_type(dircache[i].name) != IMAGE_UNKNOWN)
|
if (!(dircache[i].attr & ATTR_DIRECTORY))
|
||||||
{
|
{
|
||||||
file_pt[entries] = dircache[i].name;
|
file_pt[entries] = dircache[i].name;
|
||||||
/* Set Selected File. */
|
/* Set Selected File. */
|
||||||
|
@ -742,7 +742,13 @@ static int load_and_show(char* filename, struct image_info *info)
|
||||||
|
|
||||||
rb->lcd_clear_display();
|
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. */
|
if (image_type != status) /* type of image is changed, load decoder. */
|
||||||
{
|
{
|
||||||
struct loader_info loader_info = {
|
struct loader_info loader_info = {
|
||||||
|
@ -914,7 +920,7 @@ enum plugin_status plugin_start(const void* parameter)
|
||||||
if(!parameter) return PLUGIN_ERROR;
|
if(!parameter) return PLUGIN_ERROR;
|
||||||
|
|
||||||
rb->strcpy(np_file, parameter);
|
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");
|
rb->splash(HZ*2, "Unsupported file");
|
||||||
return PLUGIN_ERROR;
|
return PLUGIN_ERROR;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue