Blender V4.3
allocimbuf.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2001-2002 NaN Holding BV. All rights reserved.
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
9/* It's become a bit messy... Basically, only the IMB_ prefixed files
10 * should remain. */
11
12#include <cstddef>
13
14#include "IMB_imbuf.hh"
15#include "IMB_imbuf_types.hh"
16
17#include "IMB_allocimbuf.hh"
19#include "IMB_filetype.hh"
20#include "IMB_metadata.hh"
21
22#include "imbuf.hh"
23
24#include "MEM_guardedalloc.h"
25
26#include "BLI_threads.h"
27#include "BLI_utildefines.h"
28
29#include "GPU_texture.hh"
30
32
37
42
43#ifndef WIN32
45
50
55
60
65#endif
66
67/* Free the specified buffer storage, freeing memory when needed and restoring the state of the
68 * buffer to its defaults. */
69template<class BufferType> static void imb_free_buffer(BufferType &buffer)
70{
71 if (buffer.data) {
72 switch (buffer.ownership) {
74 break;
75
77 MEM_freeN(buffer.data);
78 break;
79 }
80 }
81
82 /* Reset buffer to defaults. */
83 buffer.data = nullptr;
84 buffer.ownership = IB_DO_NOT_TAKE_OWNERSHIP;
85}
86
87/* Free the specified DDS buffer storage, freeing memory when needed and restoring the state of the
88 * buffer to its defaults. */
89static void imb_free_dds_buffer(DDSData &dds_data)
90{
91 if (dds_data.data) {
92 switch (dds_data.ownership) {
94 break;
95
97 /* dds_data.data is allocated by DirectDrawSurface::readData(), so don't use MEM_freeN! */
98 free(dds_data.data);
99 break;
100 }
101 }
102
103 /* Reset buffer to defaults. */
104 dds_data.data = nullptr;
106}
107
108/* Allocate pixel storage of the given buffer. The buffer owns the allocated memory.
109 * Returns true of allocation succeeded, false otherwise. */
110template<class BufferType>
111bool imb_alloc_buffer(BufferType &buffer,
112 const uint x,
113 const uint y,
114 const uint channels,
115 const size_t type_size,
116 bool initialize_pixels)
117{
118 buffer.data = static_cast<decltype(BufferType::data)>(
119 imb_alloc_pixels(x, y, channels, type_size, initialize_pixels, __func__));
120 if (!buffer.data) {
121 return false;
122 }
123
124 buffer.ownership = IB_TAKE_OWNERSHIP;
125
126 return true;
127}
128
129/* Make the buffer available for modification.
130 * Is achieved by ensuring that the buffer is the only owner of its data. */
131template<class BufferType> void imb_make_writeable_buffer(BufferType &buffer)
132{
133 if (!buffer.data) {
134 return;
135 }
136
137 switch (buffer.ownership) {
139 buffer.data = static_cast<decltype(BufferType::data)>(MEM_dupallocN(buffer.data));
140 buffer.ownership = IB_TAKE_OWNERSHIP;
141
143 break;
144 }
145}
146
147template<class BufferType>
148auto imb_steal_buffer_data(BufferType &buffer) -> decltype(BufferType::data)
149{
150 if (!buffer.data) {
151 return nullptr;
152 }
153
154 switch (buffer.ownership) {
156 BLI_assert_msg(false, "Unexpected behavior: stealing non-owned data pointer");
157 return nullptr;
158
159 case IB_TAKE_OWNERSHIP: {
160 decltype(BufferType::data) data = buffer.data;
161
162 buffer.data = nullptr;
163 buffer.ownership = IB_DO_NOT_TAKE_OWNERSHIP;
164
165 return data;
166 }
167 }
168
170
171 return nullptr;
172}
173
175{
176 int a;
177
178 /* Do not trust ibuf->miptot, in some cases IMB_remakemipmap can leave unfreed unused levels,
179 * leading to memory leaks... */
180 for (a = 0; a < IMB_MIPMAP_LEVELS; a++) {
181 if (ibuf->mipmap[a] != nullptr) {
182 IMB_freeImBuf(ibuf->mipmap[a]);
183 ibuf->mipmap[a] = nullptr;
184 }
185 }
186
187 ibuf->miptot = 0;
188}
189
191{
192 if (ibuf == nullptr) {
193 return;
194 }
195
197
199
200 ibuf->flags &= ~IB_rectfloat;
201}
202
204{
205 if (ibuf == nullptr) {
206 return;
207 }
208
210
212
213 ibuf->flags &= ~IB_rect;
214}
215
217{
218 if (ibuf == nullptr) {
219 return;
220 }
221
223
224 ibuf->encoded_buffer_size = 0;
225 ibuf->encoded_size = 0;
226
227 ibuf->flags &= ~IB_mem;
228}
229
236
238{
239 if (!ibuf || !ibuf->gpu.texture) {
240 return;
241 }
242
244 ibuf->gpu.texture = nullptr;
245}
246
248{
249 if (ibuf == nullptr) {
250 return;
251 }
252
253 bool needs_free = false;
254
256 if (ibuf->refcounter > 0) {
257 ibuf->refcounter--;
258 }
259 else {
260 needs_free = true;
261 }
263
264 if (needs_free) {
265 /* Include this check here as the path may be manipulated after creation. */
266 BLI_assert_msg(!(ibuf->filepath[0] == '/' && ibuf->filepath[1] == '/'),
267 "'.blend' relative \"//\" must not be used in ImBuf!");
268
274 MEM_freeN(ibuf);
275 }
276}
277
284
286{
287 if (ibuf == nullptr) {
288 return nullptr;
289 }
290
292 const bool is_single = (ibuf->refcounter == 0);
294 if (is_single) {
295 return ibuf;
296 }
297
298 ImBuf *rval = IMB_dupImBuf(ibuf);
299
300 IMB_metadata_copy(rval, ibuf);
301
302 IMB_freeImBuf(ibuf);
303
304 return rval;
305}
306
308{
309 if (ibuf == nullptr) {
310 return false;
311 }
312
314
315 if (ibuf->encoded_buffer_size == 0) {
316 ibuf->encoded_buffer_size = 10000;
317 }
318
319 ibuf->encoded_size = 0;
320
321 if (!imb_alloc_buffer(
322 ibuf->encoded_buffer, ibuf->encoded_buffer_size, 1, 1, sizeof(uint8_t), true))
323 {
324 return false;
325 }
326
327 ibuf->flags |= IB_mem;
328
329 return true;
330}
331
333{
334 if (ibuf == nullptr) {
335 return false;
336 }
337
338 if (ibuf->encoded_buffer_size < ibuf->encoded_size) {
339 printf("%s: error in parameters\n", __func__);
340 return false;
341 }
342
343 uint newsize = 2 * ibuf->encoded_buffer_size;
344 if (newsize < 10000) {
345 newsize = 10000;
346 }
347
348 ImBufByteBuffer new_buffer;
349 if (!imb_alloc_buffer(new_buffer, newsize, 1, 1, sizeof(uint8_t), true)) {
350 return false;
351 }
352
353 if (ibuf->encoded_buffer.data) {
354 memcpy(new_buffer.data, ibuf->encoded_buffer.data, ibuf->encoded_size);
355 }
356 else {
357 ibuf->encoded_size = 0;
358 }
359
361
362 ibuf->encoded_buffer = new_buffer;
363 ibuf->encoded_buffer_size = newsize;
364 ibuf->flags |= IB_mem;
365
366 return true;
367}
368
370 uint x, uint y, uint channels, size_t typesize, bool initialize_pixels, const char *alloc_name)
371{
372 /* Protect against buffer overflow vulnerabilities from files specifying
373 * a width and height that overflow and alloc too little memory. */
374 if (!(uint64_t(x) * uint64_t(y) < (SIZE_MAX / (channels * typesize)))) {
375 return nullptr;
376 }
377
378 size_t size = size_t(x) * size_t(y) * size_t(channels) * typesize;
379 return initialize_pixels ? MEM_callocN(size, alloc_name) : MEM_mallocN(size, alloc_name);
380}
381
382bool imb_addrectfloatImBuf(ImBuf *ibuf, const uint channels, bool initialize_pixels)
383{
384 if (ibuf == nullptr) {
385 return false;
386 }
387
388 /* NOTE: Follows the historical code.
389 * Is unclear if it is desired or not to free mipmaps. If mipmaps are to be preserved a simple
390 * `imb_free_buffer(ibuf->float_buffer)` can be used instead. */
391 if (ibuf->float_buffer.data) {
392 imb_freerectfloatImBuf(ibuf); /* frees mipmap too, hrm */
393 }
394
395 if (!imb_alloc_buffer(
396 ibuf->float_buffer, ibuf->x, ibuf->y, channels, sizeof(float), initialize_pixels))
397 {
398 return false;
399 }
400
401 ibuf->channels = channels;
402 ibuf->flags |= IB_rectfloat;
403
404 return true;
405}
406
407bool imb_addrectImBuf(ImBuf *ibuf, bool initialize_pixels)
408{
409 /* Question; why also add ZBUF (when `planes > 32`)? */
410
411 if (ibuf == nullptr) {
412 return false;
413 }
414
415 /* Don't call imb_freerectImBuf, it frees mipmaps,
416 * this call is used only too give float buffers display. */
418
419 if (!imb_alloc_buffer(
420 ibuf->byte_buffer, ibuf->x, ibuf->y, 4, sizeof(uint8_t), initialize_pixels))
421 {
422 return false;
423 }
424
425 ibuf->flags |= IB_rect;
426
427 return true;
428}
429
431{
433 ibuf->flags &= ~IB_rect;
434 return data;
435}
436
438{
439 float *data = imb_steal_buffer_data(ibuf->float_buffer);
440 ibuf->flags &= ~IB_rectfloat;
441 return data;
442}
443
445{
447
448 ibuf->encoded_size = 0;
449 ibuf->encoded_buffer_size = 0;
450
451 ibuf->flags &= ~IB_mem;
452
453 return data;
454}
455
460
465
466void IMB_assign_byte_buffer(ImBuf *ibuf, uint8_t *buffer_data, const ImBufOwnership ownership)
467{
469 ibuf->flags &= ~IB_rect;
470
471 if (buffer_data) {
472 ibuf->byte_buffer.data = buffer_data;
473 ibuf->byte_buffer.ownership = ownership;
474
475 ibuf->flags |= IB_rect;
476 }
477}
478
479void IMB_assign_float_buffer(ImBuf *ibuf, float *buffer_data, const ImBufOwnership ownership)
480{
482 ibuf->flags &= ~IB_rectfloat;
483
484 if (buffer_data) {
485 ibuf->float_buffer.data = buffer_data;
486 ibuf->float_buffer.ownership = ownership;
487
488 ibuf->flags |= IB_rectfloat;
489 }
490}
491
493 const ImBufByteBuffer &buffer,
494 const ImBufOwnership ownership)
495{
496 IMB_assign_byte_buffer(ibuf, buffer.data, ownership);
497 ibuf->byte_buffer.colorspace = buffer.colorspace;
498}
499
501 const ImBufFloatBuffer &buffer,
502 const ImBufOwnership ownership)
503{
504 IMB_assign_float_buffer(ibuf, buffer.data, ownership);
505 ibuf->float_buffer.colorspace = buffer.colorspace;
506}
507
508void IMB_assign_dds_data(ImBuf *ibuf, const DDSData &data, const ImBufOwnership ownership)
509{
511
513
514 ibuf->dds_data = data;
515 ibuf->dds_data.ownership = ownership;
516}
517
519 uint8_t *byte_buffer, float *float_buffer, uint w, uint h, uint channels)
520{
521 if (!(byte_buffer || float_buffer)) {
522 return nullptr;
523 }
524
525 ImBuf *ibuf = IMB_allocImBuf(w, h, 32, 0);
526
527 ibuf->channels = channels;
528
529 if (float_buffer) {
530 /* TODO(sergey): The 4 channels is the historical code. Should probably be `channels`, but
531 * needs a dedicated investigation. */
532 BLI_assert(MEM_allocN_len(float_buffer) == sizeof(float[4]) * w * h);
533 IMB_assign_float_buffer(ibuf, float_buffer, IB_TAKE_OWNERSHIP);
534 }
535
536 if (byte_buffer) {
537 BLI_assert(MEM_allocN_len(byte_buffer) == sizeof(uint8_t[4]) * w * h);
538 IMB_assign_byte_buffer(ibuf, byte_buffer, IB_TAKE_OWNERSHIP);
539 }
540
541 return ibuf;
542}
543
545 const uint8_t *byte_buffer, const float *float_buffer, uint w, uint h, uint channels)
546{
547 ImBuf *ibuf = nullptr;
548
549 if (!(byte_buffer || float_buffer)) {
550 return nullptr;
551 }
552
553 ibuf = IMB_allocImBuf(w, h, 32, 0);
554
555 ibuf->channels = channels;
556
557 /* NOTE: Avoid #MEM_dupallocN since the buffers might not be allocated using guarded-allocation.
558 */
559 if (float_buffer) {
560 /* TODO(sergey): The 4 channels is the historical code. Should probably be `channels`, but
561 * needs a dedicated investigation. */
562 imb_alloc_buffer(ibuf->float_buffer, w, h, 4, sizeof(float), false);
563
564 memcpy(ibuf->float_buffer.data, float_buffer, sizeof(float[4]) * w * h);
565 }
566
567 if (byte_buffer) {
568 imb_alloc_buffer(ibuf->byte_buffer, w, h, 4, sizeof(uint8_t), false);
569
570 memcpy(ibuf->byte_buffer.data, byte_buffer, sizeof(uint8_t[4]) * w * h);
571 }
572
573 return ibuf;
574}
575
576ImBuf *IMB_allocImBuf(uint x, uint y, uchar planes, uint flags)
577{
578 ImBuf *ibuf = MEM_cnew<ImBuf>("ImBuf_struct");
579
580 if (ibuf) {
581 if (!IMB_initImBuf(ibuf, x, y, planes, flags)) {
582 IMB_freeImBuf(ibuf);
583 return nullptr;
584 }
585 }
586
587 return ibuf;
588}
589
590bool IMB_initImBuf(ImBuf *ibuf, uint x, uint y, uchar planes, uint flags)
591{
592 memset(ibuf, 0, sizeof(ImBuf));
593
594 ibuf->x = x;
595 ibuf->y = y;
596 ibuf->planes = planes;
597 ibuf->ftype = IMB_FTYPE_PNG;
598 /* The '15' means, set compression to low ratio but not time consuming. */
599 ibuf->foptions.quality = 15;
600 /* float option, is set to other values when buffers get assigned. */
601 ibuf->channels = 4;
602 /* IMB_DPI_DEFAULT -> pixels-per-meter. */
603 ibuf->ppm[0] = ibuf->ppm[1] = IMB_DPI_DEFAULT / 0.0254;
604
605 const bool init_pixels = (flags & IB_uninitialized_pixels) == 0;
606
607 if (flags & IB_rect) {
608 if (imb_addrectImBuf(ibuf, init_pixels) == false) {
609 return false;
610 }
611 }
612
613 if (flags & IB_rectfloat) {
614 if (imb_addrectfloatImBuf(ibuf, ibuf->channels, init_pixels) == false) {
615 return false;
616 }
617 }
618
619 /* assign default spaces */
621
622 return true;
623}
624
626{
627 ImBuf *ibuf2, tbuf;
628 int flags = IB_uninitialized_pixels;
629 int a, x, y;
630
631 if (ibuf1 == nullptr) {
632 return nullptr;
633 }
634
635 if (ibuf1->byte_buffer.data) {
636 flags |= IB_rect;
637 }
638
639 x = ibuf1->x;
640 y = ibuf1->y;
641
642 ibuf2 = IMB_allocImBuf(x, y, ibuf1->planes, flags);
643 if (ibuf2 == nullptr) {
644 return nullptr;
645 }
646
647 if (flags & IB_rect) {
648 memcpy(ibuf2->byte_buffer.data, ibuf1->byte_buffer.data, size_t(x) * y * 4 * sizeof(uint8_t));
649 }
650
651 if (ibuf1->float_buffer.data) {
652 /* Ensure the correct number of channels are being allocated for the new #ImBuf. Some
653 * compositing scenarios might end up with >4 channels and we want to duplicate them properly.
654 */
655 if (imb_addrectfloatImBuf(ibuf2, ibuf1->channels, false) == false) {
656 IMB_freeImBuf(ibuf2);
657 return nullptr;
658 }
659
660 memcpy(ibuf2->float_buffer.data,
661 ibuf1->float_buffer.data,
662 size_t(ibuf2->channels) * x * y * sizeof(float));
663 }
664
665 if (ibuf1->encoded_buffer.data) {
667 if (imb_addencodedbufferImBuf(ibuf2) == false) {
668 IMB_freeImBuf(ibuf2);
669 return nullptr;
670 }
671
672 memcpy(ibuf2->encoded_buffer.data, ibuf1->encoded_buffer.data, ibuf1->encoded_size);
673 }
674
677
678 /* silly trick to copy the entire contents of ibuf1 struct over to ibuf */
679 tbuf = *ibuf1;
680
681 /* fix pointers */
682 tbuf.byte_buffer = ibuf2->byte_buffer;
683 tbuf.float_buffer = ibuf2->float_buffer;
684 tbuf.encoded_buffer = ibuf2->encoded_buffer;
685 for (a = 0; a < IMB_MIPMAP_LEVELS; a++) {
686 tbuf.mipmap[a] = nullptr;
687 }
688 tbuf.dds_data.data = nullptr;
689
690 /* set malloc flag */
691 tbuf.refcounter = 0;
692
693 /* for now don't duplicate metadata */
694 tbuf.metadata = nullptr;
695
696 tbuf.display_buffer_flags = nullptr;
697 tbuf.colormanage_cache = nullptr;
698
699 /* GPU textures can not be easily copied, as it is not guaranteed that this function is called
700 * from within an active GPU context. */
701 tbuf.gpu.texture = nullptr;
702
703 *ibuf2 = tbuf;
704
705 return ibuf2;
706}
707
708size_t IMB_get_rect_len(const ImBuf *ibuf)
709{
710 return size_t(ibuf->x) * size_t(ibuf->y);
711}
712
714{
715 int a;
716 size_t size = 0, channel_size = 0;
717
718 size += sizeof(ImBuf);
719
720 if (ibuf->byte_buffer.data) {
721 channel_size += sizeof(char);
722 }
723
724 if (ibuf->float_buffer.data) {
725 channel_size += sizeof(float);
726 }
727
728 size += channel_size * ibuf->x * ibuf->y * ibuf->channels;
729
730 if (ibuf->miptot) {
731 for (a = 0; a < ibuf->miptot; a++) {
732 if (ibuf->mipmap[a]) {
733 size += IMB_get_size_in_memory(ibuf->mipmap[a]);
734 }
735 }
736 }
737
738 return size;
739}
#define BLI_assert_unreachable()
Definition BLI_assert.h:97
#define BLI_assert(a)
Definition BLI_assert.h:50
#define BLI_assert_msg(a, msg)
Definition BLI_assert.h:57
void BLI_kdtree_nd_ free(KDTree *tree)
unsigned char uchar
unsigned int uint
pthread_spinlock_t SpinLock
void BLI_spin_init(SpinLock *spin)
Definition threads.cc:391
void BLI_spin_unlock(SpinLock *spin)
Definition threads.cc:430
void BLI_spin_lock(SpinLock *spin)
Definition threads.cc:405
void BLI_spin_end(SpinLock *spin)
Definition threads.cc:445
void GPU_texture_free(GPUTexture *texture)
@ IMB_FTYPE_DDS
@ IMB_FTYPE_PNG
Contains defines and structs used throughout the imbuf module.
#define IMB_MIPMAP_LEVELS
ImBufOwnership
@ IB_DO_NOT_TAKE_OWNERSHIP
@ IB_TAKE_OWNERSHIP
@ IB_rectfloat
@ IB_uninitialized_pixels
@ IB_mem
@ IB_rect
void IMB_metadata_free(IDProperty *metadata)
Definition metadata.cc:33
void IMB_metadata_copy(ImBuf *ibuf_dst, const ImBuf *ibuf_src)
Definition metadata.cc:60
Read Guarded memory(de)allocation.
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
void imb_freerectImBuf(ImBuf *ibuf)
void IMB_free_gpu_textures(ImBuf *ibuf)
void imb_mmap_lock_exit()
Definition allocimbuf.cc:51
void imb_freerectfloatImBuf(ImBuf *ibuf)
size_t IMB_get_rect_len(const ImBuf *ibuf)
Get the length of the rect of the given image buffer in terms of pixels.
float * IMB_steal_float_buffer(ImBuf *ibuf)
void imb_refcounter_lock_init()
Definition allocimbuf.cc:33
ImBuf * IMB_dupImBuf(const ImBuf *ibuf1)
void IMB_make_writable_byte_buffer(ImBuf *ibuf)
uint8_t * IMB_steal_byte_buffer(ImBuf *ibuf)
static SpinLock mmap_spin
Definition allocimbuf.cc:44
void imb_mmap_lock()
Definition allocimbuf.cc:56
bool IMB_initImBuf(ImBuf *ibuf, uint x, uint y, uchar planes, uint flags)
ImBuf * IMB_makeSingleUser(ImBuf *ibuf)
void imb_freerectImbuf_all(ImBuf *ibuf)
void imb_mmap_lock_init()
Definition allocimbuf.cc:46
void * imb_alloc_pixels(uint x, uint y, uint channels, size_t typesize, bool initialize_pixels, const char *alloc_name)
static void imb_free_dds_buffer(DDSData &dds_data)
Definition allocimbuf.cc:89
void imb_freemipmapImBuf(ImBuf *ibuf)
void IMB_make_writable_float_buffer(ImBuf *ibuf)
bool imb_alloc_buffer(BufferType &buffer, const uint x, const uint y, const uint channels, const size_t type_size, bool initialize_pixels)
void imb_refcounter_lock_exit()
Definition allocimbuf.cc:38
ImBuf * IMB_allocImBuf(uint x, uint y, uchar planes, uint flags)
ImBuf * IMB_allocFromBufferOwn(uint8_t *byte_buffer, float *float_buffer, uint w, uint h, uint channels)
bool imb_enlargeencodedbufferImBuf(ImBuf *ibuf)
bool imb_addrectImBuf(ImBuf *ibuf, bool initialize_pixels)
void IMB_freeImBuf(ImBuf *ibuf)
void imb_make_writeable_buffer(BufferType &buffer)
void IMB_refImBuf(ImBuf *ibuf)
static SpinLock refcounter_spin
Definition allocimbuf.cc:31
uint8_t * IMB_steal_encoded_buffer(ImBuf *ibuf)
bool imb_addrectfloatImBuf(ImBuf *ibuf, const uint channels, bool initialize_pixels)
static void freeencodedbufferImBuf(ImBuf *ibuf)
void IMB_assign_dds_data(ImBuf *ibuf, const DDSData &data, const ImBufOwnership ownership)
auto imb_steal_buffer_data(BufferType &buffer) -> decltype(BufferType::data)
void IMB_assign_byte_buffer(ImBuf *ibuf, uint8_t *buffer_data, const ImBufOwnership ownership)
void imb_mmap_unlock()
Definition allocimbuf.cc:61
ImBuf * IMB_allocFromBuffer(const uint8_t *byte_buffer, const float *float_buffer, uint w, uint h, uint channels)
static void imb_free_buffer(BufferType &buffer)
Definition allocimbuf.cc:69
size_t IMB_get_size_in_memory(ImBuf *ibuf)
bool imb_addencodedbufferImBuf(ImBuf *ibuf)
void IMB_assign_float_buffer(ImBuf *ibuf, float *buffer_data, const ImBufOwnership ownership)
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition btDbvt.cpp:52
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
Definition btQuadWord.h:119
void colormanage_cache_free(ImBuf *ibuf)
void colormanage_imbuf_set_default_spaces(ImBuf *ibuf)
#define printf
draw_view in_light_buf[] float
#define IMB_DPI_DEFAULT
Definition imbuf.hh:29
void *(* MEM_mallocN)(size_t len, const char *str)
Definition mallocn.cc:44
size_t(* MEM_allocN_len)(const void *vmemh)
Definition mallocn.cc:36
void MEM_freeN(void *vmemh)
Definition mallocn.cc:105
void *(* MEM_callocN)(size_t len, const char *str)
Definition mallocn.cc:42
void *(* MEM_dupallocN)(const void *vmemh)
Definition mallocn.cc:39
#define SIZE_MAX
Definition stdint.h:206
unsigned char uint8_t
Definition stdint.h:78
unsigned __int64 uint64_t
Definition stdint.h:90
ImBufOwnership ownership
unsigned char * data
ImBufOwnership ownership
ColorSpace * colorspace
ImBufOwnership ownership
ColorSpace * colorspace
GPUTexture * texture
ImBufGPU gpu
char filepath[IMB_FILEPATH_SIZE]
DDSData dds_data
ImBufFloatBuffer float_buffer
ImbFormatOptions foptions
ImBufByteBuffer byte_buffer
unsigned char planes
enum eImbFileType ftype
ImBuf * mipmap[IMB_MIPMAP_LEVELS]
unsigned int encoded_buffer_size
unsigned int * display_buffer_flags
IDProperty * metadata
ColormanageCache * colormanage_cache
ImBufByteBuffer encoded_buffer
double ppm[2]
unsigned int encoded_size