Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2020-11-10 14:16:29 +0300
committerCampbell Barton <ideasman42@gmail.com>2020-11-10 14:25:05 +0300
commit23c71a5fab42e22266196a45f1f2ac77e815bcd3 (patch)
tree66dd61354a80166b99de0539b1f704ba3986f396 /source/blender/imbuf/intern/util.c
parentd2ab9b568e854457414e779dcceb6f48968de4d0 (diff)
ImBuf: support detecting the file format from in-memory images
Add `IMB_ispic_type_from_memory` so we can detect the file format of in-memory images. This removes `is_a_filepath` callback and uses a magic check for photo-shop files that's compatible with OIIO. Even though OIIO doesn't support packed images, we can still use the file magic for detecting the format. This change allows D9500 (a fix for unpacking images), to be implemented without a significant performance penalty, although the actual performance cost would depend heavily on the blend file. Reviewed By: dfelinto, sergey Ref D9517
Diffstat (limited to 'source/blender/imbuf/intern/util.c')
-rw-r--r--source/blender/imbuf/intern/util.c62
1 files changed, 49 insertions, 13 deletions
diff --git a/source/blender/imbuf/intern/util.c b/source/blender/imbuf/intern/util.c
index 7be58a9ca14..37a1afb5dd7 100644
--- a/source/blender/imbuf/intern/util.c
+++ b/source/blender/imbuf/intern/util.c
@@ -117,13 +117,11 @@ const char *imb_ext_audio[] = {
NULL,
};
-int IMB_ispic_type(const char *name)
-{
- /* increased from 32 to 64 because of the bitmaps header size */
+/* Increased from 32 to 64 because of the bitmaps header size. */
#define HEADER_SIZE 64
- unsigned char buf[HEADER_SIZE];
- const ImFileType *type;
+static bool imb_ispic_read_header_from_filename(const char *name, unsigned char buf[HEADER_SIZE])
+{
BLI_stat_t st;
int fp;
@@ -144,32 +142,70 @@ int IMB_ispic_type(const char *name)
return false;
}
- memset(buf, 0, sizeof(buf));
+ memset(buf, 0, HEADER_SIZE);
if (read(fp, buf, HEADER_SIZE) <= 0) {
close(fp);
return false;
}
close(fp);
+ return true;
+}
- for (type = IMB_FILE_TYPES; type < IMB_FILE_TYPES_LAST; type++) {
+int IMB_ispic_type_from_memory(const unsigned char *mem, const size_t mem_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) {
if (type->is_a(buf)) {
return type->filetype;
}
}
- else if (type->is_a_filepath) {
- if (type->is_a_filepath(name)) {
- return type->filetype;
- }
- }
}
return 0;
+}
-#undef HEADER_SIZE
+int IMB_ispic_type(const char *name)
+{
+ unsigned char buf[HEADER_SIZE];
+ if (!imb_ispic_read_header_from_filename(name, buf)) {
+ return false;
+ }
+ return IMB_ispic_type_from_memory(buf, HEADER_SIZE);
}
+bool IMB_ispic_type_matches(const char *name, int filetype)
+{
+ unsigned char buf[HEADER_SIZE];
+ if (!imb_ispic_read_header_from_filename(name, buf)) {
+ return false;
+ }
+
+ for (const ImFileType *type = IMB_FILE_TYPES; type < IMB_FILE_TYPES_LAST; type++) {
+ if (type->filetype == filetype) {
+ /* Requesting to load a type that can't check it's own header doesn't make sense.
+ * Keep the check for developers. */
+ BLI_assert(type->is_a != NULL);
+ return type->is_a ? type->is_a(buf) : false;
+ }
+ }
+ return false;
+}
+
+#undef HEADER_SIZE
+
bool IMB_ispic(const char *name)
{
return (IMB_ispic_type(name) != 0);