Fix #107212: Fix file browser thumbnails for images

Fix several issues found while investigating missing browser thumbnails.

TIFF, PSD, and PNG now use their old file check code. This is due to
OIIO not having an early-out check within `.open`. Calling `.open`
required a large portion of the file to be available (more than 8192
bytes). The code here can be removed in the future if/when a new API is
available which alleviates this problem.

PSD files often carry along a large blob of ICCProfile metadata.
Attempting to roundtrip this metadata when we cache the thumbnail to
.png was leading to problems. We suppress this metadata now as ICC
profiles are not supported in general and are quite large.

Lastly, even after the mentioned new API is available, OIIO will want to
validate the full header of some file formats. DPX is the largest at a
full 2048 bytes so we must have this as our minimum now too. OS's should
be servicing this read call just as efficiently as when using 64. I
could spot no performance difference here at least.

This was missed during development because Blender will cache thumbnails
into a special .thumbnails directory and the images I was using to test
had already been cached there.

Pull Request: https://projects.blender.org/blender/blender/pulls/107515
This commit is contained in:
Jesse Yurkovich
2023-05-06 00:16:19 +02:00
committed by Jesse Yurkovich
parent fcddc1a1af
commit 5cc8fea7e9
5 changed files with 24 additions and 5 deletions

View File

@@ -13,7 +13,11 @@ extern "C" {
bool imb_is_a_png(const uchar *mem, size_t size)
{
return imb_oiio_check(mem, size, "png");
const char signature[] = {0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A};
if (size < sizeof(signature)) {
return false;
}
return memcmp(signature, mem, sizeof(signature)) == 0;
}
ImBuf *imb_load_png(const uchar *mem, size_t size, int flags, char colorspace[IM_MAX_SPACE])

View File

@@ -13,7 +13,11 @@ extern "C" {
bool imb_is_a_psd(const uchar *mem, size_t size)
{
return imb_oiio_check(mem, size, "psd");
const uchar magic[4] = {'8', 'B', 'P', 'S'};
if (size < sizeof(magic)) {
return false;
}
return memcmp(magic, mem, sizeof(magic)) == 0;
}
ImBuf *imb_load_psd(const uchar *mem, size_t size, int flags, char colorspace[IM_MAX_SPACE])

View File

@@ -13,7 +13,15 @@ extern "C" {
bool imb_is_a_tiff(const uchar *mem, size_t size)
{
return imb_oiio_check(mem, size, "tif");
constexpr int MAGIC_SIZE = 4;
if (size < MAGIC_SIZE) {
return false;
}
const char big_endian[MAGIC_SIZE] = {0x4d, 0x4d, 0x00, 0x2a};
const char lil_endian[MAGIC_SIZE] = {0x49, 0x49, 0x2a, 0x00};
return ((memcmp(big_endian, mem, MAGIC_SIZE) == 0) ||
(memcmp(lil_endian, mem, MAGIC_SIZE) == 0));
}
ImBuf *imb_load_tiff(const uchar *mem, size_t size, int flags, char colorspace[IM_MAX_SPACE])

View File

@@ -225,6 +225,9 @@ static ImBuf *get_oiio_ibuf(ImageInput *in, const ReadContext &ctx, char colorsp
ibuf->flags |= spec.extra_attribs.empty() ? 0 : IB_metadata;
for (const auto &attrib : spec.extra_attribs) {
if (attrib.name().find("ICCProfile") != string::npos) {
continue;
}
IMB_metadata_set_field(ibuf->metadata, attrib.name().c_str(), attrib.get_string().c_str());
}
}

View File

@@ -88,8 +88,8 @@ const char *imb_ext_audio[] = {
nullptr,
};
/* Increased from 32 to 64 because of the bitmaps header size. */
#define HEADER_SIZE 64
/* OIIO will validate the entire header of some files and DPX requires 2048 */
#define HEADER_SIZE 2048
static ssize_t imb_ispic_read_header_from_filepath(const char *filepath, uchar buf[HEADER_SIZE])
{