forked from blender/blender
main sync #3
@ -18,6 +18,7 @@ set(INC_SYS
|
|||||||
${JPEG_INCLUDE_DIR}
|
${JPEG_INCLUDE_DIR}
|
||||||
${PNG_INCLUDE_DIRS}
|
${PNG_INCLUDE_DIRS}
|
||||||
${ZLIB_INCLUDE_DIRS}
|
${ZLIB_INCLUDE_DIRS}
|
||||||
|
${OPENIMAGEIO_INCLUDE_DIRS}
|
||||||
)
|
)
|
||||||
|
|
||||||
set(SRC
|
set(SRC
|
||||||
@ -29,6 +30,7 @@ set(SRC
|
|||||||
intern/divers.c
|
intern/divers.c
|
||||||
intern/filetype.c
|
intern/filetype.c
|
||||||
intern/filter.c
|
intern/filter.c
|
||||||
|
intern/format_psd.cc
|
||||||
intern/imageprocess.c
|
intern/imageprocess.c
|
||||||
intern/indexer.c
|
intern/indexer.c
|
||||||
intern/iris.c
|
intern/iris.c
|
||||||
|
@ -678,7 +678,7 @@ void IMB_sampleImageAtLocation(
|
|||||||
* \attention defined in readimage.c
|
* \attention defined in readimage.c
|
||||||
*/
|
*/
|
||||||
struct ImBuf *IMB_loadifffile(
|
struct ImBuf *IMB_loadifffile(
|
||||||
int file, const char *filepath, int flags, char colorspace[IM_MAX_SPACE], const char *descr);
|
int file, int flags, char colorspace[IM_MAX_SPACE], const char *descr);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \attention defined in scaling.c
|
* \attention defined in scaling.c
|
||||||
|
@ -318,9 +318,6 @@ extern const char *imb_ext_image[];
|
|||||||
extern const char *imb_ext_movie[];
|
extern const char *imb_ext_movie[];
|
||||||
extern const char *imb_ext_audio[];
|
extern const char *imb_ext_audio[];
|
||||||
|
|
||||||
/** Image formats that can only be loaded via filepath. */
|
|
||||||
extern const char *imb_ext_image_filepath_only[];
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
/** \name Imbuf Color Management Flag
|
/** \name Imbuf Color Management Flag
|
||||||
*
|
*
|
||||||
|
@ -256,3 +256,16 @@ struct ImBuf *imb_load_filepath_thumbnail_webp(const char *filepath,
|
|||||||
bool imb_savewebp(struct ImBuf *ibuf, const char *name, int flags);
|
bool imb_savewebp(struct ImBuf *ibuf, const char *name, int flags);
|
||||||
|
|
||||||
/** \} */
|
/** \} */
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------- */
|
||||||
|
/** \name Format: PSD (#IMB_FTYPE_PSD)
|
||||||
|
* \{ */
|
||||||
|
|
||||||
|
bool imb_is_a_psd(const unsigned char *buf, size_t size);
|
||||||
|
|
||||||
|
struct ImBuf *imb_load_psd(const uchar *mem,
|
||||||
|
size_t size,
|
||||||
|
int flags,
|
||||||
|
char colorspace[IM_MAX_SPACE]);
|
||||||
|
|
||||||
|
/** \} */
|
||||||
|
@ -184,9 +184,9 @@ const ImFileType IMB_FILE_TYPES[] = {
|
|||||||
{
|
{
|
||||||
.init = NULL,
|
.init = NULL,
|
||||||
.exit = NULL,
|
.exit = NULL,
|
||||||
.is_a = imb_is_a_photoshop,
|
.is_a = imb_is_a_psd,
|
||||||
.load = NULL,
|
.load = imb_load_psd,
|
||||||
.load_filepath = imb_load_photoshop,
|
.load_filepath = NULL,
|
||||||
.load_filepath_thumbnail = NULL,
|
.load_filepath_thumbnail = NULL,
|
||||||
.save = NULL,
|
.save = NULL,
|
||||||
.flag = IM_FTYPE_FLOAT,
|
.flag = IM_FTYPE_FLOAT,
|
||||||
|
29
source/blender/imbuf/intern/format_psd.cc
Normal file
29
source/blender/imbuf/intern/format_psd.cc
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||||
|
|
||||||
|
#include "oiio/openimageio_support.hh"
|
||||||
|
|
||||||
|
#include "IMB_imbuf_types.h"
|
||||||
|
|
||||||
|
OIIO_NAMESPACE_USING
|
||||||
|
using namespace blender::imbuf;
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
|
||||||
|
bool imb_is_a_psd(const uchar *mem, size_t size)
|
||||||
|
{
|
||||||
|
return imb_oiio_check(mem, size, "psd");
|
||||||
|
}
|
||||||
|
|
||||||
|
ImBuf *imb_load_psd(const uchar *mem, size_t size, int flags, char colorspace[IM_MAX_SPACE])
|
||||||
|
{
|
||||||
|
ImageSpec config, spec;
|
||||||
|
config.attribute("oiio:UnassociatedAlpha", 1);
|
||||||
|
|
||||||
|
ReadContext ctx{mem, size, "psd", IMB_FTYPE_PSD, flags};
|
||||||
|
|
||||||
|
/* PSD should obey color space information embedded in the file. */
|
||||||
|
ctx.use_embedded_colorspace = true;
|
||||||
|
|
||||||
|
return imb_oiio_read(ctx, config, colorspace, spec);
|
||||||
|
}
|
||||||
|
}
|
@ -18,8 +18,10 @@ set(INC_SYS
|
|||||||
|
|
||||||
set(SRC
|
set(SRC
|
||||||
openimageio_api.h
|
openimageio_api.h
|
||||||
|
openimageio_support.hh
|
||||||
|
|
||||||
openimageio_api.cpp
|
openimageio_api.cpp
|
||||||
|
openimageio_support.cc
|
||||||
)
|
)
|
||||||
|
|
||||||
set(LIB
|
set(LIB
|
||||||
|
@ -5,278 +5,16 @@
|
|||||||
* \ingroup openimageio
|
* \ingroup openimageio
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <set>
|
|
||||||
|
|
||||||
#if defined(WIN32)
|
|
||||||
# include "utfconv.h"
|
|
||||||
# define _USE_MATH_DEFINES
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* NOTE: Keep first, #BLI_path_util conflicts with OIIO's format. */
|
|
||||||
#include "openimageio_api.h"
|
#include "openimageio_api.h"
|
||||||
#include <OpenImageIO/imageio.h>
|
#include <OpenImageIO/imageio.h>
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
#include "MEM_guardedalloc.h"
|
|
||||||
|
|
||||||
#include "BLI_blenlib.h"
|
|
||||||
|
|
||||||
#include "IMB_allocimbuf.h"
|
|
||||||
#include "IMB_colormanagement.h"
|
|
||||||
#include "IMB_colormanagement_intern.h"
|
|
||||||
#include "IMB_imbuf.h"
|
|
||||||
#include "IMB_imbuf_types.h"
|
|
||||||
|
|
||||||
OIIO_NAMESPACE_USING
|
OIIO_NAMESPACE_USING
|
||||||
|
|
||||||
using std::string;
|
|
||||||
using std::unique_ptr;
|
|
||||||
|
|
||||||
using uchar = uchar;
|
|
||||||
|
|
||||||
template<class T, class Q>
|
|
||||||
static void fill_all_channels(T *pixels, int width, int height, int components, Q alpha)
|
|
||||||
{
|
|
||||||
if (components == 2) {
|
|
||||||
for (int i = width * height - 1; i >= 0; i--) {
|
|
||||||
pixels[i * 4 + 3] = pixels[i * 2 + 1];
|
|
||||||
pixels[i * 4 + 2] = pixels[i * 2 + 0];
|
|
||||||
pixels[i * 4 + 1] = pixels[i * 2 + 0];
|
|
||||||
pixels[i * 4 + 0] = pixels[i * 2 + 0];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (components == 3) {
|
|
||||||
for (int i = width * height - 1; i >= 0; i--) {
|
|
||||||
pixels[i * 4 + 3] = alpha;
|
|
||||||
pixels[i * 4 + 2] = pixels[i * 3 + 2];
|
|
||||||
pixels[i * 4 + 1] = pixels[i * 3 + 1];
|
|
||||||
pixels[i * 4 + 0] = pixels[i * 3 + 0];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (components == 1) {
|
|
||||||
for (int i = width * height - 1; i >= 0; i--) {
|
|
||||||
pixels[i * 4 + 3] = alpha;
|
|
||||||
pixels[i * 4 + 2] = pixels[i];
|
|
||||||
pixels[i * 4 + 1] = pixels[i];
|
|
||||||
pixels[i * 4 + 0] = pixels[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static ImBuf *imb_oiio_load_image(
|
|
||||||
ImageInput *in, int width, int height, int components, int flags, bool is_alpha)
|
|
||||||
{
|
|
||||||
ImBuf *ibuf;
|
|
||||||
int scanlinesize = width * components * sizeof(uchar);
|
|
||||||
|
|
||||||
/* allocate the memory for the image */
|
|
||||||
ibuf = IMB_allocImBuf(width, height, is_alpha ? 32 : 24, flags | IB_rect);
|
|
||||||
|
|
||||||
try {
|
|
||||||
if (!in->read_image(0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
components,
|
|
||||||
TypeDesc::UINT8,
|
|
||||||
(uchar *)ibuf->rect + (height - 1) * scanlinesize,
|
|
||||||
AutoStride,
|
|
||||||
-scanlinesize,
|
|
||||||
AutoStride)) {
|
|
||||||
std::cerr << __func__ << ": ImageInput::read_image() failed:" << std::endl
|
|
||||||
<< in->geterror() << std::endl;
|
|
||||||
|
|
||||||
if (ibuf) {
|
|
||||||
IMB_freeImBuf(ibuf);
|
|
||||||
}
|
|
||||||
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (const std::exception &exc) {
|
|
||||||
std::cerr << exc.what() << std::endl;
|
|
||||||
if (ibuf) {
|
|
||||||
IMB_freeImBuf(ibuf);
|
|
||||||
}
|
|
||||||
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ImBuf always needs 4 channels */
|
|
||||||
fill_all_channels((uchar *)ibuf->rect, width, height, components, 0xFF);
|
|
||||||
|
|
||||||
return ibuf;
|
|
||||||
}
|
|
||||||
|
|
||||||
static ImBuf *imb_oiio_load_image_float(
|
|
||||||
ImageInput *in, int width, int height, int components, int flags, bool is_alpha)
|
|
||||||
{
|
|
||||||
ImBuf *ibuf;
|
|
||||||
int scanlinesize = width * components * sizeof(float);
|
|
||||||
|
|
||||||
/* allocate the memory for the image */
|
|
||||||
ibuf = IMB_allocImBuf(width, height, is_alpha ? 32 : 24, flags | IB_rectfloat);
|
|
||||||
|
|
||||||
try {
|
|
||||||
if (!in->read_image(0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
components,
|
|
||||||
TypeDesc::FLOAT,
|
|
||||||
(uchar *)ibuf->rect_float + (height - 1) * scanlinesize,
|
|
||||||
AutoStride,
|
|
||||||
-scanlinesize,
|
|
||||||
AutoStride)) {
|
|
||||||
std::cerr << __func__ << ": ImageInput::read_image() failed:" << std::endl
|
|
||||||
<< in->geterror() << std::endl;
|
|
||||||
|
|
||||||
if (ibuf) {
|
|
||||||
IMB_freeImBuf(ibuf);
|
|
||||||
}
|
|
||||||
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (const std::exception &exc) {
|
|
||||||
std::cerr << exc.what() << std::endl;
|
|
||||||
if (ibuf) {
|
|
||||||
IMB_freeImBuf(ibuf);
|
|
||||||
}
|
|
||||||
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ImBuf always needs 4 channels */
|
|
||||||
fill_all_channels((float *)ibuf->rect_float, width, height, components, 1.0f);
|
|
||||||
|
|
||||||
/* NOTE: Photoshop 16 bit files never has alpha with it,
|
|
||||||
* so no need to handle associated/unassociated alpha. */
|
|
||||||
return ibuf;
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
||||||
bool imb_is_a_photoshop(const uchar *mem, size_t size)
|
|
||||||
{
|
|
||||||
const uchar magic[4] = {'8', 'B', 'P', 'S'};
|
|
||||||
if (size < sizeof(magic)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return memcmp(magic, mem, sizeof(magic)) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int imb_save_photoshop(struct ImBuf *ibuf, const char * /*name*/, int flags)
|
|
||||||
{
|
|
||||||
if (flags & IB_mem) {
|
|
||||||
std::cerr << __func__ << ": Photoshop PSD-save: Create PSD in memory"
|
|
||||||
<< " currently not supported" << std::endl;
|
|
||||||
imb_addencodedbufferImBuf(ibuf);
|
|
||||||
ibuf->encodedsize = 0;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct ImBuf *imb_load_photoshop(const char *filename, int flags, char colorspace[IM_MAX_SPACE])
|
|
||||||
{
|
|
||||||
struct ImBuf *ibuf = nullptr;
|
|
||||||
int width, height, components;
|
|
||||||
bool is_float, is_alpha, is_half;
|
|
||||||
int basesize;
|
|
||||||
char file_colorspace[IM_MAX_SPACE];
|
|
||||||
const bool is_colorspace_manually_set = (colorspace[0] != '\0');
|
|
||||||
|
|
||||||
/* load image from file through OIIO */
|
|
||||||
if (IMB_ispic_type_matches(filename, IMB_FTYPE_PSD) == 0) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
colorspace_set_default_role(colorspace, IM_MAX_SPACE, COLOR_ROLE_DEFAULT_BYTE);
|
|
||||||
|
|
||||||
unique_ptr<ImageInput> in(ImageInput::create(filename));
|
|
||||||
if (!in) {
|
|
||||||
std::cerr << __func__ << ": ImageInput::create() failed:" << std::endl
|
|
||||||
<< OIIO_NAMESPACE::geterror() << std::endl;
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
ImageSpec spec, config;
|
|
||||||
config.attribute("oiio:UnassociatedAlpha", int(1));
|
|
||||||
|
|
||||||
if (!in->open(filename, spec, config)) {
|
|
||||||
std::cerr << __func__ << ": ImageInput::open() failed:" << std::endl
|
|
||||||
<< in->geterror() << std::endl;
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!is_colorspace_manually_set) {
|
|
||||||
string ics = spec.get_string_attribute("oiio:ColorSpace");
|
|
||||||
BLI_strncpy(file_colorspace, ics.c_str(), IM_MAX_SPACE);
|
|
||||||
|
|
||||||
/* Only use color-spaces exist. */
|
|
||||||
if (colormanage_colorspace_get_named(file_colorspace)) {
|
|
||||||
strcpy(colorspace, file_colorspace);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
std::cerr << __func__ << ": The embed colorspace (\"" << file_colorspace
|
|
||||||
<< "\") not supported in existent OCIO configuration file. Fallback "
|
|
||||||
<< "to system default colorspace (\"" << colorspace << "\")." << std::endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
width = spec.width;
|
|
||||||
height = spec.height;
|
|
||||||
components = spec.nchannels;
|
|
||||||
is_alpha = spec.alpha_channel != -1;
|
|
||||||
basesize = spec.format.basesize();
|
|
||||||
is_float = basesize > 1;
|
|
||||||
is_half = spec.format == TypeDesc::HALF;
|
|
||||||
|
|
||||||
/* we only handle certain number of components */
|
|
||||||
if (!(components >= 1 && components <= 4)) {
|
|
||||||
if (in) {
|
|
||||||
in->close();
|
|
||||||
}
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is_float) {
|
|
||||||
ibuf = imb_oiio_load_image_float(in.get(), width, height, components, flags, is_alpha);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
ibuf = imb_oiio_load_image(in.get(), width, height, components, flags, is_alpha);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (in) {
|
|
||||||
in->close();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!ibuf) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ImBuf always needs 4 channels */
|
|
||||||
ibuf->ftype = IMB_FTYPE_PSD;
|
|
||||||
ibuf->channels = 4;
|
|
||||||
ibuf->planes = (3 + (is_alpha ? 1 : 0)) * 4 << basesize;
|
|
||||||
ibuf->flags |= (is_float && is_half) ? IB_halffloat : 0;
|
|
||||||
|
|
||||||
try {
|
|
||||||
return ibuf;
|
|
||||||
}
|
|
||||||
catch (const std::exception &exc) {
|
|
||||||
std::cerr << exc.what() << std::endl;
|
|
||||||
if (ibuf) {
|
|
||||||
IMB_freeImBuf(ibuf);
|
|
||||||
}
|
|
||||||
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int OIIO_getVersionHex(void)
|
int OIIO_getVersionHex(void)
|
||||||
{
|
{
|
||||||
return openimageio_version();
|
return openimageio_version();
|
||||||
}
|
}
|
||||||
|
|
||||||
} /* export "C" */
|
} /* extern "C" */
|
||||||
|
@ -7,20 +7,10 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct ImBuf;
|
|
||||||
|
|
||||||
bool imb_is_a_photoshop(const unsigned char *mem, size_t size);
|
|
||||||
|
|
||||||
int imb_save_photoshop(struct ImBuf *ibuf, const char *name, int flags);
|
|
||||||
|
|
||||||
struct ImBuf *imb_load_photoshop(const char *name, int flags, char *colorspace);
|
|
||||||
|
|
||||||
int OIIO_getVersionHex(void);
|
int OIIO_getVersionHex(void);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
398
source/blender/imbuf/intern/oiio/openimageio_support.cc
Normal file
398
source/blender/imbuf/intern/oiio/openimageio_support.cc
Normal file
@ -0,0 +1,398 @@
|
|||||||
|
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||||
|
|
||||||
|
#include "openimageio_support.hh"
|
||||||
|
|
||||||
|
#include "BLI_blenlib.h"
|
||||||
|
|
||||||
|
#include "BKE_idprop.h"
|
||||||
|
#include "DNA_ID.h" /* ID property definitions. */
|
||||||
|
|
||||||
|
#include "IMB_allocimbuf.h"
|
||||||
|
#include "IMB_colormanagement.h"
|
||||||
|
#include "IMB_metadata.h"
|
||||||
|
|
||||||
|
OIIO_NAMESPACE_USING
|
||||||
|
|
||||||
|
using std::string;
|
||||||
|
using std::unique_ptr;
|
||||||
|
|
||||||
|
namespace blender::imbuf {
|
||||||
|
|
||||||
|
/* An OIIO IOProxy used during file packing to write into an in-memory #ImBuf buffer. */
|
||||||
|
class ImBufMemWriter : public Filesystem::IOProxy {
|
||||||
|
public:
|
||||||
|
ImBufMemWriter(ImBuf *ibuf) : IOProxy("", Write), ibuf_(ibuf)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *proxytype() const override
|
||||||
|
{
|
||||||
|
return "ImBufMemWriter";
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t write(const void *buf, size_t size) override
|
||||||
|
{
|
||||||
|
size = pwrite(buf, size, m_pos);
|
||||||
|
m_pos += size;
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t pwrite(const void *buf, size_t size, int64_t offset) override
|
||||||
|
{
|
||||||
|
/* If buffer is too small increase it. */
|
||||||
|
size_t end = offset + size;
|
||||||
|
while (end > ibuf_->encodedbuffersize) {
|
||||||
|
if (!imb_enlargeencodedbufferImBuf(ibuf_)) {
|
||||||
|
/* Out of memory. */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(ibuf_->encodedbuffer + offset, buf, size);
|
||||||
|
|
||||||
|
if (end > ibuf_->encodedsize) {
|
||||||
|
ibuf_->encodedsize = end;
|
||||||
|
}
|
||||||
|
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t size() const override
|
||||||
|
{
|
||||||
|
return ibuf_->encodedsize;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
ImBuf *ibuf_;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Utility to in-place expand an n-component pixel buffer into a 4-component buffer. */
|
||||||
|
template<typename T>
|
||||||
|
static void fill_all_channels(T *pixels, int width, int height, int components, T alpha)
|
||||||
|
{
|
||||||
|
const int64_t pixel_count = int64_t(width) * height;
|
||||||
|
if (components == 3) {
|
||||||
|
for (int64_t i = 0; i < pixel_count; i++) {
|
||||||
|
pixels[i * 4 + 3] = alpha;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (components == 1) {
|
||||||
|
for (int64_t i = 0; i < pixel_count; i++) {
|
||||||
|
pixels[i * 4 + 3] = alpha;
|
||||||
|
pixels[i * 4 + 2] = pixels[i * 4 + 0];
|
||||||
|
pixels[i * 4 + 1] = pixels[i * 4 + 0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (components == 2) {
|
||||||
|
for (int64_t i = 0; i < pixel_count; i++) {
|
||||||
|
pixels[i * 4 + 3] = pixels[i * 4 + 1];
|
||||||
|
pixels[i * 4 + 2] = pixels[i * 4 + 0];
|
||||||
|
pixels[i * 4 + 1] = pixels[i * 4 + 0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
static ImBuf *load_pixels(
|
||||||
|
ImageInput *in, int width, int height, int channels, int flags, bool use_all_planes)
|
||||||
|
{
|
||||||
|
/* Allocate the ImBuf for the image. */
|
||||||
|
constexpr bool is_float = sizeof(T) > 1;
|
||||||
|
const uint format_flag = is_float ? IB_rectfloat : IB_rect;
|
||||||
|
const uint ibuf_flags = (flags & IB_test) ? 0 : format_flag;
|
||||||
|
const int planes = use_all_planes ? 32 : 8 * channels;
|
||||||
|
ImBuf *ibuf = IMB_allocImBuf(width, height, planes, ibuf_flags);
|
||||||
|
if (!ibuf) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* No need to load actual pixel data during the test phase. */
|
||||||
|
if (flags & IB_test) {
|
||||||
|
return ibuf;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Calculate an appropriate stride to read n-channels directly into
|
||||||
|
* the ImBuf 4-channel layout. */
|
||||||
|
const stride_t ibuf_xstride = sizeof(T) * 4;
|
||||||
|
const stride_t ibuf_ystride = ibuf_xstride * width;
|
||||||
|
const TypeDesc format = is_float ? TypeDesc::FLOAT : TypeDesc::UINT8;
|
||||||
|
uchar *rect = is_float ? reinterpret_cast<uchar *>(ibuf->rect_float) :
|
||||||
|
reinterpret_cast<uchar *>(ibuf->rect);
|
||||||
|
void *ibuf_data = rect + ((stride_t(height) - 1) * ibuf_ystride);
|
||||||
|
|
||||||
|
bool ok = in->read_image(
|
||||||
|
0, 0, 0, channels, format, ibuf_data, ibuf_xstride, -ibuf_ystride, AutoStride);
|
||||||
|
if (!ok) {
|
||||||
|
fprintf(stderr, "ImageInput::read_image() failed: %s\n", in->geterror().c_str());
|
||||||
|
|
||||||
|
IMB_freeImBuf(ibuf);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ImBuf always needs 4 channels */
|
||||||
|
const T alpha_fill = is_float ? 1.0f : 0xFF;
|
||||||
|
fill_all_channels<T>(reinterpret_cast<T *>(rect), width, height, channels, alpha_fill);
|
||||||
|
|
||||||
|
return ibuf;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void set_colorspace_name(char colorspace[IM_MAX_SPACE],
|
||||||
|
const ReadContext &ctx,
|
||||||
|
const ImageSpec &spec,
|
||||||
|
bool is_float)
|
||||||
|
{
|
||||||
|
const bool is_colorspace_set = (colorspace[0] != '\0');
|
||||||
|
if (is_colorspace_set) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Use a default role unless otherwise specified. */
|
||||||
|
if (ctx.use_colorspace_role >= 0) {
|
||||||
|
colorspace_set_default_role(colorspace, IM_MAX_SPACE, ctx.use_colorspace_role);
|
||||||
|
}
|
||||||
|
else if (is_float) {
|
||||||
|
colorspace_set_default_role(colorspace, IM_MAX_SPACE, COLOR_ROLE_DEFAULT_FLOAT);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
colorspace_set_default_role(colorspace, IM_MAX_SPACE, COLOR_ROLE_DEFAULT_BYTE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Override if necessary. */
|
||||||
|
if (ctx.use_embedded_colorspace) {
|
||||||
|
string ics = spec.get_string_attribute("oiio:ColorSpace");
|
||||||
|
char file_colorspace[IM_MAX_SPACE];
|
||||||
|
BLI_strncpy(file_colorspace, ics.c_str(), IM_MAX_SPACE);
|
||||||
|
|
||||||
|
/* Only use color-spaces that exist. */
|
||||||
|
if (colormanage_colorspace_get_named(file_colorspace)) {
|
||||||
|
BLI_strncpy(colorspace, file_colorspace, IM_MAX_SPACE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get an #ImBuf filled in with pixel data and associated metadata using the provided ImageInput.
|
||||||
|
*/
|
||||||
|
static ImBuf *get_oiio_ibuf(ImageInput *in, const ReadContext &ctx, char colorspace[IM_MAX_SPACE])
|
||||||
|
{
|
||||||
|
const ImageSpec &spec = in->spec();
|
||||||
|
const int width = spec.width;
|
||||||
|
const int height = spec.height;
|
||||||
|
const int channels = spec.nchannels;
|
||||||
|
const bool has_alpha = spec.alpha_channel != -1;
|
||||||
|
const bool is_float = spec.format.basesize() > 1;
|
||||||
|
|
||||||
|
if (channels < 1 || channels > 4) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
const bool use_all_planes = has_alpha || ctx.use_all_planes;
|
||||||
|
|
||||||
|
ImBuf *ibuf = nullptr;
|
||||||
|
if (is_float) {
|
||||||
|
ibuf = load_pixels<float>(in, width, height, channels, ctx.flags, use_all_planes);
|
||||||
|
ibuf->channels = 4;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ibuf = load_pixels<uchar>(in, width, height, channels, ctx.flags, use_all_planes);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Fill in common ibuf properties. */
|
||||||
|
if (ibuf) {
|
||||||
|
ibuf->ftype = ctx.file_type;
|
||||||
|
ibuf->flags |= (spec.format == TypeDesc::HALF) ? IB_halffloat : 0;
|
||||||
|
|
||||||
|
set_colorspace_name(colorspace, ctx, spec, is_float);
|
||||||
|
|
||||||
|
float x_res = spec.get_float_attribute("XResolution", 0.0f);
|
||||||
|
float y_res = spec.get_float_attribute("YResolution", 0.0f);
|
||||||
|
if (x_res > 0.0f && y_res > 0.0f) {
|
||||||
|
double scale = 1.0;
|
||||||
|
auto unit = spec.get_string_attribute("ResolutionUnit", "");
|
||||||
|
if (unit == "in" || unit == "inch") {
|
||||||
|
scale = 100.0 / 2.54;
|
||||||
|
}
|
||||||
|
else if (unit == "cm") {
|
||||||
|
scale = 100.0;
|
||||||
|
}
|
||||||
|
ibuf->ppm[0] = scale * x_res;
|
||||||
|
ibuf->ppm[1] = scale * y_res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Transfer metadata to the ibuf if necessary. */
|
||||||
|
if (ctx.flags & IB_metadata) {
|
||||||
|
IMB_metadata_ensure(&ibuf->metadata);
|
||||||
|
ibuf->flags |= (spec.extra_attribs.empty()) ? 0 : IB_metadata;
|
||||||
|
|
||||||
|
for (const auto &attrib : spec.extra_attribs) {
|
||||||
|
IMB_metadata_set_field(ibuf->metadata, attrib.name().c_str(), attrib.get_string().c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ibuf;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an ImageInput for the precise `format` requested using the provided IOMemReader.
|
||||||
|
* If successful, the ImageInput will be opened and ready for operations. Null will be returned if
|
||||||
|
* the format was not found or if the open call fails.
|
||||||
|
*/
|
||||||
|
static unique_ptr<ImageInput> get_oiio_reader(const char *format,
|
||||||
|
const ImageSpec &config,
|
||||||
|
Filesystem::IOMemReader &mem_reader,
|
||||||
|
ImageSpec &r_newspec)
|
||||||
|
{
|
||||||
|
/* Attempt to create a reader based on the passed in format. */
|
||||||
|
unique_ptr<ImageInput> in = ImageInput::create(format);
|
||||||
|
if (!in) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Open the reader using the ioproxy. */
|
||||||
|
in->set_ioproxy(&mem_reader);
|
||||||
|
bool ok = in->open("", r_newspec, config);
|
||||||
|
if (!ok) {
|
||||||
|
in.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
return in;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool imb_oiio_check(const uchar *mem, size_t mem_size, const char *file_format)
|
||||||
|
{
|
||||||
|
ImageSpec config, spec;
|
||||||
|
|
||||||
|
/* This memory proxy must remain alive for the full duration of the read. */
|
||||||
|
Filesystem::IOMemReader mem_reader(cspan<uchar>(mem, mem_size));
|
||||||
|
unique_ptr<ImageInput> in = get_oiio_reader(file_format, config, mem_reader, spec);
|
||||||
|
return in ? true : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImBuf *imb_oiio_read(const ReadContext &ctx,
|
||||||
|
const ImageSpec &config,
|
||||||
|
char colorspace[IM_MAX_SPACE],
|
||||||
|
ImageSpec &r_newspec)
|
||||||
|
{
|
||||||
|
/* This memory proxy must remain alive for the full duration of the read. */
|
||||||
|
Filesystem::IOMemReader mem_reader(cspan<uchar>(ctx.mem_start, ctx.mem_size));
|
||||||
|
unique_ptr<ImageInput> in = get_oiio_reader(ctx.file_format, config, mem_reader, r_newspec);
|
||||||
|
if (!in) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return get_oiio_ibuf(in.get(), ctx, colorspace);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool imb_oiio_write(const WriteContext &ctx, const char *filepath, const ImageSpec &file_spec)
|
||||||
|
{
|
||||||
|
unique_ptr<ImageOutput> out = ImageOutput::create(ctx.file_format);
|
||||||
|
if (!out) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto write_op = [&out, &ctx]() {
|
||||||
|
return out->write_image(
|
||||||
|
ctx.mem_format, ctx.mem_start, ctx.mem_xstride, -ctx.mem_ystride, AutoStride);
|
||||||
|
};
|
||||||
|
|
||||||
|
bool ok = false;
|
||||||
|
if (ctx.flags & IB_mem) {
|
||||||
|
/* This memory proxy must remain alive for the full duration of the write. */
|
||||||
|
ImBufMemWriter writer(ctx.ibuf);
|
||||||
|
|
||||||
|
imb_addencodedbufferImBuf(ctx.ibuf);
|
||||||
|
out->set_ioproxy(&writer);
|
||||||
|
out->open("", file_spec);
|
||||||
|
ok = write_op();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
out->open(filepath, file_spec);
|
||||||
|
ok = write_op();
|
||||||
|
}
|
||||||
|
|
||||||
|
out->close();
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
WriteContext imb_create_write_context(const char *file_format,
|
||||||
|
ImBuf *ibuf,
|
||||||
|
int flags,
|
||||||
|
bool prefer_float)
|
||||||
|
{
|
||||||
|
WriteContext ctx{};
|
||||||
|
ctx.file_format = file_format;
|
||||||
|
ctx.ibuf = ibuf;
|
||||||
|
ctx.flags = flags;
|
||||||
|
|
||||||
|
const int width = ibuf->x;
|
||||||
|
const int height = ibuf->y;
|
||||||
|
const bool use_float = prefer_float && (ibuf->rect_float != nullptr);
|
||||||
|
if (use_float) {
|
||||||
|
const int mem_channels = ibuf->channels ? ibuf->channels : 4;
|
||||||
|
ctx.mem_xstride = sizeof(float) * mem_channels;
|
||||||
|
ctx.mem_ystride = width * ctx.mem_xstride;
|
||||||
|
ctx.mem_format = TypeDesc::FLOAT;
|
||||||
|
ctx.mem_start = reinterpret_cast<uchar *>(ibuf->rect_float);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const int mem_channels = 4;
|
||||||
|
ctx.mem_xstride = sizeof(uchar) * mem_channels;
|
||||||
|
ctx.mem_ystride = width * ctx.mem_xstride;
|
||||||
|
ctx.mem_format = TypeDesc::UINT8;
|
||||||
|
ctx.mem_start = reinterpret_cast<uchar *>(ibuf->rect);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We always write using a negative y-stride so ensure we start at the end. */
|
||||||
|
ctx.mem_start = ctx.mem_start + ((stride_t(height) - 1) * ctx.mem_ystride);
|
||||||
|
|
||||||
|
return ctx;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImageSpec imb_create_write_spec(const WriteContext &ctx, int file_channels, TypeDesc data_format)
|
||||||
|
{
|
||||||
|
const int width = ctx.ibuf->x;
|
||||||
|
const int height = ctx.ibuf->y;
|
||||||
|
ImageSpec file_spec(width, height, file_channels, data_format);
|
||||||
|
|
||||||
|
/* Populate the spec with all common attributes.
|
||||||
|
*
|
||||||
|
* Care must be taken with the metadata:
|
||||||
|
* - It should be processed first, before the "Resolution" metadata below, to
|
||||||
|
* ensure the proper values end up in the ImageSpec
|
||||||
|
* - It needs to filter format-specific metadata that may no longer apply to
|
||||||
|
* the current format being written (e.g. metadata for tiff being written to a png)
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (ctx.ibuf->metadata) {
|
||||||
|
for (IDProperty *prop = static_cast<IDProperty *>(ctx.ibuf->metadata->data.group.first); prop;
|
||||||
|
prop = prop->next) {
|
||||||
|
if (prop->type == IDP_STRING) {
|
||||||
|
/* If this property has a prefixed name (oiio:, tiff:, etc.) and it belongs to
|
||||||
|
* oiio or a different format, then skip. */
|
||||||
|
if (char *colon = strchr(prop->name, ':')) {
|
||||||
|
std::string prefix(prop->name, colon);
|
||||||
|
Strutil::to_lower(prefix);
|
||||||
|
if (prefix == "oiio" ||
|
||||||
|
(!STREQ(prefix.c_str(), ctx.file_format) && OIIO::is_imageio_format_name(prefix))) {
|
||||||
|
/* Skip this attribute. */
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
file_spec.attribute(prop->name, IDP_String(prop));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ctx.ibuf->ppm[0] > 0.0 && ctx.ibuf->ppm[1] > 0.0) {
|
||||||
|
/* More OIIO formats support inch than meter. */
|
||||||
|
file_spec.attribute("ResolutionUnit", "in");
|
||||||
|
file_spec.attribute("XResolution", float(ctx.ibuf->ppm[0] * 0.0254));
|
||||||
|
file_spec.attribute("YResolution", float(ctx.ibuf->ppm[1] * 0.0254));
|
||||||
|
}
|
||||||
|
|
||||||
|
return file_spec;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace blender::imbuf
|
104
source/blender/imbuf/intern/oiio/openimageio_support.hh
Normal file
104
source/blender/imbuf/intern/oiio/openimageio_support.hh
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#include <OpenImageIO/filesystem.h>
|
||||||
|
#include <OpenImageIO/imageio.h>
|
||||||
|
|
||||||
|
#include "BLI_sys_types.h"
|
||||||
|
|
||||||
|
#include "IMB_imbuf.h"
|
||||||
|
#include "IMB_imbuf_types.h"
|
||||||
|
|
||||||
|
namespace blender::imbuf {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parameters and settings used while reading image formats.
|
||||||
|
*/
|
||||||
|
struct ReadContext {
|
||||||
|
const uchar *mem_start;
|
||||||
|
const size_t mem_size;
|
||||||
|
const char *file_format;
|
||||||
|
const eImbFileType file_type;
|
||||||
|
const int flags;
|
||||||
|
|
||||||
|
/* Override the automatic color-role choice with the value specified here. */
|
||||||
|
int use_colorspace_role = -1;
|
||||||
|
|
||||||
|
/* Allocate and use all ImBuf image planes even if the image has fewer. */
|
||||||
|
bool use_all_planes = false;
|
||||||
|
|
||||||
|
/* Use the colorspace provided in the image metadata when available. */
|
||||||
|
bool use_embedded_colorspace = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parameters and settings used while writing image formats.
|
||||||
|
*/
|
||||||
|
struct WriteContext {
|
||||||
|
const char *file_format;
|
||||||
|
ImBuf *ibuf;
|
||||||
|
|
||||||
|
OIIO::stride_t mem_xstride;
|
||||||
|
OIIO::stride_t mem_ystride;
|
||||||
|
OIIO::TypeDesc mem_format;
|
||||||
|
uchar *mem_start;
|
||||||
|
|
||||||
|
int flags;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check to see if we can load and open the given file format.
|
||||||
|
*/
|
||||||
|
bool imb_oiio_check(const uchar *mem, size_t mem_size, const char *file_format);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The primary method for reading data into an #ImBuf.
|
||||||
|
*
|
||||||
|
* During the `IB_test` phase of loading, the `colorspace` parameter will be populated
|
||||||
|
* with the appropriate colorspace name.
|
||||||
|
*
|
||||||
|
* Upon return, the `r_newspec` parameter will contain image format information
|
||||||
|
* which can be inspected afterwards if necessary.
|
||||||
|
*/
|
||||||
|
ImBuf *imb_oiio_read(const ReadContext &ctx,
|
||||||
|
const OIIO::ImageSpec &config,
|
||||||
|
char colorspace[IM_MAX_SPACE],
|
||||||
|
OIIO::ImageSpec &r_newspec);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The primary method for writing data from an #ImBuf to either a physical or in-memory
|
||||||
|
* destination.
|
||||||
|
*
|
||||||
|
* The `file_spec` parameter will typically come from #imb_create_write_spec.
|
||||||
|
*/
|
||||||
|
bool imb_oiio_write(const WriteContext &ctx,
|
||||||
|
const char *filepath,
|
||||||
|
const OIIO::ImageSpec &file_spec);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a #WriteContext based on the provided #ImBuf and format information.
|
||||||
|
*
|
||||||
|
* If the provided #ImBuf contains both byte and float buffers, the `prefer_float`
|
||||||
|
* flag controls which buffer to use. By default, if a float buffer exists it will
|
||||||
|
* be used.
|
||||||
|
*/
|
||||||
|
WriteContext imb_create_write_context(const char *file_format,
|
||||||
|
ImBuf *ibuf,
|
||||||
|
int flags,
|
||||||
|
bool prefer_float = true);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an ImageSpec filled in with all common attributes associated with the #ImBuf
|
||||||
|
* provided as part of the #WriteContext.
|
||||||
|
*
|
||||||
|
* This includes optional metadata that has been attached to the #ImBuf and which should be
|
||||||
|
* written to the new file as necessary.
|
||||||
|
*/
|
||||||
|
OIIO::ImageSpec imb_create_write_spec(const WriteContext &ctx,
|
||||||
|
int file_channels,
|
||||||
|
OIIO::TypeDesc data_format);
|
||||||
|
|
||||||
|
} // namespace blender::imbuf
|
@ -441,7 +441,7 @@ static void openexr_header_metadata(Header *header, struct ImBuf *ibuf)
|
|||||||
IDProperty *prop;
|
IDProperty *prop;
|
||||||
|
|
||||||
for (prop = (IDProperty *)ibuf->metadata->data.group.first; prop; prop = prop->next) {
|
for (prop = (IDProperty *)ibuf->metadata->data.group.first; prop; prop = prop->next) {
|
||||||
if (prop->type == IDP_STRING) {
|
if (prop->type == IDP_STRING && !STREQ(prop->name, "compression")) {
|
||||||
header->insert(prop->name, StringAttribute(IDP_String(prop)));
|
header->insert(prop->name, StringAttribute(IDP_String(prop)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -114,44 +114,7 @@ ImBuf *IMB_ibImageFromMemory(
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ImBuf *IMB_ibImageFromFile(const char *filepath,
|
ImBuf *IMB_loadifffile(int file, int flags, char colorspace[IM_MAX_SPACE], const char *descr)
|
||||||
int flags,
|
|
||||||
char colorspace[IM_MAX_SPACE],
|
|
||||||
const char *descr)
|
|
||||||
{
|
|
||||||
ImBuf *ibuf;
|
|
||||||
const ImFileType *type;
|
|
||||||
char effective_colorspace[IM_MAX_SPACE] = "";
|
|
||||||
|
|
||||||
if (colorspace) {
|
|
||||||
BLI_strncpy(effective_colorspace, colorspace, sizeof(effective_colorspace));
|
|
||||||
}
|
|
||||||
|
|
||||||
for (type = IMB_FILE_TYPES; type < IMB_FILE_TYPES_LAST; type++) {
|
|
||||||
if (type->load_filepath) {
|
|
||||||
ibuf = type->load_filepath(filepath, flags, effective_colorspace);
|
|
||||||
if (ibuf) {
|
|
||||||
imb_handle_alpha(ibuf, flags, colorspace, effective_colorspace);
|
|
||||||
return ibuf;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((flags & IB_test) == 0) {
|
|
||||||
fprintf(stderr, "%s: unknown fileformat (%s)\n", __func__, descr);
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool imb_is_filepath_format(const char *filepath)
|
|
||||||
{
|
|
||||||
/* return true if this is one of the formats that can't be loaded from memory */
|
|
||||||
return BLI_path_extension_check_array(filepath, imb_ext_image_filepath_only);
|
|
||||||
}
|
|
||||||
|
|
||||||
ImBuf *IMB_loadifffile(
|
|
||||||
int file, const char *filepath, int flags, char colorspace[IM_MAX_SPACE], const char *descr)
|
|
||||||
{
|
{
|
||||||
ImBuf *ibuf;
|
ImBuf *ibuf;
|
||||||
uchar *mem;
|
uchar *mem;
|
||||||
@ -161,10 +124,6 @@ ImBuf *IMB_loadifffile(
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (imb_is_filepath_format(filepath)) {
|
|
||||||
return IMB_ibImageFromFile(filepath, flags, colorspace, descr);
|
|
||||||
}
|
|
||||||
|
|
||||||
size = BLI_file_descriptor_size(file);
|
size = BLI_file_descriptor_size(file);
|
||||||
|
|
||||||
imb_mmap_lock();
|
imb_mmap_lock();
|
||||||
@ -198,7 +157,7 @@ ImBuf *IMB_loadiffname(const char *filepath, int flags, char colorspace[IM_MAX_S
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ibuf = IMB_loadifffile(file, filepath, flags, colorspace, filepath);
|
ibuf = IMB_loadifffile(file, flags, colorspace, filepath);
|
||||||
|
|
||||||
if (ibuf) {
|
if (ibuf) {
|
||||||
BLI_strncpy(ibuf->name, filepath, sizeof(ibuf->name));
|
BLI_strncpy(ibuf->name, filepath, sizeof(ibuf->name));
|
||||||
@ -277,7 +236,7 @@ ImBuf *IMB_testiffname(const char *filepath, int flags)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ibuf = IMB_loadifffile(file, filepath, flags | IB_test | IB_multilayer, colorspace, filepath);
|
ibuf = IMB_loadifffile(file, flags | IB_test | IB_multilayer, colorspace, filepath);
|
||||||
|
|
||||||
if (ibuf) {
|
if (ibuf) {
|
||||||
BLI_strncpy(ibuf->name, filepath, sizeof(ibuf->name));
|
BLI_strncpy(ibuf->name, filepath, sizeof(ibuf->name));
|
||||||
|
@ -67,13 +67,6 @@ const char *imb_ext_image[] = {
|
|||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
const char *imb_ext_image_filepath_only[] = {
|
|
||||||
".psd",
|
|
||||||
".pdd",
|
|
||||||
".psb",
|
|
||||||
NULL,
|
|
||||||
};
|
|
||||||
|
|
||||||
const char *imb_ext_movie[] = {
|
const char *imb_ext_movie[] = {
|
||||||
".avi", ".flc", ".mov", ".movie", ".mp4", ".m4v", ".m2v", ".m2t", ".m2ts", ".mts",
|
".avi", ".flc", ".mov", ".movie", ".mp4", ".m4v", ".m2v", ".m2t", ".m2ts", ".mts",
|
||||||
".ts", ".mv", ".avs", ".wmv", ".ogv", ".ogg", ".r3d", ".dv", ".mpeg", ".mpg",
|
".ts", ".mv", ".avs", ".wmv", ".ogv", ".ogg", ".r3d", ".dv", ".mpeg", ".mpg",
|
||||||
|
@ -480,7 +480,7 @@ static PyObject *M_imbuf_load(PyObject *UNUSED(self), PyObject *args, PyObject *
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ImBuf *ibuf = IMB_loadifffile(file, filepath, IB_rect, NULL, filepath);
|
ImBuf *ibuf = IMB_loadifffile(file, IB_rect, NULL, filepath);
|
||||||
|
|
||||||
close(file);
|
close(file);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user