6#include <OpenImageIO/imagebuf.h>
7#include <OpenImageIO/imagebufalgo.h>
32 return "ImBufMemWriter";
45 size_t end = offset +
size;
46 while (end > ibuf_->encoded_buffer_size) {
53 memcpy(ibuf_->encoded_buffer.data + offset, buf,
size);
55 if (end > ibuf_->encoded_size) {
56 ibuf_->encoded_size = end;
62 size_t size()
const override
64 return ibuf_->encoded_size;
76 if (components == 3) {
77 for (
int64_t i = 0; i < pixel_count; i++) {
78 pixels[i * 4 + 3] = alpha;
81 else if (components == 1) {
82 for (
int64_t i = 0; i < pixel_count; i++) {
83 pixels[i * 4 + 3] = alpha;
84 pixels[i * 4 + 2] = pixels[i * 4 + 0];
85 pixels[i * 4 + 1] = pixels[i * 4 + 0];
88 else if (components == 2) {
89 for (
int64_t i = 0; i < pixel_count; i++) {
90 pixels[i * 4 + 3] = pixels[i * 4 + 1];
91 pixels[i * 4 + 2] = pixels[i * 4 + 0];
92 pixels[i * 4 + 1] = pixels[i * 4 + 0];
99 ImageInput *in,
int width,
int height,
int channels,
int flags,
bool use_all_planes)
102 constexpr bool is_float =
sizeof(
T) > 1;
104 const uint ibuf_flags = (flags &
IB_test) ? 0 : format_flag;
105 const int planes = use_all_planes ? 32 : 8 *
channels;
118 const stride_t ibuf_xstride =
sizeof(
T) * 4;
119 const stride_t ibuf_ystride = ibuf_xstride * width;
120 const TypeDesc format = is_float ? TypeDesc::FLOAT : TypeDesc::UINT8;
123 void *ibuf_data = rect + ((stride_t(height) - 1) * ibuf_ystride);
125 bool ok = in->read_image(
126 0, 0, 0,
channels,
format, ibuf_data, ibuf_xstride, -ibuf_ystride, AutoStride);
128 fprintf(stderr,
"ImageInput::read_image() failed: %s\n", in->geterror().c_str());
135 const T alpha_fill = is_float ? 1.0f : 0xFF;
143 const ImageSpec &spec,
146 const bool is_colorspace_set = (colorspace[0] !=
'\0');
147 if (is_colorspace_set) {
164 string ics = spec.get_string_attribute(
"oiio:ColorSpace");
166 STRNCPY(file_colorspace, ics.c_str());
180 const ImageSpec &spec = in->spec();
181 const int width = spec.width;
182 const int height = spec.height;
183 const bool has_alpha = spec.alpha_channel != -1;
184 const bool is_float = spec.format.basesize() > 1;
187 const int channels = spec.nchannels <= 4 ? spec.nchannels : 4;
194 ImBuf *ibuf =
nullptr;
209 float x_res = spec.get_float_attribute(
"XResolution", 0.0f);
210 float y_res = spec.get_float_attribute(
"YResolution", 0.0f);
211 if (x_res > 0.0f && y_res > 0.0f) {
213 auto unit = spec.get_string_attribute(
"ResolutionUnit",
"");
214 if (
ELEM(unit,
"in",
"inch")) {
215 scale = 100.0 / 2.54;
217 else if (unit ==
"cm") {
220 ibuf->
ppm[0] = scale * x_res;
221 ibuf->
ppm[1] = scale * y_res;
229 for (
const auto &attrib : spec.extra_attribs) {
230 if (attrib.name().find(
"ICCProfile") != string::npos) {
247 const ImageSpec &config,
248 Filesystem::IOMemReader &mem_reader,
249 ImageSpec &r_newspec)
253 if (!(in && in->valid_file(&mem_reader))) {
258 in->set_ioproxy(&mem_reader);
259 bool ok = in->open(
"", r_newspec, config);
269 ImageSpec config, spec;
272 Filesystem::IOMemReader mem_reader(cspan<uchar>(mem, mem_size));
274 return in && in->valid_file(&mem_reader);
278 const ImageSpec &config,
280 ImageSpec &r_newspec)
300 ImageBuf final_buf{};
304 if (ctx.
ibuf->
channels > 1 && file_spec.nchannels == 1) {
305 float weights[4] = {};
306#if OIIO_VERSION_MAJOR >= 3
307 const size_t nchannels = orig_buf.nchannels();
309 const int nchannels = orig_buf.nchannels();
312 ImageBufAlgo::channel_sum(final_buf, orig_buf, {weights, nchannels});
317 if (ctx.
ibuf->
channels == 1 && file_spec.nchannels > 1) {
318 final_buf = ImageBuf(file_spec, InitializePixels::No);
319 ImageBufAlgo::paste(final_buf, 0, 0, 0, 0, orig_buf);
320 ImageBufAlgo::paste(final_buf, 0, 0, 0, 1, orig_buf);
321 ImageBufAlgo::paste(final_buf, 0, 0, 0, 2, orig_buf);
322 if (file_spec.alpha_channel == 3) {
323 ROI alpha_roi = file_spec.roi();
324 alpha_roi.chbegin = file_spec.alpha_channel;
325 ImageBufAlgo::fill(final_buf, {0, 0, 0, 1.0f}, alpha_roi);
329 final_buf = std::move(orig_buf);
333 bool write_ok =
false;
334 bool close_ok =
false;
340 out->set_ioproxy(&writer);
341 if (out->open(
"", file_spec)) {
342 write_ok = final_buf.write(out.get());
343 close_ok = out->close();
347 if (out->open(filepath, file_spec)) {
348 write_ok = final_buf.write(out.get());
349 close_ok = out->close();
353 return write_ok && close_ok;
366 const int width = ibuf->
x;
367 const int height = ibuf->
y;
368 const bool use_float = prefer_float && (ibuf->
float_buffer.
data !=
nullptr);
374 ctx.
mem_spec = ImageSpec(width, height, mem_channels, TypeDesc::FLOAT);
377 const int mem_channels = 4;
381 ctx.
mem_spec = ImageSpec(width, height, mem_channels, TypeDesc::UINT8);
392 const int width = ctx.
ibuf->
x;
393 const int height = ctx.
ibuf->
y;
394 ImageSpec file_spec(width, height, file_channels, data_format);
410 if (
char *colon = strchr(prop->name,
':')) {
411 std::string prefix(prop->name, colon);
412 Strutil::to_lower(prefix);
413 if (prefix ==
"oiio" ||
414 (!
STREQ(prefix.c_str(), ctx.
file_format) && OIIO::is_imageio_format_name(prefix)))
421 file_spec.attribute(prop->name,
IDP_String(prop));
428 file_spec.attribute(
"ResolutionUnit",
"in");
429 file_spec.attribute(
"XResolution",
float(ctx.
ibuf->
ppm[0] * 0.0254));
430 file_spec.attribute(
"YResolution",
float(ctx.
ibuf->
ppm[1] * 0.0254));
#define LISTBASE_FOREACH(type, var, list)
#define STRNCPY(dst, src)
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, size_t dst_maxncpy) ATTR_NONNULL(1
ID and Library types, which are fundamental for SDNA.
@ COLOR_ROLE_DEFAULT_FLOAT
@ COLOR_ROLE_DEFAULT_BYTE
BLI_INLINE void IMB_colormanagement_get_luminance_coefficients(float r_rgb[3])
@ IB_uninitialized_pixels
Group Output data from inside of a node group A color picker Mix two input colors RGB to Convert a color s luminance to a grayscale value Generate a normal vector and a dot product Brightness Control the brightness and contrast of the input color Vector Map input vector components with curves Camera Retrieve information about the camera and how it relates to the current shading point s position Clamp a value between a minimum and a maximum Vector Perform vector math operation Invert Invert a producing a negative Combine Generate a color from its and blue channels(Deprecated)") DefNode(ShaderNode
bool imb_enlargeencodedbufferImBuf(ImBuf *ibuf)
bool imb_addencodedbufferImBuf(ImBuf *ibuf)
size_t write(const void *buf, size_t size) override
size_t pwrite(const void *buf, size_t size, int64_t offset) override
const char * proxytype() const override
size_t size() const override
ImBufMemWriter(ImBuf *ibuf)
void colorspace_set_default_role(char *colorspace, int size, int role)
ColorSpace * colormanage_colorspace_get_named(const char *name)
draw_view in_light_buf[] float
struct ImBuf * IMB_allocImBuf(unsigned int, unsigned int, unsigned char, unsigned int)
void IMB_freeImBuf(ImBuf *)
bool imb_oiio_write(const WriteContext &ctx, const char *filepath, const ImageSpec &file_spec)
WriteContext imb_create_write_context(const char *file_format, ImBuf *ibuf, int flags, bool prefer_float)
static unique_ptr< ImageInput > get_oiio_reader(const char *format, const ImageSpec &config, Filesystem::IOMemReader &mem_reader, ImageSpec &r_newspec)
ImBuf * imb_oiio_read(const ReadContext &ctx, const ImageSpec &config, char colorspace[IM_MAX_SPACE], ImageSpec &r_newspec)
static void set_colorspace_name(char colorspace[IM_MAX_SPACE], const ReadContext &ctx, const ImageSpec &spec, bool is_float)
bool imb_oiio_check(const uchar *mem, size_t mem_size, const char *file_format)
ImageSpec imb_create_write_spec(const WriteContext &ctx, int file_channels, TypeDesc data_format)
static ImBuf * get_oiio_ibuf(ImageInput *in, const ReadContext &ctx, char colorspace[IM_MAX_SPACE])
static ImBuf * load_pixels(ImageInput *in, int width, int height, int channels, int flags, bool use_all_planes)
static void fill_all_channels(T *pixels, int width, int height, int components, T alpha)
ImBufFloatBuffer float_buffer
ImBufByteBuffer byte_buffer
bool use_embedded_colorspace
const eImbFileType file_type
OIIO::stride_t mem_ystride
OIIO::stride_t mem_xstride