ImBuf: pass the number of bytes read to 'is_a' callbacks
Previously the header was a fixed size and assumed to be zeroed. Now read in bytes up to `HEADER_SIZE`, pass the number or bytes read to the callback which must not read past those bytes.
This commit is contained in:
parent
fa81a42539
commit
f284a40385
|
@ -120,8 +120,8 @@ const char *imb_ext_audio[] = {
|
|||
/* Increased from 32 to 64 because of the bitmaps header size. */
|
||||
#define HEADER_SIZE 64
|
||||
|
||||
static bool imb_ispic_read_header_from_filepath(const char *filepath,
|
||||
unsigned char buf[HEADER_SIZE])
|
||||
static ssize_t imb_ispic_read_header_from_filepath(const char *filepath,
|
||||
unsigned char buf[HEADER_SIZE])
|
||||
{
|
||||
BLI_stat_t st;
|
||||
int fp;
|
||||
|
@ -133,43 +133,27 @@ static bool imb_ispic_read_header_from_filepath(const char *filepath,
|
|||
}
|
||||
|
||||
if (BLI_stat(filepath, &st) == -1) {
|
||||
return false;
|
||||
return -1;
|
||||
}
|
||||
if (((st.st_mode) & S_IFMT) != S_IFREG) {
|
||||
return false;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((fp = BLI_open(filepath, O_BINARY | O_RDONLY, 0)) == -1) {
|
||||
return false;
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(buf, 0, HEADER_SIZE);
|
||||
if (read(fp, buf, HEADER_SIZE) <= 0) {
|
||||
close(fp);
|
||||
return false;
|
||||
}
|
||||
const ssize_t size = read(fp, buf, HEADER_SIZE);
|
||||
|
||||
close(fp);
|
||||
return true;
|
||||
return size;
|
||||
}
|
||||
|
||||
int IMB_ispic_type_from_memory(const unsigned char *mem, const size_t mem_size)
|
||||
int IMB_ispic_type_from_memory(const unsigned char *buf, const size_t buf_size)
|
||||
{
|
||||
unsigned char buf_static[HEADER_SIZE];
|
||||
const unsigned char *buf;
|
||||
|
||||
if (mem_size >= HEADER_SIZE) {
|
||||
buf = buf_static;
|
||||
}
|
||||
else {
|
||||
memset(buf_static, 0, HEADER_SIZE);
|
||||
memcpy(buf_static, mem, mem_size);
|
||||
buf = buf_static;
|
||||
}
|
||||
|
||||
for (const ImFileType *type = IMB_FILE_TYPES; type < IMB_FILE_TYPES_LAST; type++) {
|
||||
if (type->is_a != NULL) {
|
||||
if (type->is_a(buf, HEADER_SIZE)) {
|
||||
if (type->is_a(buf, buf_size)) {
|
||||
return type->filetype;
|
||||
}
|
||||
}
|
||||
|
@ -181,17 +165,19 @@ int IMB_ispic_type_from_memory(const unsigned char *mem, const size_t mem_size)
|
|||
int IMB_ispic_type(const char *filepath)
|
||||
{
|
||||
unsigned char buf[HEADER_SIZE];
|
||||
if (!imb_ispic_read_header_from_filepath(filepath, buf)) {
|
||||
const ssize_t buf_size = imb_ispic_read_header_from_filepath(filepath, buf);
|
||||
if (buf_size <= 0) {
|
||||
return 0;
|
||||
}
|
||||
return IMB_ispic_type_from_memory(buf, HEADER_SIZE);
|
||||
return IMB_ispic_type_from_memory(buf, (size_t)buf_size);
|
||||
}
|
||||
|
||||
bool IMB_ispic_type_matches(const char *filepath, int filetype)
|
||||
{
|
||||
unsigned char buf[HEADER_SIZE];
|
||||
if (!imb_ispic_read_header_from_filepath(filepath, buf)) {
|
||||
return 0;
|
||||
const ssize_t buf_size = imb_ispic_read_header_from_filepath(filepath, buf);
|
||||
if (buf_size <= 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (const ImFileType *type = IMB_FILE_TYPES; type < IMB_FILE_TYPES_LAST; type++) {
|
||||
|
@ -200,11 +186,11 @@ bool IMB_ispic_type_matches(const char *filepath, int filetype)
|
|||
* Keep the check for developers. */
|
||||
BLI_assert(type->is_a != NULL);
|
||||
if (type->is_a != NULL) {
|
||||
return type->is_a(buf, HEADER_SIZE);
|
||||
return type->is_a(buf, (size_t)buf_size);
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
#undef HEADER_SIZE
|
||||
|
@ -360,7 +346,6 @@ static int isffmpeg(const char *filepath)
|
|||
|
||||
int imb_get_anim_type(const char *filepath)
|
||||
{
|
||||
int type;
|
||||
BLI_stat_t st;
|
||||
|
||||
BLI_assert(!BLI_path_is_rel(filepath));
|
||||
|
@ -390,7 +375,7 @@ int imb_get_anim_type(const char *filepath)
|
|||
if (ismovie(filepath)) {
|
||||
return ANIM_MOVIE;
|
||||
}
|
||||
#else
|
||||
#else /* !_WIN32 */
|
||||
if (BLI_stat(filepath, &st) == -1) {
|
||||
return 0;
|
||||
}
|
||||
|
@ -410,9 +395,10 @@ int imb_get_anim_type(const char *filepath)
|
|||
if (isavi(filepath)) {
|
||||
return ANIM_AVI;
|
||||
}
|
||||
#endif
|
||||
type = IMB_ispic(filepath);
|
||||
if (type) {
|
||||
#endif /* !_WIN32 */
|
||||
|
||||
/* Assume a single image is part of an image sequence. */
|
||||
if (IMB_ispic(filepath)) {
|
||||
return ANIM_SEQUENCE;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue