Refactor ImBuf buffer access

The goal is to make it more explicit and centralized operation to
assign and steal buffer data, with proper ownership tracking.

The buffers and ownership flags are wrapped into their dedicated
structures now.

There should be no functional changes currently, it is a preparation
for allowing implicit sharing of the ImBuf buffers. Additionally, in
the future it is possible to more buffer-specific information (such
as color space) next to the buffer data itself. It is also possible
to clean up the allocation flags (IB_rect, ...) to give them more
clear naming and not have stored in the ImBuf->flags as they are only
needed for allocation.

The most dangerous part of this change is the change of byte buffer
data from `int*` to `uint8_t*`. In a lot of cases the byte buffer was
cast to `uchar*`, so those casts are now gone. But some code is
operating on `int*` so now there are casts in there. In practice this
should be fine, since we only support 64bit platforms, so allocations
are aligned. The real things to watch out for here is the fact that
allocation and offsetting from the byte buffer now need an explicit 4
channel multiplier.

Once everything is C++ it will be possible to simplify public
functions even further.

Pull Request: blender/blender#107609
This commit is contained in:
2023-05-18 10:19:01 +02:00
committed by Sergey Sharybin
parent 07058765b9
commit 406cfd214a
121 changed files with 1594 additions and 1362 deletions
+2 -2
View File
@@ -1261,7 +1261,7 @@ GHOST_TSuccess GHOST_SystemCocoa::handleDraggingEvent(GHOST_TEventType eventType
![bitmapImage isPlanar])
{
/* Try a fast copy if the image is a meshed RGBA 32bit bitmap. */
toIBuf = (uint8_t *)ibuf->rect;
toIBuf = ibuf->byte_buffer.data;
rasterRGB = (uint8_t *)[bitmapImage bitmapData];
for (y = 0; y < imgSize.height; y++) {
to_i = (imgSize.height - y - 1) * imgSize.width;
@@ -1338,7 +1338,7 @@ GHOST_TSuccess GHOST_SystemCocoa::handleDraggingEvent(GHOST_TEventType eventType
}
/* Copy the image to ibuf, flipping it vertically. */
toIBuf = (uint8_t *)ibuf->rect;
toIBuf = ibuf->byte_buffer.data;
for (y = 0; y < imgSize.height; y++) {
for (x = 0; x < imgSize.width; x++) {
to_i = (imgSize.height - y - 1) * imgSize.width + x;
+4 -4
View File
@@ -2422,7 +2422,7 @@ static uint *getClipboardImageImBuf(int *r_width, int *r_height, UINT format)
*r_width = ibuf->x;
*r_height = ibuf->y;
rgba = (uint *)malloc(4 * ibuf->x * ibuf->y);
memcpy(rgba, ibuf->rect, 4 * ibuf->x * ibuf->y);
memcpy(rgba, ibuf->byte_buffer.data, 4 * ibuf->x * ibuf->y);
IMB_freeImBuf(ibuf);
}
@@ -2513,7 +2513,7 @@ static bool putClipboardImagePNG(uint *rgba, int width, int height)
UINT cf = RegisterClipboardFormat("PNG");
/* Load buffer into ImBuf, convert to PNG. */
ImBuf *ibuf = IMB_allocFromBuffer(rgba, nullptr, width, height, 32);
ImBuf *ibuf = IMB_allocFromBuffer(reinterpret_cast<uint8_t *>(rgba), nullptr, width, height, 32);
ibuf->ftype = IMB_FTYPE_PNG;
ibuf->foptions.quality = 15;
if (!IMB_saveiff(ibuf, "<memory>", IB_rect | IB_mem)) {
@@ -2521,7 +2521,7 @@ static bool putClipboardImagePNG(uint *rgba, int width, int height)
return false;
}
HGLOBAL hMem = GlobalAlloc(GHND, ibuf->encodedbuffersize);
HGLOBAL hMem = GlobalAlloc(GHND, ibuf->encoded_buffer_size);
if (!hMem) {
IMB_freeImBuf(ibuf);
return false;
@@ -2534,7 +2534,7 @@ static bool putClipboardImagePNG(uint *rgba, int width, int height)
return false;
}
memcpy(pMem, ibuf->encodedbuffer, ibuf->encodedbuffersize);
memcpy(pMem, ibuf->encoded_buffer.data, ibuf->encoded_buffer_size);
GlobalUnlock(hMem);
IMB_freeImBuf(ibuf);
@@ -57,13 +57,14 @@ template<typename T, int Channels = 4> struct ImageBufferAccessor {
{
if constexpr ((std::is_same_v<T, float4>)) {
int offset = (coordinate.y * image_buffer.x + coordinate.x) * Channels;
return float4(&image_buffer.rect_float[offset]);
return float4(&image_buffer.float_buffer.data[offset]);
}
if constexpr ((std::is_same_v<T, int>)) {
int offset = (coordinate.y * image_buffer.x + coordinate.x);
float4 result;
rgba_uchar_to_float(result,
static_cast<uchar *>(static_cast<void *>(&image_buffer.rect[offset])));
rgba_uchar_to_float(
result,
static_cast<uchar *>(static_cast<void *>(&image_buffer.byte_buffer.data[offset])));
return result;
}
return float4();
@@ -73,12 +74,13 @@ template<typename T, int Channels = 4> struct ImageBufferAccessor {
{
if constexpr ((std::is_same_v<T, float>)) {
int offset = (coordinate.y * image_buffer.x + coordinate.x) * Channels;
copy_v4_v4(&image_buffer.rect_float[offset], new_value);
copy_v4_v4(&image_buffer.float_buffer.data[offset], new_value);
}
if constexpr ((std::is_same_v<T, int>)) {
int offset = (coordinate.y * image_buffer.x + coordinate.x);
rgba_float_to_uchar(static_cast<uchar *>(static_cast<void *>(&image_buffer.rect[offset])),
new_value);
rgba_float_to_uchar(
static_cast<uchar *>(static_cast<void *>(&image_buffer.byte_buffer.data[offset])),
new_value);
}
}
};
+1 -1
View File
@@ -346,7 +346,7 @@ struct CopyPixelTile {
void copy_pixels(ImBuf &tile_buffer, IndexRange group_range) const
{
if (tile_buffer.rect_float) {
if (tile_buffer.float_buffer.data) {
image::ImageBufferAccessor<float4> accessor(tile_buffer);
copy_pixels<float4>(accessor, group_range);
}
+8 -4
View File
@@ -2624,18 +2624,22 @@ struct ImBuf *BKE_brush_gen_radial_control_imbuf(Brush *br, bool secondary, bool
int half = side / 2;
BKE_curvemapping_init(br->curve);
im->rect_float = (float *)MEM_callocN(sizeof(float) * side * side, "radial control rect");
float *rect_float = (float *)MEM_callocN(sizeof(float) * side * side, "radial control rect");
IMB_assign_float_buffer(im, rect_float, IB_DO_NOT_TAKE_OWNERSHIP);
im->x = im->y = side;
const bool have_texture = brush_gen_texture(br, side, secondary, im->rect_float);
const bool have_texture = brush_gen_texture(br, side, secondary, im->float_buffer.data);
if (display_gradient || have_texture) {
for (int i = 0; i < side; i++) {
for (int j = 0; j < side; j++) {
const float magn = sqrtf(pow2f(i - half) + pow2f(j - half));
const float strength = BKE_brush_curve_strength_clamped(br, magn, half);
im->rect_float[i * side + j] = (have_texture) ? im->rect_float[i * side + j] * strength :
strength;
im->float_buffer.data[i * side + j] = (have_texture) ?
im->float_buffer.data[i * side + j] * strength :
strength;
}
}
}
+10 -10
View File
@@ -1382,11 +1382,11 @@ void BKE_histogram_update_sample_line(Histogram *hist,
hist->xmax = 1.0f;
/* hist->ymax = 1.0f; */ /* now do this on the operator _only_ */
if (ibuf->rect == NULL && ibuf->rect_float == NULL) {
if (ibuf->byte_buffer.data == NULL && ibuf->float_buffer.data == NULL) {
return;
}
if (ibuf->rect_float) {
if (ibuf->float_buffer.data) {
cm_processor = IMB_colormanagement_display_processor_new(view_settings, display_settings);
}
@@ -1399,9 +1399,9 @@ void BKE_histogram_update_sample_line(Histogram *hist,
0.0f;
}
else {
if (ibuf->rect_float) {
if (ibuf->float_buffer.data) {
float rgba[4];
fp = (ibuf->rect_float + (ibuf->channels) * (y * ibuf->x + x));
fp = (ibuf->float_buffer.data + (ibuf->channels) * (y * ibuf->x + x));
switch (ibuf->channels) {
case 4:
@@ -1431,8 +1431,8 @@ void BKE_histogram_update_sample_line(Histogram *hist,
hist->data_b[i] = rgba[2];
hist->data_a[i] = rgba[3];
}
else if (ibuf->rect) {
cp = (uchar *)(ibuf->rect + y * ibuf->x + x);
else if (ibuf->byte_buffer.data) {
cp = ibuf->byte_buffer.data + 4 * (y * ibuf->x + x);
hist->data_luma[i] = (float)IMB_colormanagement_get_luminance_byte(cp) / 255.0f;
hist->data_r[i] = (float)cp[0] / 255.0f;
hist->data_g[i] = (float)cp[1] / 255.0f;
@@ -1492,10 +1492,10 @@ static void scopes_update_cb(void *__restrict userdata,
const int savedlines = y / rows_per_sample_line;
const bool do_sample_line = (savedlines < scopes->sample_lines) &&
(y % rows_per_sample_line) == 0;
const bool is_float = (ibuf->rect_float != NULL);
const bool is_float = (ibuf->float_buffer.data != NULL);
if (is_float) {
rf = ibuf->rect_float + ((size_t)y) * ibuf->x * ibuf->channels;
rf = ibuf->float_buffer.data + ((size_t)y) * ibuf->x * ibuf->channels;
}
else {
rc = display_buffer + ((size_t)y) * ibuf->x * ibuf->channels;
@@ -1616,7 +1616,7 @@ void BKE_scopes_update(Scopes *scopes,
void *cache_handle = NULL;
struct ColormanageProcessor *cm_processor = NULL;
if (ibuf->rect == NULL && ibuf->rect_float == NULL) {
if (ibuf->byte_buffer.data == NULL && ibuf->float_buffer.data == NULL) {
return;
}
@@ -1692,7 +1692,7 @@ void BKE_scopes_update(Scopes *scopes,
scopes->vecscope = MEM_callocN(scopes->waveform_tot * 2 * sizeof(float),
"vectorscope point channel");
if (ibuf->rect_float) {
if (ibuf->float_buffer.data) {
cm_processor = IMB_colormanagement_display_processor_new(view_settings, display_settings);
}
else {
@@ -3210,12 +3210,15 @@ static void dynamic_paint_output_surface_image_paint_cb(void *__restrict userdat
const int pos = ((ImgSeqFormatData *)(surface->data->format_data))->uv_p[index].pixel_index * 4;
/* blend wet and dry layers */
blendColors(
point->color, point->color[3], point->e_color, point->e_color[3], &ibuf->rect_float[pos]);
blendColors(point->color,
point->color[3],
point->e_color,
point->e_color[3],
&ibuf->float_buffer.data[pos]);
/* Multiply color by alpha if enabled */
if (surface->flags & MOD_DPAINT_MULALPHA) {
mul_v3_fl(&ibuf->rect_float[pos], ibuf->rect_float[pos + 3]);
mul_v3_fl(&ibuf->float_buffer.data[pos], ibuf->float_buffer.data[pos + 3]);
}
}
@@ -3242,8 +3245,8 @@ static void dynamic_paint_output_surface_image_displace_cb(
CLAMP(depth, 0.0f, 1.0f);
copy_v3_fl(&ibuf->rect_float[pos], depth);
ibuf->rect_float[pos + 3] = 1.0f;
copy_v3_fl(&ibuf->float_buffer.data[pos], depth);
ibuf->float_buffer.data[pos + 3] = 1.0f;
}
static void dynamic_paint_output_surface_image_wave_cb(void *__restrict userdata,
@@ -3268,8 +3271,8 @@ static void dynamic_paint_output_surface_image_wave_cb(void *__restrict userdata
depth = (0.5f + depth / 2.0f);
CLAMP(depth, 0.0f, 1.0f);
copy_v3_fl(&ibuf->rect_float[pos], depth);
ibuf->rect_float[pos + 3] = 1.0f;
copy_v3_fl(&ibuf->float_buffer.data[pos], depth);
ibuf->float_buffer.data[pos + 3] = 1.0f;
}
static void dynamic_paint_output_surface_image_wetmap_cb(void *__restrict userdata,
@@ -3286,8 +3289,8 @@ static void dynamic_paint_output_surface_image_wetmap_cb(void *__restrict userda
/* image buffer position */
const int pos = ((ImgSeqFormatData *)(surface->data->format_data))->uv_p[index].pixel_index * 4;
copy_v3_fl(&ibuf->rect_float[pos], (point->wetness > 1.0f) ? 1.0f : point->wetness);
ibuf->rect_float[pos + 3] = 1.0f;
copy_v3_fl(&ibuf->float_buffer.data[pos], (point->wetness > 1.0f) ? 1.0f : point->wetness);
ibuf->float_buffer.data[pos + 3] = 1.0f;
}
void dynamicPaint_outputSurfaceImage(DynamicPaintSurface *surface,
@@ -2308,7 +2308,7 @@ bool BKE_gpencil_from_image(
ibuf = BKE_image_acquire_ibuf(image, &iuser, &lock);
if (ibuf && ibuf->rect) {
if (ibuf && ibuf->byte_buffer.data) {
int img_x = ibuf->x;
int img_y = ibuf->y;
+3 -3
View File
@@ -552,7 +552,7 @@ void BKE_previewimg_ensure(PreviewImage *prv, const int size)
if (do_preview) {
prv->w[ICON_SIZE_PREVIEW] = thumb->x;
prv->h[ICON_SIZE_PREVIEW] = thumb->y;
prv->rect[ICON_SIZE_PREVIEW] = (uint *)MEM_dupallocN(thumb->rect);
prv->rect[ICON_SIZE_PREVIEW] = (uint *)MEM_dupallocN(thumb->byte_buffer.data);
prv->flag[ICON_SIZE_PREVIEW] &= ~(PRV_CHANGED | PRV_USER_EDITED | PRV_RENDERING);
}
if (do_icon) {
@@ -571,7 +571,7 @@ void BKE_previewimg_ensure(PreviewImage *prv, const int size)
IMB_scaleImBuf(thumb, icon_w, icon_h);
prv->w[ICON_SIZE_ICON] = icon_w;
prv->h[ICON_SIZE_ICON] = icon_h;
prv->rect[ICON_SIZE_ICON] = (uint *)MEM_dupallocN(thumb->rect);
prv->rect[ICON_SIZE_ICON] = (uint *)MEM_dupallocN(thumb->byte_buffer.data);
prv->flag[ICON_SIZE_ICON] &= ~(PRV_CHANGED | PRV_USER_EDITED | PRV_RENDERING);
}
IMB_freeImBuf(thumb);
@@ -588,7 +588,7 @@ ImBuf *BKE_previewimg_to_imbuf(PreviewImage *prv, const int size)
if (w > 0 && h > 0 && rect) {
/* first allocate imbuf for copying preview into it */
ima = IMB_allocImBuf(w, h, 32, IB_rect);
memcpy(ima->rect, rect, w * h * sizeof(*ima->rect));
memcpy(ima->byte_buffer.data, rect, w * h * sizeof(uint8_t) * 4);
}
return ima;
@@ -85,7 +85,7 @@ ImBuf *BKE_icon_geom_rasterize(const struct Icon_Geom *geom, const uint size_x,
data.rect_size[0] = rect_size[0];
data.rect_size[1] = rect_size[1];
data.rect = ibuf->rect;
data.rect = (uint *)ibuf->byte_buffer.data;
float scale[2];
const bool use_scale = (rect_size[0] != 256) || (rect_size[1] != 256);
+30 -75
View File
@@ -1138,7 +1138,7 @@ static ImBuf *add_ibuf_for_tile(Image *ima, ImageTile *tile)
}
if (ibuf != nullptr) {
rect_float = ibuf->rect_float;
rect_float = ibuf->float_buffer.data;
IMB_colormanagement_check_is_data(ibuf, ima->colorspace_settings.name);
}
@@ -1162,7 +1162,7 @@ static ImBuf *add_ibuf_for_tile(Image *ima, ImageTile *tile)
}
if (ibuf != nullptr) {
rect = (uchar *)ibuf->rect;
rect = ibuf->byte_buffer.data;
IMB_colormanagement_assign_rect_colorspace(ibuf, ima->colorspace_settings.name);
}
@@ -1261,7 +1261,7 @@ static void image_colorspace_from_imbuf(Image *image, const ImBuf *ibuf)
{
const char *colorspace_name = nullptr;
if (ibuf->rect_float) {
if (ibuf->float_buffer.data) {
if (ibuf->float_colorspace) {
colorspace_name = IMB_colormanagement_colorspace_get_name(ibuf->float_colorspace);
}
@@ -1270,7 +1270,7 @@ static void image_colorspace_from_imbuf(Image *image, const ImBuf *ibuf)
}
}
if (ibuf->rect && !colorspace_name) {
if (ibuf->byte_buffer.data && !colorspace_name) {
if (ibuf->rect_colorspace) {
colorspace_name = IMB_colormanagement_colorspace_get_name(ibuf->rect_colorspace);
}
@@ -1318,7 +1318,7 @@ void BKE_image_replace_imbuf(Image *image, ImBuf *ibuf)
/* Keep generated image type flags consistent with the image buffer. */
if (image->source == IMA_SRC_GENERATED) {
if (ibuf->rect_float) {
if (ibuf->float_buffer.data) {
image->gen_flag |= IMA_GEN_FLOAT;
}
else {
@@ -1338,11 +1338,11 @@ void BKE_image_replace_imbuf(Image *image, ImBuf *ibuf)
static bool image_memorypack_imbuf(
Image *ima, ImBuf *ibuf, int view, int tile_number, const char *filepath)
{
ibuf->ftype = (ibuf->rect_float) ? IMB_FTYPE_OPENEXR : IMB_FTYPE_PNG;
ibuf->ftype = (ibuf->float_buffer.data) ? IMB_FTYPE_OPENEXR : IMB_FTYPE_PNG;
IMB_saveiff(ibuf, filepath, IB_rect | IB_mem);
if (ibuf->encodedbuffer == nullptr) {
if (ibuf->encoded_buffer.data == nullptr) {
CLOG_STR_ERROR(&LOG, "memory save for pack error");
IMB_freeImBuf(ibuf);
image_free_packedfiles(ima);
@@ -1352,8 +1352,8 @@ static bool image_memorypack_imbuf(
ImagePackedFile *imapf;
PackedFile *pf = MEM_cnew<PackedFile>("PackedFile");
pf->data = ibuf->encodedbuffer;
pf->size = ibuf->encodedsize;
pf->data = IMB_steal_encoded_buffer(ibuf);
pf->size = ibuf->encoded_size;
imapf = static_cast<ImagePackedFile *>(MEM_mallocN(sizeof(ImagePackedFile), "Image PackedFile"));
STRNCPY(imapf->filepath, filepath);
@@ -1362,8 +1362,6 @@ static bool image_memorypack_imbuf(
imapf->tile_number = tile_number;
BLI_addtail(&ima->packedfiles, imapf);
ibuf->encodedbuffer = nullptr;
ibuf->encodedsize = 0;
ibuf->userflags &= ~IB_BITMAPDIRTY;
return true;
@@ -1505,26 +1503,12 @@ static uintptr_t image_mem_size(Image *image)
if (ibuf == nullptr) {
continue;
}
ImBuf *ibufm;
int level;
if (ibuf->rect) {
size += MEM_allocN_len(ibuf->rect);
}
if (ibuf->rect_float) {
size += MEM_allocN_len(ibuf->rect_float);
}
size += IMB_get_size_in_memory(ibuf);
for (level = 0; level < IMB_MIPMAP_LEVELS; level++) {
ibufm = ibuf->mipmap[level];
if (ibufm) {
if (ibufm->rect) {
size += MEM_allocN_len(ibufm->rect);
}
if (ibufm->rect_float) {
size += MEM_allocN_len(ibufm->rect_float);
}
}
for (int level = 0; level < IMB_MIPMAP_LEVELS; level++) {
ImBuf *ibufm = ibuf->mipmap[level];
size += IMB_get_size_in_memory(ibufm);
}
}
IMB_moviecacheIter_free(iter);
@@ -2537,16 +2521,16 @@ void BKE_stamp_info_from_imbuf(RenderResult *rr, ImBuf *ibuf)
bool BKE_imbuf_alpha_test(ImBuf *ibuf)
{
int tot;
if (ibuf->rect_float) {
const float *buf = ibuf->rect_float;
if (ibuf->float_buffer.data) {
const float *buf = ibuf->float_buffer.data;
for (tot = ibuf->x * ibuf->y; tot--; buf += 4) {
if (buf[3] < 1.0f) {
return true;
}
}
}
else if (ibuf->rect) {
uchar *buf = (uchar *)ibuf->rect;
else if (ibuf->byte_buffer.data) {
uchar *buf = ibuf->byte_buffer.data;
for (tot = ibuf->x * ibuf->y; tot--; buf += 4) {
if (buf[3] != 255) {
return true;
@@ -4007,9 +3991,8 @@ static ImBuf *image_load_sequence_multilayer(Image *ima, ImageUser *iuser, int e
// printf("load from pass %s\n", rpass->name);
/* since we free render results, we copy the rect */
ibuf = IMB_allocImBuf(ima->rr->rectx, ima->rr->recty, 32, 0);
ibuf->rect_float = static_cast<float *>(MEM_dupallocN(rpass->rect));
ibuf->flags |= IB_rectfloat;
ibuf->mall = IB_rectfloat;
IMB_assign_float_buffer(
ibuf, static_cast<float *>(MEM_dupallocN(rpass->rect)), IB_TAKE_OWNERSHIP);
ibuf->channels = rpass->channels;
BKE_imbuf_stamp_info(ima->rr, ibuf);
@@ -4318,8 +4301,7 @@ static ImBuf *image_get_ibuf_multilayer(Image *ima, ImageUser *iuser)
image_init_after_load(ima, iuser, ibuf);
ibuf->rect_float = rpass->rect;
ibuf->flags |= IB_rectfloat;
IMB_assign_float_buffer(ibuf, rpass->rect, IB_DO_NOT_TAKE_OWNERSHIP);
ibuf->channels = rpass->channels;
BKE_imbuf_stamp_info(ima->rr, ibuf);
@@ -4459,56 +4441,29 @@ static ImBuf *image_get_render_result(Image *ima, ImageUser *iuser, void **r_loc
*
* For other cases we need to be sure it stays to default byte buffer space.
*/
if (ibuf->rect != rect) {
if (ibuf->byte_buffer.data != (uint8_t *)rect) {
const char *colorspace = IMB_colormanagement_role_colorspace_name_get(COLOR_ROLE_DEFAULT_BYTE);
IMB_colormanagement_assign_rect_colorspace(ibuf, colorspace);
}
/* invalidate color managed buffers if render result changed */
BLI_thread_lock(LOCK_COLORMANAGE);
if (ibuf->x != rres.rectx || ibuf->y != rres.recty || ibuf->rect_float != rectf) {
if (ibuf->x != rres.rectx || ibuf->y != rres.recty || ibuf->float_buffer.data != rectf) {
ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID;
}
ibuf->x = rres.rectx;
ibuf->y = rres.recty;
ibuf->channels = channels;
if (rect) {
imb_freerectImBuf(ibuf);
ibuf->rect = rect;
}
else {
/* byte buffer of render result has been freed, make sure image buffers
* does not reference to this buffer anymore
* need check for whether byte buffer was allocated and owned by image itself
* or if it's reusing buffer from render result
*/
if ((ibuf->mall & IB_rect) == 0) {
ibuf->rect = nullptr;
}
}
imb_freerectImBuf(ibuf);
if (rectf) {
ibuf->rect_float = rectf;
ibuf->flags |= IB_rectfloat;
ibuf->channels = channels;
}
else {
ibuf->rect_float = nullptr;
ibuf->flags &= ~IB_rectfloat;
}
if (rectz) {
ibuf->zbuf_float = rectz;
ibuf->flags |= IB_zbuffloat;
}
else {
ibuf->zbuf_float = nullptr;
ibuf->flags &= ~IB_zbuffloat;
}
IMB_assign_byte_buffer(ibuf, (uint8_t *)rect, IB_DO_NOT_TAKE_OWNERSHIP);
IMB_assign_float_buffer(ibuf, rectf, IB_DO_NOT_TAKE_OWNERSHIP);
IMB_assign_float_z_buffer(ibuf, rectz, IB_DO_NOT_TAKE_OWNERSHIP);
/* TODO(sergey): Make this faster by either simply referencing the stamp
* or by changing both ImBug and RenderResult to use same data type to
* or by changing both ImBuf and RenderResult to use same data type to
* store metadata. */
if (ibuf->metadata != nullptr) {
IMB_metadata_free(ibuf->metadata);
@@ -5269,7 +5224,7 @@ uchar *BKE_image_get_pixels_for_frame(struct Image *image, int frame, int tile)
ibuf = BKE_image_acquire_ibuf(image, &iuser, &lock);
if (ibuf) {
pixels = (uchar *)ibuf->rect;
pixels = ibuf->byte_buffer.data;
if (pixels) {
pixels = static_cast<uchar *>(MEM_dupallocN(pixels));
@@ -5299,7 +5254,7 @@ float *BKE_image_get_float_pixels_for_frame(struct Image *image, int frame, int
ibuf = BKE_image_acquire_ibuf(image, &iuser, &lock);
if (ibuf) {
pixels = ibuf->rect_float;
pixels = ibuf->float_buffer.data;
if (pixels) {
pixels = static_cast<float *>(MEM_dupallocN(pixels));
@@ -799,7 +799,7 @@ void BKE_image_format_from_imbuf(ImageFormatData *im_format, const ImBuf *imbuf)
if (custom_flags & OPENEXR_COMPRESS) {
im_format->exr_codec = R_IMF_EXR_CODEC_ZIP; /* Can't determine compression */
}
if (imbuf->zbuf_float) {
if (imbuf->float_z_buffer.data) {
im_format->flag |= R_IMF_FLAG_ZBUF;
}
}
+10 -9
View File
@@ -50,11 +50,11 @@ bool BKE_image_has_gpu_texture_premultiplied_alpha(Image *image, ImBuf *ibuf)
}
/* Generated images use pre multiplied float buffer, but straight alpha for byte buffers. */
if (image->type == IMA_TYPE_UV_TEST && ibuf) {
return ibuf->rect_float != nullptr;
return ibuf->float_buffer.data != nullptr;
}
}
if (ibuf) {
if (ibuf->rect_float) {
if (ibuf->float_buffer.data) {
return image ? (image->alpha_mode != IMA_ALPHA_STRAIGHT) : false;
}
@@ -643,7 +643,7 @@ static ImBuf *update_do_scale(uchar *rect,
}
/* Scale pixels. */
ImBuf *ibuf = IMB_allocFromBuffer((uint *)rect, rect_float, part_w, part_h, 4);
ImBuf *ibuf = IMB_allocFromBuffer(rect, rect_float, part_w, part_h, 4);
IMB_scaleImBuf(ibuf, *w, *h);
return ibuf;
@@ -679,8 +679,9 @@ static void gpu_texture_update_scaled(GPUTexture *tex,
ibuf = update_do_scale(rect, rect_float, &x, &y, &w, &h, limit_w, limit_h, full_w, full_h);
}
void *data = (ibuf->rect_float) ? (void *)(ibuf->rect_float) : (void *)(ibuf->rect);
eGPUDataFormat data_format = (ibuf->rect_float) ? GPU_DATA_FLOAT : GPU_DATA_UBYTE;
void *data = (ibuf->float_buffer.data) ? (void *)(ibuf->float_buffer.data) :
(void *)(ibuf->byte_buffer.data);
eGPUDataFormat data_format = (ibuf->float_buffer.data) ? GPU_DATA_FLOAT : GPU_DATA_UBYTE;
GPU_texture_update_sub(tex, data_format, data, x, y, layer, w, h, 1);
@@ -742,8 +743,8 @@ static void gpu_texture_update_from_ibuf(
}
/* Get texture data pointers. */
float *rect_float = ibuf->rect_float;
uchar *rect = (uchar *)ibuf->rect;
float *rect_float = ibuf->float_buffer.data;
uchar *rect = ibuf->byte_buffer.data;
int tex_stride = ibuf->x;
int tex_offset = ibuf->channels * (y * ibuf->x + x);
@@ -832,10 +833,10 @@ static void gpu_texture_update_from_ibuf(
}
/* Free buffers if needed. */
if (rect && rect != (uchar *)ibuf->rect) {
if (rect && rect != ibuf->byte_buffer.data) {
MEM_freeN(rect);
}
if (rect_float && rect_float != ibuf->rect_float) {
if (rect_float && rect_float != ibuf->float_buffer.data) {
MEM_freeN(rect_float);
}
+7 -14
View File
@@ -42,7 +42,7 @@ static char imtype_best_depth(ImBuf *ibuf, const char imtype)
{
const char depth_ok = BKE_imtype_valid_depths(imtype);
if (ibuf->rect_float) {
if (ibuf->float_buffer.data) {
if (depth_ok & R_IMF_CHAN_DEPTH_32) {
return R_IMF_CHAN_DEPTH_32;
}
@@ -298,18 +298,10 @@ static void image_save_post(ReportList *reports,
/* workaround to ensure the render result buffer is no longer used
* by this image, otherwise can crash when a new render result is
* created. */
if (ibuf->rect && !(ibuf->mall & IB_rect)) {
imb_freerectImBuf(ibuf);
}
if (ibuf->rect_float && !(ibuf->mall & IB_rectfloat)) {
imb_freerectfloatImBuf(ibuf);
}
if (ibuf->zbuf && !(ibuf->mall & IB_zbuf)) {
IMB_freezbufImBuf(ibuf);
}
if (ibuf->zbuf_float && !(ibuf->mall & IB_zbuffloat)) {
IMB_freezbuffloatImBuf(ibuf);
}
imb_freerectImBuf(ibuf);
imb_freerectfloatImBuf(ibuf);
IMB_freezbufImBuf(ibuf);
IMB_freezbuffloatImBuf(ibuf);
}
if (ELEM(ima->source, IMA_SRC_GENERATED, IMA_SRC_VIEWER)) {
ima->source = IMA_SRC_FILE;
@@ -365,7 +357,8 @@ static bool image_save_single(ReportList *reports,
RenderResult *rr = nullptr;
bool ok = false;
if (ibuf == nullptr || (ibuf->rect == nullptr && ibuf->rect_float == nullptr)) {
if (ibuf == nullptr || (ibuf->byte_buffer.data == nullptr && ibuf->float_buffer.data == nullptr))
{
BKE_image_release_ibuf(ima, ibuf, lock);
return ok;
}
+2 -2
View File
@@ -523,7 +523,7 @@ BlendThumbnail *BKE_main_thumbnail_from_imbuf(Main *bmain, ImBuf *img)
IMB_rect_from_float(img); /* Just in case... */
data->width = img->x;
data->height = img->y;
memcpy(data->rect, img->rect, data_size - sizeof(*data));
memcpy(data->rect, img->byte_buffer.data, data_size - sizeof(*data));
}
if (bmain) {
@@ -542,7 +542,7 @@ ImBuf *BKE_main_thumbnail_to_imbuf(Main *bmain, BlendThumbnail *data)
if (data) {
img = IMB_allocFromBuffer(
(const uint *)data->rect, NULL, (uint)data->width, (uint)data->height, 4);
(const uint8_t *)data->rect, NULL, (uint)data->width, (uint)data->height, 4);
}
return img;
+4 -6
View File
@@ -548,11 +548,9 @@ void BKE_movieclip_convert_multilayer_ibuf(struct ImBuf *ibuf)
movieclip_convert_multilayer_add_layer,
movieclip_convert_multilayer_add_pass);
if (ctx.combined_pass != NULL) {
BLI_assert(ibuf->rect_float == NULL);
ibuf->rect_float = ctx.combined_pass;
BLI_assert(ibuf->float_buffer.data == NULL);
IMB_assign_float_buffer(ibuf, ctx.combined_pass, IB_TAKE_OWNERSHIP);
ibuf->channels = ctx.num_combined_channels;
ibuf->flags |= IB_rectfloat;
ibuf->mall |= IB_rectfloat;
}
IMB_exr_close(ibuf->userdata);
ibuf->userdata = NULL;
@@ -1732,7 +1730,7 @@ void BKE_movieclip_update_scopes(MovieClip *clip,
scopes->track_disabled = false;
if (ibuf && (ibuf->rect || ibuf->rect_float)) {
if (ibuf && (ibuf->byte_buffer.data || ibuf->float_buffer.data)) {
MovieTrackingMarker undist_marker = *marker;
if (user->render_flag & MCLIP_PROXY_RENDER_UNDISTORT) {
@@ -2049,7 +2047,7 @@ GPUTexture *BKE_movieclip_get_gpu_texture(MovieClip *clip, MovieClipUser *cuser)
/* This only means RGBA16F instead of RGBA32F. */
const bool high_bitdepth = false;
const bool store_premultiplied = ibuf->rect_float ? false : true;
const bool store_premultiplied = ibuf->float_buffer.data ? false : true;
*tex = IMB_create_gpu_texture(clip->id.name + 2, ibuf, high_bitdepth, store_premultiplied);
/* Do not generate mips for movieclips... too slow. */
+11 -10
View File
@@ -1286,23 +1286,23 @@ void BKE_ocean_cache_eval_ij(struct OceanCache *och, struct OceanResult *ocr, in
j = j % res_y;
if (och->ibufs_disp[f]) {
copy_v3_v3(ocr->disp, &och->ibufs_disp[f]->rect_float[4 * (res_x * j + i)]);
copy_v3_v3(ocr->disp, &och->ibufs_disp[f]->float_buffer.data[4 * (res_x * j + i)]);
}
if (och->ibufs_foam[f]) {
ocr->foam = och->ibufs_foam[f]->rect_float[4 * (res_x * j + i)];
ocr->foam = och->ibufs_foam[f]->float_buffer.data[4 * (res_x * j + i)];
}
if (och->ibufs_spray[f]) {
copy_v3_v3(ocr->Eplus, &och->ibufs_spray[f]->rect_float[4 * (res_x * j + i)]);
copy_v3_v3(ocr->Eplus, &och->ibufs_spray[f]->float_buffer.data[4 * (res_x * j + i)]);
}
if (och->ibufs_spray_inverse[f]) {
copy_v3_v3(ocr->Eminus, &och->ibufs_spray_inverse[f]->rect_float[4 * (res_x * j + i)]);
copy_v3_v3(ocr->Eminus, &och->ibufs_spray_inverse[f]->float_buffer.data[4 * (res_x * j + i)]);
}
if (och->ibufs_norm[f]) {
copy_v3_v3(ocr->normal, &och->ibufs_norm[f]->rect_float[4 * (res_x * j + i)]);
copy_v3_v3(ocr->normal, &och->ibufs_norm[f]->float_buffer.data[4 * (res_x * j + i)]);
}
}
@@ -1435,7 +1435,7 @@ void BKE_ocean_bake(struct Ocean *o,
BKE_ocean_eval_ij(o, &ocr, x, y);
/* add to the image */
rgb_to_rgba_unit_alpha(&ibuf_disp->rect_float[4 * (res_x * y + x)], ocr.disp);
rgb_to_rgba_unit_alpha(&ibuf_disp->float_buffer.data[4 * (res_x * y + x)], ocr.disp);
if (o->_do_jacobian) {
/* TODO(@ideasman42): cleanup unused code. */
@@ -1478,18 +1478,19 @@ void BKE_ocean_bake(struct Ocean *o,
// foam_result = min_ff(foam_result, 1.0f);
value_to_rgba_unit_alpha(&ibuf_foam->rect_float[4 * (res_x * y + x)], foam_result);
value_to_rgba_unit_alpha(&ibuf_foam->float_buffer.data[4 * (res_x * y + x)],
foam_result);
/* spray map baking */
if (o->_do_spray) {
rgb_to_rgba_unit_alpha(&ibuf_spray->rect_float[4 * (res_x * y + x)], ocr.Eplus);
rgb_to_rgba_unit_alpha(&ibuf_spray_inverse->rect_float[4 * (res_x * y + x)],
rgb_to_rgba_unit_alpha(&ibuf_spray->float_buffer.data[4 * (res_x * y + x)], ocr.Eplus);
rgb_to_rgba_unit_alpha(&ibuf_spray_inverse->float_buffer.data[4 * (res_x * y + x)],
ocr.Eminus);
}
}
if (o->_do_normals) {
rgb_to_rgba_unit_alpha(&ibuf_normal->rect_float[4 * (res_x * y + x)], ocr.normal);
rgb_to_rgba_unit_alpha(&ibuf_normal->float_buffer.data[4 * (res_x * y + x)], ocr.normal);
}
}
}
@@ -637,12 +637,11 @@ static void apply_watertight_check(PBVH *pbvh, Image *image, ImageUser *image_us
int pixel_offset = pixel_row.start_image_coordinate.y * image_buffer->x +
pixel_row.start_image_coordinate.x;
for (int x = 0; x < pixel_row.num_pixels; x++) {
if (image_buffer->rect_float) {
copy_v4_fl(&image_buffer->rect_float[pixel_offset * 4], 1.0);
if (image_buffer->float_buffer.data) {
copy_v4_fl(&image_buffer->float_buffer.data[pixel_offset * 4], 1.0);
}
if (image_buffer->rect) {
uint8_t *dest = static_cast<uint8_t *>(
static_cast<void *>(&image_buffer->rect[pixel_offset]));
if (image_buffer->byte_buffer.data) {
uint8_t *dest = &image_buffer->byte_buffer.data[pixel_offset * 4];
copy_v4_uchar(dest, 255);
}
pixel_offset += 1;
@@ -484,7 +484,7 @@ static void studiolight_create_equirect_radiance_gputexture(StudioLight *sl)
1,
GPU_RGBA16F,
GPU_TEXTURE_USAGE_SHADER_READ,
ibuf->rect_float);
ibuf->float_buffer.data);
GPUTexture *tex = sl->equirect_radiance_gputexture;
GPU_texture_filter_mode(tex, true);
GPU_texture_extend_mode(tex, GPU_SAMPLER_EXTEND_MODE_REPEAT);
@@ -498,7 +498,7 @@ static void studiolight_create_matcap_gputexture(StudioLightImage *sli)
ImBuf *ibuf = sli->ibuf;
float *gpu_matcap_3components = MEM_callocN(sizeof(float[3]) * ibuf->x * ibuf->y, __func__);
const float(*offset4)[4] = (const float(*)[4])ibuf->rect_float;
const float(*offset4)[4] = (const float(*)[4])ibuf->float_buffer.data;
float(*offset3)[3] = (float(*)[3])gpu_matcap_3components;
for (int i = 0; i < ibuf->x * ibuf->y; i++, offset4++, offset3++) {
copy_v3_v3(*offset3, *offset4);
@@ -545,7 +545,7 @@ static void studiolight_create_equirect_irradiance_gputexture(StudioLight *sl)
1,
GPU_RGBA16F,
GPU_TEXTURE_USAGE_SHADER_READ,
ibuf->rect_float);
ibuf->float_buffer.data);
GPUTexture *tex = sl->equirect_irradiance_gputexture;
GPU_texture_filter_mode(tex, true);
GPU_texture_extend_mode(tex, GPU_SAMPLER_EXTEND_MODE_REPEAT);
@@ -681,7 +681,7 @@ static void studiolight_spherical_harmonics_calculate_coefficients(StudioLight *
for (int face = 0; face < 6; face++) {
ITER_PIXELS (float,
sl->radiance_cubemap_buffers[face]->rect_float,
sl->radiance_cubemap_buffers[face]->float_buffer.data,
4,
STUDIOLIGHT_RADIANCE_CUBEMAP_SIZE,
STUDIOLIGHT_RADIANCE_CUBEMAP_SIZE)
@@ -976,7 +976,7 @@ BLI_INLINE void studiolight_evaluate_specular_radiance_buffer(ImBuf *radiance_bu
float accum[3] = {0.0f, 0.0f, 0.0f};
float accum_weight = 0.00001f;
ITER_PIXELS (float,
radiance_buffer->rect_float,
radiance_buffer->float_buffer.data,
4,
STUDIOLIGHT_RADIANCE_CUBEMAP_SIZE,
STUDIOLIGHT_RADIANCE_CUBEMAP_SIZE)
+30 -32
View File
@@ -2277,48 +2277,46 @@ ImBuf *BKE_tracking_distortion_exec(MovieDistortion *distortion,
resibuf = IMB_dupImBuf(ibuf);
if (ibuf->rect_float) {
if (ibuf->float_buffer.data) {
if (undistort) {
libmv_cameraIntrinsicsUndistortFloat(distortion->intrinsics,
ibuf->rect_float,
ibuf->float_buffer.data,
ibuf->x,
ibuf->y,
overscan,
ibuf->channels,
resibuf->rect_float);
resibuf->float_buffer.data);
}
else {
libmv_cameraIntrinsicsDistortFloat(distortion->intrinsics,
ibuf->rect_float,
ibuf->float_buffer.data,
ibuf->x,
ibuf->y,
overscan,
ibuf->channels,
resibuf->rect_float);
resibuf->float_buffer.data);
}
if (ibuf->rect) {
imb_freerectImBuf(ibuf);
}
imb_freerectImBuf(ibuf);
}
else {
if (undistort) {
libmv_cameraIntrinsicsUndistortByte(distortion->intrinsics,
(uchar *)ibuf->rect,
ibuf->byte_buffer.data,
ibuf->x,
ibuf->y,
overscan,
ibuf->channels,
(uchar *)resibuf->rect);
resibuf->byte_buffer.data);
}
else {
libmv_cameraIntrinsicsDistortByte(distortion->intrinsics,
(uchar *)ibuf->rect,
ibuf->byte_buffer.data,
ibuf->x,
ibuf->y,
overscan,
ibuf->channels,
(uchar *)resibuf->rect);
resibuf->byte_buffer.data);
}
}
@@ -2573,7 +2571,7 @@ ImBuf *BKE_tracking_sample_pattern(const int frame_width,
}
pattern_ibuf = IMB_allocImBuf(
num_samples_x, num_samples_y, 32, search_ibuf->rect_float ? IB_rectfloat : IB_rect);
num_samples_x, num_samples_y, 32, search_ibuf->float_buffer.data ? IB_rectfloat : IB_rect);
tracking_get_marker_coords_for_tracking(
frame_width, frame_height, marker, src_pixel_x, src_pixel_y);
@@ -2606,8 +2604,8 @@ ImBuf *BKE_tracking_sample_pattern(const int frame_width,
mask = BKE_tracking_track_get_mask(frame_width, frame_height, track, marker);
}
if (search_ibuf->rect_float) {
libmv_samplePlanarPatchFloat(search_ibuf->rect_float,
if (search_ibuf->float_buffer.data) {
libmv_samplePlanarPatchFloat(search_ibuf->float_buffer.data,
search_ibuf->x,
search_ibuf->y,
4,
@@ -2616,12 +2614,12 @@ ImBuf *BKE_tracking_sample_pattern(const int frame_width,
num_samples_x,
num_samples_y,
mask,
pattern_ibuf->rect_float,
pattern_ibuf->float_buffer.data,
&warped_position_x,
&warped_position_y);
}
else {
libmv_samplePlanarPatchByte((uchar *)search_ibuf->rect,
libmv_samplePlanarPatchByte(search_ibuf->byte_buffer.data,
search_ibuf->x,
search_ibuf->y,
4,
@@ -2630,7 +2628,7 @@ ImBuf *BKE_tracking_sample_pattern(const int frame_width,
num_samples_x,
num_samples_y,
mask,
(uchar *)pattern_ibuf->rect,
pattern_ibuf->byte_buffer.data,
&warped_position_x,
&warped_position_y);
}
@@ -2712,7 +2710,7 @@ ImBuf *BKE_tracking_get_search_imbuf(const ImBuf *ibuf,
return nullptr;
}
searchibuf = IMB_allocImBuf(w, h, 32, ibuf->rect_float ? IB_rectfloat : IB_rect);
searchibuf = IMB_allocImBuf(w, h, 32, ibuf->float_buffer.data ? IB_rectfloat : IB_rect);
IMB_rectcpy(searchibuf, ibuf, 0, 0, x, y, w, h);
@@ -2766,7 +2764,7 @@ ImBuf *BKE_tracking_get_plane_imbuf(const ImBuf *frame_ibuf,
/* Create new result image with the same type of content as the original. */
ImBuf *plane_ibuf = IMB_allocImBuf(
num_samples_x, num_samples_y, 32, frame_ibuf->rect_float ? IB_rectfloat : IB_rect);
num_samples_x, num_samples_y, 32, frame_ibuf->float_buffer.data ? IB_rectfloat : IB_rect);
/* Calculate corner coordinates in pixel space, as separate X/Y arrays. */
const double src_pixel_x[4] = {corners[0][0] * frame_width,
@@ -2782,8 +2780,8 @@ ImBuf *BKE_tracking_get_plane_imbuf(const ImBuf *frame_ibuf,
double warped_position_x, warped_position_y;
/* Actual sampling. */
if (frame_ibuf->rect_float != nullptr) {
libmv_samplePlanarPatchFloat(frame_ibuf->rect_float,
if (frame_ibuf->float_buffer.data != nullptr) {
libmv_samplePlanarPatchFloat(frame_ibuf->float_buffer.data,
frame_ibuf->x,
frame_ibuf->y,
4,
@@ -2792,12 +2790,12 @@ ImBuf *BKE_tracking_get_plane_imbuf(const ImBuf *frame_ibuf,
num_samples_x,
num_samples_y,
nullptr,
plane_ibuf->rect_float,
plane_ibuf->float_buffer.data,
&warped_position_x,
&warped_position_y);
}
else {
libmv_samplePlanarPatchByte((uchar *)frame_ibuf->rect,
libmv_samplePlanarPatchByte(frame_ibuf->byte_buffer.data,
frame_ibuf->x,
frame_ibuf->y,
4,
@@ -2806,7 +2804,7 @@ ImBuf *BKE_tracking_get_plane_imbuf(const ImBuf *frame_ibuf,
num_samples_x,
num_samples_y,
nullptr,
(uchar *)plane_ibuf->rect,
plane_ibuf->byte_buffer.data,
&warped_position_x,
&warped_position_y);
}
@@ -2834,8 +2832,8 @@ void BKE_tracking_disable_channels(
for (int x = 0; x < ibuf->x; x++) {
int pixel = ibuf->x * y + x;
if (ibuf->rect_float) {
float *rrgbf = ibuf->rect_float + pixel * 4;
if (ibuf->float_buffer.data) {
float *rrgbf = ibuf->float_buffer.data + pixel * 4;
float r = disable_red ? 0.0f : rrgbf[0];
float g = disable_green ? 0.0f : rrgbf[1];
float b = disable_blue ? 0.0f : rrgbf[2];
@@ -2852,10 +2850,10 @@ void BKE_tracking_disable_channels(
}
}
else {
char *rrgb = (char *)ibuf->rect + pixel * 4;
char r = disable_red ? 0 : rrgb[0];
char g = disable_green ? 0 : rrgb[1];
char b = disable_blue ? 0 : rrgb[2];
uchar *rrgb = ibuf->byte_buffer.data + pixel * 4;
uchar r = disable_red ? 0 : rrgb[0];
uchar g = disable_green ? 0 : rrgb[1];
uchar b = disable_blue ? 0 : rrgb[2];
if (grayscale) {
float gray = (0.2126f * r + 0.7152f * g + 0.0722f * b) / scale;
@@ -2871,7 +2869,7 @@ void BKE_tracking_disable_channels(
}
}
if (ibuf->rect_float) {
if (ibuf->float_buffer.data) {
ibuf->userflags |= IB_RECT_INVALID;
}
}
@@ -117,11 +117,11 @@ static void run_configured_detector(MovieTracking *tracking,
{
struct libmv_Features *features = nullptr;
if (ibuf->rect_float) {
features = libmv_detectFeaturesFloat(ibuf->rect_float, ibuf->x, ibuf->y, 4, options);
if (ibuf->float_buffer.data) {
features = libmv_detectFeaturesFloat(ibuf->float_buffer.data, ibuf->x, ibuf->y, 4, options);
}
else if (ibuf->rect) {
features = libmv_detectFeaturesByte((uchar *)ibuf->rect, ibuf->x, ibuf->y, 4, options);
else if (ibuf->byte_buffer.data) {
features = libmv_detectFeaturesByte(ibuf->byte_buffer.data, ibuf->x, ibuf->y, 4, options);
}
if (features != nullptr) {
@@ -80,13 +80,13 @@ static float *track_get_search_floatbuf(ImBuf *ibuf,
gray_pixels = MEM_cnew_array<float>(width * height, "tracking floatBuf");
if (searchibuf->rect_float) {
if (searchibuf->float_buffer.data) {
float_rgba_to_gray(
searchibuf->rect_float, gray_pixels, width * height, 0.2126f, 0.7152f, 0.0722f);
searchibuf->float_buffer.data, gray_pixels, width * height, 0.2126f, 0.7152f, 0.0722f);
}
else {
uint8_rgba_to_float_gray(
(uchar *)searchibuf->rect, gray_pixels, width * height, 0.2126f, 0.7152f, 0.0722f);
searchibuf->byte_buffer.data, gray_pixels, width * height, 0.2126f, 0.7152f, 0.0722f);
}
IMB_freeImBuf(searchibuf);
@@ -1356,10 +1356,10 @@ ImBuf *BKE_tracking_stabilize_frame(
/* Allocate frame for stabilization result, copy alpha mode and color-space. */
ibuf_flags = 0;
if (ibuf->rect) {
if (ibuf->byte_buffer.data) {
ibuf_flags |= IB_rect;
}
if (ibuf->rect_float) {
if (ibuf->float_buffer.data) {
ibuf_flags |= IB_rectfloat;
}
@@ -1402,7 +1402,7 @@ ImBuf *BKE_tracking_stabilize_frame(
BLI_task_parallel_range(
0, tmpibuf->y, &data, tracking_stabilize_frame_interpolation_cb, &settings);
if (tmpibuf->rect_float) {
if (tmpibuf->float_buffer.data) {
tmpibuf->userflags |= IB_RECT_INVALID;
}
@@ -625,16 +625,14 @@ static ImBuf *make_grayscale_ibuf_copy(ImBuf *ibuf)
*/
const size_t num_pixels = size_t(grayscale->x) * size_t(grayscale->y);
grayscale->channels = 1;
if ((grayscale->rect_float = MEM_cnew_array<float>(num_pixels, "tracking grayscale image")) !=
nullptr)
{
grayscale->mall |= IB_rectfloat;
grayscale->flags |= IB_rectfloat;
float *rect_float = MEM_cnew_array<float>(num_pixels, "tracking grayscale image");
if (rect_float != nullptr) {
IMB_assign_float_buffer(grayscale, rect_float, IB_TAKE_OWNERSHIP);
for (int i = 0; i < grayscale->x * grayscale->y; i++) {
const float *pixel = ibuf->rect_float + ibuf->channels * i;
const float *pixel = rect_float + ibuf->channels * i;
grayscale->rect_float[i] = 0.2126f * pixel[0] + 0.7152f * pixel[1] + 0.0722f * pixel[2];
rect_float[i] = 0.2126f * pixel[0] + 0.7152f * pixel[1] + 0.0722f * pixel[2];
}
}
@@ -643,8 +641,8 @@ static ImBuf *make_grayscale_ibuf_copy(ImBuf *ibuf)
static void ibuf_to_float_image(const ImBuf *ibuf, libmv_FloatImage *float_image)
{
BLI_assert(ibuf->rect_float != nullptr);
float_image->buffer = ibuf->rect_float;
BLI_assert(ibuf->float_buffer.data != nullptr);
float_image->buffer = ibuf->float_buffer.data;
float_image->width = ibuf->x;
float_image->height = ibuf->y;
float_image->channels = ibuf->channels;
@@ -655,13 +653,11 @@ static ImBuf *float_image_to_ibuf(libmv_FloatImage *float_image)
ImBuf *ibuf = IMB_allocImBuf(float_image->width, float_image->height, 32, 0);
size_t num_total_channels = size_t(ibuf->x) * size_t(ibuf->y) * float_image->channels;
ibuf->channels = float_image->channels;
if ((ibuf->rect_float = MEM_cnew_array<float>(num_total_channels, "tracking grayscale image")) !=
nullptr)
{
ibuf->mall |= IB_rectfloat;
ibuf->flags |= IB_rectfloat;
float *rect_float = MEM_cnew_array<float>(num_total_channels, "tracking grayscale image");
if (rect_float != nullptr) {
IMB_assign_float_buffer(ibuf, rect_float, IB_TAKE_OWNERSHIP);
memcpy(ibuf->rect_float, float_image->buffer, num_total_channels * sizeof(float));
memcpy(rect_float, float_image->buffer, num_total_channels * sizeof(float));
}
return ibuf;
}
@@ -700,7 +696,7 @@ static ImBuf *accessor_get_ibuf(TrackingImageAccessor *accessor,
final_ibuf = IMB_allocImBuf(width, height, 32, IB_rectfloat);
if (orig_ibuf->rect_float != nullptr) {
if (orig_ibuf->float_buffer.data != nullptr) {
IMB_rectcpy(final_ibuf,
orig_ibuf,
dst_offset_x,
@@ -721,8 +717,8 @@ static ImBuf *accessor_get_ibuf(TrackingImageAccessor *accessor,
int dst_x = x + dst_offset_x, dst_y = y + dst_offset_y;
int dst_index = (dst_y * width + dst_x) * 4,
src_index = (src_y * orig_ibuf->x + src_x) * 4;
rgba_uchar_to_float(final_ibuf->rect_float + dst_index,
(uchar *)orig_ibuf->rect + src_index);
rgba_uchar_to_float(final_ibuf->float_buffer.data + dst_index,
orig_ibuf->byte_buffer.data + src_index);
}
}
}
@@ -804,7 +800,7 @@ static libmv_CacheKey accessor_get_image_callback(struct libmv_FrameAccessorUser
ibuf = accessor_get_ibuf(accessor, clip_index, frame, input_mode, downscale, region, transform);
if (ibuf) {
*destination = ibuf->rect_float;
*destination = ibuf->float_buffer.data;
*width = ibuf->x;
*height = ibuf->y;
*channels = ibuf->channels;
@@ -452,7 +452,7 @@ void DebugInfo::export_operation(const NodeOperation *op, MemoryBuffer *render)
const int num_channels = render->get_num_channels();
ImBuf *ibuf = IMB_allocImBuf(width, height, 8 * num_channels, IB_rectfloat);
MemoryBuffer mem_ibuf(ibuf->rect_float, 4, width, height);
MemoryBuffer mem_ibuf(ibuf->float_buffer.data, 4, width, height);
mem_ibuf.copy_from(render, render->get_rect(), 0, num_channels, 0);
const std::string file_name = operation_class_name(op) + "_" + std::to_string(op->get_id()) +
@@ -342,12 +342,12 @@ void MemoryBuffer::copy_from(const ImBuf *src,
const int to_channel_offset,
const bool ensure_linear_space)
{
if (src->rect_float) {
const MemoryBuffer mem_buf(src->rect_float, src->channels, src->x, src->y, false);
if (src->float_buffer.data) {
const MemoryBuffer mem_buf(src->float_buffer.data, src->channels, src->x, src->y, false);
copy_from(&mem_buf, area, channel_offset, elem_size, to_x, to_y, to_channel_offset);
}
else if (src->rect) {
const uchar *uc_buf = (uchar *)src->rect;
else if (src->byte_buffer.data) {
const uchar *uc_buf = src->byte_buffer.data;
const int elem_stride = src->channels;
const int row_stride = elem_stride * src->x;
copy_from(uc_buf,
@@ -55,7 +55,8 @@ ImBuf *BaseImageOperation::get_im_buf()
}
ibuf = BKE_image_acquire_ibuf(image_, &iuser, nullptr);
if (ibuf == nullptr || (ibuf->rect == nullptr && ibuf->rect_float == nullptr)) {
if (ibuf == nullptr || (ibuf->byte_buffer.data == nullptr && ibuf->float_buffer.data == nullptr))
{
BKE_image_release_ibuf(image_, ibuf, nullptr);
return nullptr;
}
@@ -67,11 +68,11 @@ void BaseImageOperation::init_execution()
ImBuf *stackbuf = get_im_buf();
buffer_ = stackbuf;
if (stackbuf) {
image_float_buffer_ = stackbuf->rect_float;
image_byte_buffer_ = stackbuf->rect;
image_depth_buffer_ = stackbuf->zbuf_float;
if (stackbuf->zbuf_float) {
depth_buffer_ = new MemoryBuffer(stackbuf->zbuf_float, 1, stackbuf->x, stackbuf->y);
image_float_buffer_ = stackbuf->float_buffer.data;
image_byte_buffer_ = stackbuf->byte_buffer.data;
image_depth_buffer_ = stackbuf->float_z_buffer.data;
if (stackbuf->float_z_buffer.data) {
depth_buffer_ = new MemoryBuffer(stackbuf->float_z_buffer.data, 1, stackbuf->x, stackbuf->y);
}
imagewidth_ = stackbuf->x;
imageheight_ = stackbuf->y;
@@ -106,7 +107,7 @@ void BaseImageOperation::determine_canvas(const rcti & /*preferred_area*/, rcti
static void sample_image_at_location(
ImBuf *ibuf, float x, float y, PixelSampler sampler, bool make_linear_rgb, float color[4])
{
if (ibuf->rect_float) {
if (ibuf->float_buffer.data) {
switch (sampler) {
case PixelSampler::Nearest:
nearest_interpolation_color(ibuf, nullptr, color, x, y);
@@ -5,6 +5,7 @@
#include "BKE_image.h"
#include "BLI_listbase.h"
#include "BLI_sys_types.h"
#include "BLI_utildefines.h"
#include "COM_MultiThreadedOperation.h"
#include "MEM_guardedalloc.h"
@@ -24,7 +25,7 @@ class BaseImageOperation : public MultiThreadedOperation {
ImageUser *image_user_;
/* TODO: Remove raw buffers when removing Tiled implementation. */
float *image_float_buffer_;
unsigned int *image_byte_buffer_;
uint8_t *image_byte_buffer_;
float *image_depth_buffer_;
MemoryBuffer *depth_buffer_;
@@ -140,11 +140,11 @@ KeyingScreenOperation::TriangulationData *KeyingScreenOperation::build_voronoi_t
if (pattern_ibuf) {
for (int j = 0; j < pattern_ibuf->x * pattern_ibuf->y; j++) {
if (pattern_ibuf->rect_float) {
add_v3_v3(site->color, &pattern_ibuf->rect_float[4 * j]);
if (pattern_ibuf->float_buffer.data) {
add_v3_v3(site->color, &pattern_ibuf->float_buffer.data[4 * j]);
}
else {
uchar *rrgb = (uchar *)pattern_ibuf->rect;
uchar *rrgb = pattern_ibuf->byte_buffer.data;
site->color[0] += srgb_to_linearrgb(float(rrgb[4 * j + 0]) / 255.0f);
site->color[1] += srgb_to_linearrgb(float(rrgb[4 * j + 1]) / 255.0f);
@@ -36,7 +36,7 @@ void MovieClipBaseOperation::init_execution()
if (ibuf) {
movie_clip_buffer_ = ibuf;
if (ibuf->rect_float == nullptr || ibuf->userflags & IB_RECT_INVALID) {
if (ibuf->float_buffer.data == nullptr || ibuf->userflags & IB_RECT_INVALID) {
IMB_float_from_rect(ibuf);
ibuf->userflags &= ~IB_RECT_INVALID;
}
@@ -73,7 +73,7 @@ void MovieClipBaseOperation::execute_pixel_sampled(float output[4],
if (ibuf == nullptr) {
zero_v4(output);
}
else if (ibuf->rect == nullptr && ibuf->rect_float == nullptr) {
else if (ibuf->byte_buffer.data == nullptr && ibuf->float_buffer.data == nullptr) {
/* Happens for multi-layer EXR, i.e. */
zero_v4(output);
}
@@ -321,10 +321,10 @@ void OutputStereoOperation::deinit_execution()
ibuf[i] = IMB_allocImBuf(width, height, format_.planes, 0);
ibuf[i]->channels = channels_;
ibuf[i]->rect_float = rectf;
ibuf[i]->mall |= IB_rectfloat;
ibuf[i]->dither = rd_->dither_intensity;
IMB_assign_float_buffer(ibuf[i], rectf, IB_TAKE_OWNERSHIP);
/* do colormanagement in the individual views, so it doesn't need to do in the stereo */
IMB_colormanagement_imbuf_for_write(ibuf[i], true, false, &format_);
}
@@ -257,10 +257,10 @@ void OutputSingleLayerOperation::deinit_execution()
const char *suffix;
ibuf->channels = size;
ibuf->rect_float = output_buffer_;
ibuf->mall |= IB_rectfloat;
ibuf->dither = rd_->dither_intensity;
IMB_assign_float_buffer(ibuf, output_buffer_, IB_TAKE_OWNERSHIP);
IMB_colormanagement_imbuf_for_write(ibuf, save_as_render_, false, &format_);
suffix = BKE_scene_multiview_view_suffix_get(rd_, view_name_);
@@ -155,13 +155,13 @@ void ViewerOperation::init_image()
}
/* now we combine the input with ibuf */
output_buffer_ = ibuf->rect_float;
output_buffer_ = ibuf->float_buffer.data;
/* needed for display buffer update */
ibuf_ = ibuf;
if (do_depth_buffer_) {
depth_buffer_ = ibuf->zbuf_float;
depth_buffer_ = ibuf->float_z_buffer.data;
}
BKE_image_release_ibuf(image_, ibuf_, lock);
@@ -46,7 +46,7 @@ static struct GPUTexture *gpencil_image_texture_get(Image *image, bool *r_alpha_
ibuf = BKE_image_acquire_ibuf(image, &iuser, &lock);
if (ibuf != NULL && ibuf->rect != NULL) {
if (ibuf != NULL && ibuf->byte_buffer.data != NULL) {
gpu_tex = BKE_image_get_gpu_texture(image, &iuser, ibuf);
*r_alpha_premult = (image->alpha_mode == IMA_ALPHA_PREMUL);
}
@@ -70,11 +70,11 @@ struct FloatBufferCache {
ImBuf *cached_float_buffer(ImBuf *image_buffer)
{
/* Check if we can use the float buffer of the given image_buffer. */
if (image_buffer->rect_float != nullptr) {
if (image_buffer->float_buffer.data != nullptr) {
BLI_assert_msg(
IMB_colormanagement_space_name_is_scene_linear(
IMB_colormanagement_get_float_colorspace(image_buffer)),
"Expected rect_float to be scene_linear - if there are code paths where this "
"Expected float buffer to be scene_linear - if there are code paths where this "
"isn't the case we should convert those and add to the FloatBufferCache as well.");
return image_buffer;
}
@@ -90,12 +90,8 @@ struct FloatBufferCache {
/* Generate a new float buffer. */
IMB_float_from_rect(image_buffer);
ImBuf *new_imbuf = IMB_allocImBuf(image_buffer->x, image_buffer->y, image_buffer->planes, 0);
new_imbuf->rect_float = image_buffer->rect_float;
new_imbuf->flags |= IB_rectfloat;
new_imbuf->mall |= IB_rectfloat;
image_buffer->rect_float = nullptr;
image_buffer->flags &= ~IB_rectfloat;
image_buffer->mall &= ~IB_rectfloat;
IMB_assign_float_buffer(new_imbuf, IMB_steal_float_buffer(image_buffer), IB_TAKE_OWNERSHIP);
cache_.append(FloatImageBuffer(image_buffer, new_imbuf));
return new_imbuf;
@@ -389,10 +389,10 @@ template<typename TextureMethod> class ScreenSpaceDrawingMode : public AbstractD
ImBuf *float_buffer, PartialUpdateChecker<ImageTileData>::CollectResult &iterator) const
{
ImBuf *src = iterator.tile_data.tile_buffer;
BLI_assert(float_buffer->rect_float != nullptr);
BLI_assert(float_buffer->rect == nullptr);
BLI_assert(src->rect_float == nullptr);
BLI_assert(src->rect != nullptr);
BLI_assert(float_buffer->float_buffer.data != nullptr);
BLI_assert(float_buffer->byte_buffer.data == nullptr);
BLI_assert(src->float_buffer.data == nullptr);
BLI_assert(src->byte_buffer.data != nullptr);
/* Calculate the overlap between the updated region and the buffer size. Partial Update Checker
* always returns a tile (256x256). Which could lay partially outside the buffer when using
@@ -503,7 +503,7 @@ template<typename TextureMethod> class ScreenSpaceDrawingMode : public AbstractD
info.clipping_uv_bounds.xmin * (1.0 - xf) - tile_offset_x;
nearest_interpolation_color(tile_buffer,
nullptr,
&extracted_buffer.rect_float[offset * 4],
&extracted_buffer.float_buffer.data[offset * 4],
u * tile_buffer->x,
v * tile_buffer->y);
offset++;
@@ -513,7 +513,7 @@ template<typename TextureMethod> class ScreenSpaceDrawingMode : public AbstractD
GPU_texture_update_sub(texture,
GPU_DATA_FLOAT,
extracted_buffer.rect_float,
extracted_buffer.float_buffer.data,
gpu_texture_region_to_update.xmin,
gpu_texture_region_to_update.ymin,
0,
@@ -563,7 +563,7 @@ template<typename TextureMethod> class ScreenSpaceDrawingMode : public AbstractD
BKE_image_release_ibuf(image, tile_buffer, lock);
}
IMB_gpu_clamp_half_float(&texture_buffer);
GPU_texture_update(info.texture, GPU_DATA_FLOAT, texture_buffer.rect_float);
GPU_texture_update(info.texture, GPU_DATA_FLOAT, texture_buffer.float_buffer.data);
imb_freerectImbuf_all(&texture_buffer);
}
@@ -15,15 +15,15 @@ static bool get_matcap_tx(Texture &matcap_tx, StudioLight &studio_light)
STUDIOLIGHT_MATCAP_SPECULAR_GPUTEXTURE);
ImBuf *matcap_diffuse = studio_light.matcap_diffuse.ibuf;
ImBuf *matcap_specular = studio_light.matcap_specular.ibuf;
if (matcap_diffuse && matcap_diffuse->rect_float) {
if (matcap_diffuse && matcap_diffuse->float_buffer.data) {
int layers = 1;
float *buffer = matcap_diffuse->rect_float;
float *buffer = matcap_diffuse->float_buffer.data;
Vector<float> combined_buffer = {};
if (matcap_specular && matcap_specular->rect_float) {
if (matcap_specular && matcap_specular->float_buffer.data) {
int size = matcap_diffuse->x * matcap_diffuse->y * 4;
combined_buffer.extend(matcap_diffuse->rect_float, size);
combined_buffer.extend(matcap_specular->rect_float, size);
combined_buffer.extend(matcap_diffuse->float_buffer.data, size);
combined_buffer.extend(matcap_specular->float_buffer.data, size);
buffer = combined_buffer.begin();
layers++;
}
@@ -1322,13 +1322,13 @@ static bool gpencil_render_offscreen(tGPDfill *tgpf)
GPU_matrix_pop();
/* create a image to see result of template */
if (ibuf->rect_float) {
GPU_offscreen_read_color(offscreen, GPU_DATA_FLOAT, ibuf->rect_float);
if (ibuf->float_buffer.data) {
GPU_offscreen_read_color(offscreen, GPU_DATA_FLOAT, ibuf->float_buffer.data);
}
else if (ibuf->rect) {
GPU_offscreen_read_color(offscreen, GPU_DATA_UBYTE, ibuf->rect);
else if (ibuf->byte_buffer.data) {
GPU_offscreen_read_color(offscreen, GPU_DATA_UBYTE, ibuf->byte_buffer.data);
}
if (ibuf->rect_float && ibuf->rect) {
if (ibuf->float_buffer.data && ibuf->byte_buffer.data) {
IMB_rect_from_float(ibuf);
}
@@ -1347,22 +1347,22 @@ static bool gpencil_render_offscreen(tGPDfill *tgpf)
/* Return pixel data (RGBA) at index. */
static void get_pixel(const ImBuf *ibuf, const int idx, float r_col[4])
{
BLI_assert(ibuf->rect_float != NULL);
memcpy(r_col, &ibuf->rect_float[idx * 4], sizeof(float[4]));
BLI_assert(ibuf->float_buffer.data != NULL);
memcpy(r_col, &ibuf->float_buffer.data[idx * 4], sizeof(float[4]));
}
/* Set pixel data (RGBA) at index. */
static void set_pixel(ImBuf *ibuf, int idx, const float col[4])
{
BLI_assert(ibuf->rect_float != NULL);
float *rrectf = &ibuf->rect_float[idx * 4];
BLI_assert(ibuf->float_buffer.data != NULL);
float *rrectf = &ibuf->float_buffer.data[idx * 4];
copy_v4_v4(rrectf, col);
}
/* Helper: Check if one image row is empty. */
static bool is_row_filled(const ImBuf *ibuf, const int row_index)
{
float *row = &ibuf->rect_float[ibuf->x * 4 * row_index];
float *row = &ibuf->float_buffer.data[ibuf->x * 4 * row_index];
return (row[0] == 0.0f && memcmp(row, row + 1, ((ibuf->x * 4) - 1) * sizeof(float)) != 0);
}
@@ -114,12 +114,12 @@ static void pixel_at_index(const ImBuf *ibuf, const int32_t idx, float r_col[4])
{
BLI_assert(idx < (ibuf->x * ibuf->y));
if (ibuf->rect_float) {
const float *frgba = &ibuf->rect_float[idx * 4];
if (ibuf->float_buffer.data) {
const float *frgba = &ibuf->float_buffer.data[idx * 4];
copy_v4_v4(r_col, frgba);
}
else {
uchar *cp = (uchar *)(ibuf->rect + idx);
uchar *cp = ibuf->byte_buffer.data + 4 * idx;
r_col[0] = (float)cp[0] / 255.0f;
r_col[1] = (float)cp[1] / 255.0f;
r_col[2] = (float)cp[2] / 255.0f;
@@ -301,7 +301,7 @@ void ui_draw_but_IMAGE(ARegion * /*region*/,
ibuf->y,
GPU_RGBA8,
false,
ibuf->rect,
ibuf->byte_buffer.data,
1.0f,
1.0f,
col);
@@ -2053,11 +2053,11 @@ void ui_draw_but_TRACKPREVIEW(ARegion * /*region*/,
height,
scopes->track_pos);
if (tmpibuf) {
if (tmpibuf->rect_float) {
if (tmpibuf->float_buffer.data) {
IMB_rect_from_float(tmpibuf);
}
if (tmpibuf->rect) {
if (tmpibuf->byte_buffer.data) {
scopes->track_preview = tmpibuf;
}
else {
@@ -2095,7 +2095,7 @@ void ui_draw_but_TRACKPREVIEW(ARegion * /*region*/,
drawibuf->y,
GPU_RGBA8,
true,
drawibuf->rect,
drawibuf->byte_buffer.data,
1.0f,
1.0f,
nullptr);
@@ -77,7 +77,7 @@
struct IconImage {
int w;
int h;
uint *rect;
uint8_t *rect;
const uchar *datatoc_rect;
int datatoc_size;
};
@@ -192,18 +192,19 @@ static DrawInfo *def_internal_icon(
if (bbuf) {
int y, imgsize;
iimg->rect = static_cast<uint *>(MEM_mallocN(size * size * sizeof(uint), __func__));
iimg->rect = static_cast<uint8_t *>(MEM_mallocN(size * size * sizeof(uint), __func__));
/* Here we store the rect in the icon - same as before */
if (size == bbuf->x && size == bbuf->y && xofs == 0 && yofs == 0) {
memcpy(iimg->rect, bbuf->rect, size * size * sizeof(int));
memcpy(iimg->rect, bbuf->byte_buffer.data, size * size * 4 * sizeof(uint8_t));
}
else {
/* this code assumes square images */
imgsize = bbuf->x;
for (y = 0; y < size; y++) {
memcpy(
&iimg->rect[y * size], &bbuf->rect[(y + yofs) * imgsize + xofs], size * sizeof(int));
memcpy(&iimg->rect[y * size],
&bbuf->byte_buffer.data[(y + yofs) * imgsize + xofs],
size * 4 * sizeof(uint8_t));
}
}
}
@@ -759,8 +760,7 @@ static void icon_verify_datatoc(IconImage *iimg)
IMB_scaleImBuf(bbuf, iimg->w, iimg->h);
}
iimg->rect = bbuf->rect;
bbuf->rect = nullptr;
iimg->rect = IMB_steal_byte_buffer(bbuf);
IMB_freeImBuf(bbuf);
}
}
@@ -777,6 +777,9 @@ static ImBuf *create_mono_icon_with_border(ImBuf *buf,
const int icon_width = (ICON_GRID_W + 2 * ICON_MONO_BORDER_OUTSET) / resolution_divider;
const int icon_height = (ICON_GRID_W + 2 * ICON_MONO_BORDER_OUTSET) / resolution_divider;
const uint *buf_rect = reinterpret_cast<const uint *>(buf->byte_buffer.data);
uint *result_rect = reinterpret_cast<uint *>(result->byte_buffer.data);
for (int y = 0; y < ICON_GRID_ROWS; y++) {
for (int x = 0; x < ICON_GRID_COLS; x++) {
const IconType icontype = icontypes[y * ICON_GRID_COLS + x];
@@ -805,7 +808,7 @@ static ImBuf *create_mono_icon_with_border(ImBuf *buf,
for (int ax = asx; ax < aex; ax++) {
for (int ay = asy; ay < aey; ay++) {
const int offset_read = (sy + ay) * buf->x + (sx + ax);
const uint color_read = buf->rect[offset_read];
const uint color_read = buf_rect[offset_read];
const float alpha_read = ((color_read & 0xff000000) >> 24) / 255.0;
alpha_accum += alpha_read;
alpha_samples += 1;
@@ -824,7 +827,7 @@ static ImBuf *create_mono_icon_with_border(ImBuf *buf,
const float border_srgb[4] = {
0, 0, 0, MIN2(1.0f, blurred_alpha * border_sharpness) * border_intensity};
const uint color_read = buf->rect[offset_write];
const uint color_read = buf_rect[offset_write];
const uchar *orig_color = (uchar *)&color_read;
float border_rgba[4];
@@ -839,7 +842,8 @@ static ImBuf *create_mono_icon_with_border(ImBuf *buf,
const uint alpha_mask = uint(dest_srgb[3] * 255) << 24;
const uint cpack = rgb_to_cpack(dest_srgb[0], dest_srgb[1], dest_srgb[2]) | alpha_mask;
result->rect[offset_write] = cpack;
result_rect[offset_write] = cpack;
}
}
}
@@ -914,8 +918,8 @@ void UI_icons_reload_internal_textures()
icongltex.tex[0] = GPU_texture_create_2d(
"icons", b32buf->x, b32buf->y, 2, GPU_RGBA8, GPU_TEXTURE_USAGE_SHADER_READ, nullptr);
GPU_texture_update_mipmap(icongltex.tex[0], 0, GPU_DATA_UBYTE, b32buf->rect);
GPU_texture_update_mipmap(icongltex.tex[0], 1, GPU_DATA_UBYTE, b16buf->rect);
GPU_texture_update_mipmap(icongltex.tex[0], 0, GPU_DATA_UBYTE, b32buf->byte_buffer.data);
GPU_texture_update_mipmap(icongltex.tex[0], 1, GPU_DATA_UBYTE, b16buf->byte_buffer.data);
}
if (need_icons_with_border && icongltex.tex[1] == nullptr) {
@@ -926,8 +930,10 @@ void UI_icons_reload_internal_textures()
GPU_RGBA8,
GPU_TEXTURE_USAGE_SHADER_READ,
nullptr);
GPU_texture_update_mipmap(icongltex.tex[1], 0, GPU_DATA_UBYTE, b32buf_border->rect);
GPU_texture_update_mipmap(icongltex.tex[1], 1, GPU_DATA_UBYTE, b16buf_border->rect);
GPU_texture_update_mipmap(
icongltex.tex[1], 0, GPU_DATA_UBYTE, b32buf_border->byte_buffer.data);
GPU_texture_update_mipmap(
icongltex.tex[1], 1, GPU_DATA_UBYTE, b16buf_border->byte_buffer.data);
}
}
@@ -1316,7 +1322,8 @@ static void ui_studiolight_icon_job_exec(void *customdata,
Icon *icon = *tmp;
DrawInfo *di = icon_ensure_drawinfo(icon);
StudioLight *sl = static_cast<StudioLight *>(icon->obj);
BKE_studiolight_preview(di->data.buffer.image->rect, sl, icon->id_type);
BKE_studiolight_preview(
reinterpret_cast<uint *>(di->data.buffer.image->rect), sl, icon->id_type);
}
static void ui_studiolight_kill_icon_preview_job(wmWindowManager *wm, int icon_id)
@@ -1401,7 +1408,7 @@ void ui_icon_ensure_deferred(const bContext *C, const int icon_id, const bool bi
img->w = STUDIOLIGHT_ICON_SIZE;
img->h = STUDIOLIGHT_ICON_SIZE;
const size_t size = STUDIOLIGHT_ICON_SIZE * STUDIOLIGHT_ICON_SIZE * sizeof(uint);
img->rect = static_cast<uint *>(MEM_mallocN(size, __func__));
img->rect = static_cast<uint8_t *>(MEM_mallocN(size, __func__));
memset(img->rect, 0, size);
di->data.buffer.image = img;
@@ -1499,12 +1506,11 @@ PreviewImage *UI_icon_to_preview(int icon_id)
if (bbuf) {
PreviewImage *prv = BKE_previewimg_create();
prv->rect[0] = bbuf->rect;
prv->rect[0] = reinterpret_cast<uint *>(IMB_steal_byte_buffer(bbuf));
prv->w[0] = bbuf->x;
prv->h[0] = bbuf->y;
bbuf->rect = nullptr;
IMB_freeImBuf(bbuf);
return prv;
@@ -1521,7 +1527,7 @@ static void icon_draw_rect(float x,
float /*aspect*/,
int rw,
int rh,
uint *rect,
uint8_t *rect,
float alpha,
const float desaturate)
{
@@ -1878,7 +1884,8 @@ static void icon_draw_size(float x,
ImBuf *ibuf = static_cast<ImBuf *>(icon->obj);
GPU_blend(GPU_BLEND_ALPHA_PREMULT);
icon_draw_rect(x, y, w, h, aspect, ibuf->x, ibuf->y, ibuf->rect, alpha, desaturate);
icon_draw_rect(
x, y, w, h, aspect, ibuf->x, ibuf->y, ibuf->byte_buffer.data, alpha, desaturate);
GPU_blend(GPU_BLEND_ALPHA);
}
else if (di->type == ICON_TYPE_VECTOR) {
@@ -1918,7 +1925,7 @@ static void icon_draw_size(float x,
}
GPU_blend(GPU_BLEND_ALPHA_PREMULT);
icon_draw_rect(x, y, w, h, aspect, w, h, ibuf->rect, alpha, desaturate);
icon_draw_rect(x, y, w, h, aspect, w, h, ibuf->byte_buffer.data, alpha, desaturate);
GPU_blend(GPU_BLEND_ALPHA);
}
else if (di->type == ICON_TYPE_EVENT) {
@@ -2003,8 +2010,16 @@ static void icon_draw_size(float x,
/* Preview images use premultiplied alpha. */
GPU_blend(GPU_BLEND_ALPHA_PREMULT);
icon_draw_rect(
x, y, w, h, aspect, pi->w[size], pi->h[size], pi->rect[size], alpha, desaturate);
icon_draw_rect(x,
y,
w,
h,
aspect,
pi->w[size],
pi->h[size],
reinterpret_cast<uint8_t *>(pi->rect[size]),
alpha,
desaturate);
GPU_blend(GPU_BLEND_ALPHA);
}
}
+2 -2
View File
@@ -188,11 +188,11 @@ static bool multiresbake_check(bContext *C, wmOperator *op)
ok = false;
}
else {
if (ibuf->rect == nullptr && ibuf->rect_float == nullptr) {
if (ibuf->byte_buffer.data == nullptr && ibuf->float_buffer.data == nullptr) {
ok = false;
}
if (ibuf->rect_float && !ELEM(ibuf->channels, 0, 4)) {
if (ibuf->float_buffer.data && !ELEM(ibuf->channels, 0, 4)) {
ok = false;
}
@@ -233,7 +233,7 @@ static bool write_internal_bake_pixels(Image *image,
RE_bake_mask_fill(pixel_array, pixels_num, mask_buffer);
}
is_float = (ibuf->rect_float != nullptr);
is_float = (ibuf->float_buffer.data != nullptr);
/* colormanagement conversions */
if (!is_noncolor) {
@@ -262,7 +262,7 @@ static bool write_internal_bake_pixels(Image *image,
/* populates the ImBuf */
if (is_clear) {
if (is_float) {
IMB_buffer_float_from_float(ibuf->rect_float,
IMB_buffer_float_from_float(ibuf->float_buffer.data,
buffer,
ibuf->channels,
IB_PROFILE_LINEAR_RGB,
@@ -274,7 +274,7 @@ static bool write_internal_bake_pixels(Image *image,
ibuf->x);
}
else {
IMB_buffer_byte_from_float((uchar *)ibuf->rect,
IMB_buffer_byte_from_float(ibuf->byte_buffer.data,
buffer,
ibuf->channels,
ibuf->dither,
@@ -289,7 +289,7 @@ static bool write_internal_bake_pixels(Image *image,
}
else {
if (is_float) {
IMB_buffer_float_from_float_mask(ibuf->rect_float,
IMB_buffer_float_from_float_mask(ibuf->float_buffer.data,
buffer,
ibuf->channels,
ibuf->x,
@@ -299,7 +299,7 @@ static bool write_internal_bake_pixels(Image *image,
mask_buffer);
}
else {
IMB_buffer_byte_from_float_mask((uchar *)ibuf->rect,
IMB_buffer_byte_from_float_mask(ibuf->byte_buffer.data,
buffer,
ibuf->channels,
ibuf->dither,
@@ -320,7 +320,7 @@ static bool write_internal_bake_pixels(Image *image,
ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID;
BKE_image_mark_dirty(image, ibuf);
if (ibuf->rect_float) {
if (ibuf->float_buffer.data) {
ibuf->userflags |= IB_RECT_INVALID;
}
@@ -382,7 +382,7 @@ static bool write_external_bake_pixels(const char *filepath,
/* populates the ImBuf */
if (is_float) {
IMB_buffer_float_from_float(ibuf->rect_float,
IMB_buffer_float_from_float(ibuf->float_buffer.data,
buffer,
ibuf->channels,
IB_PROFILE_LINEAR_RGB,
@@ -406,7 +406,7 @@ static bool write_external_bake_pixels(const char *filepath,
bias_tangent_normal_pixels(buffer, ibuf->channels, ibuf->x, ibuf->y, ibuf->x);
}
IMB_buffer_byte_from_float((uchar *)ibuf->rect,
IMB_buffer_byte_from_float(ibuf->byte_buffer.data,
buffer,
ibuf->channels,
ibuf->dither,
@@ -234,7 +234,7 @@ static void image_buffer_rect_update(RenderJob *rj,
linear_offset_y = offset_y;
}
else {
rectf = ibuf->rect_float;
rectf = ibuf->float_buffer.data;
linear_stride = ibuf->x;
linear_offset_x = 0;
linear_offset_y = 0;
@@ -301,7 +301,7 @@ static void screen_opengl_render_doit(const bContext *C, OGLRender *oglrender, R
* TODO(sergey): In the case of output to float container (EXR)
* it actually makes sense to keep float buffer instead.
*/
if (ibuf_result->rect_float != nullptr) {
if (ibuf_result->float_buffer.data != nullptr) {
IMB_rect_from_float(ibuf_result);
imb_freerectfloatImBuf(ibuf_result);
}
@@ -315,7 +315,7 @@ static void screen_opengl_render_doit(const bContext *C, OGLRender *oglrender, R
if (gpd) {
int i;
uchar *gp_rect;
uchar *render_rect = (uchar *)ibuf_result->rect;
uchar *render_rect = ibuf_result->byte_buffer.data;
DRW_opengl_context_enable();
GPU_offscreen_bind(oglrender->ofs, true);
@@ -404,11 +404,11 @@ static void screen_opengl_render_doit(const bContext *C, OGLRender *oglrender, R
if ((scene->r.stamp & R_STAMP_ALL) && (scene->r.stamp & R_STAMP_DRAW)) {
float *rectf = nullptr;
uchar *rect = nullptr;
if (ibuf_result->rect_float) {
rectf = ibuf_result->rect_float;
if (ibuf_result->float_buffer.data) {
rectf = ibuf_result->float_buffer.data;
}
else {
rect = (uchar *)ibuf_result->rect;
rect = ibuf_result->byte_buffer.data;
}
BKE_image_stamp_buf(scene, camera, nullptr, rect, rectf, rr->rectx, rr->recty, 4);
}
@@ -1352,7 +1352,8 @@ static void icon_copy_rect(ImBuf *ibuf, uint w, uint h, uint *rect)
short ex, ey, dx, dy;
/* paranoia test */
if (ibuf == nullptr || (ibuf->rect == nullptr && ibuf->rect_float == nullptr)) {
if (ibuf == nullptr || (ibuf->byte_buffer.data == nullptr && ibuf->float_buffer.data == nullptr))
{
return;
}
@@ -1382,11 +1383,11 @@ static void icon_copy_rect(ImBuf *ibuf, uint w, uint h, uint *rect)
IMB_scalefastImBuf(ima, ex, ey);
/* if needed, convert to 32 bits */
if (ima->rect == nullptr) {
if (ima->byte_buffer.data == nullptr) {
IMB_rect_from_float(ima);
}
srect = ima->rect;
srect = reinterpret_cast<uint *>(ima->byte_buffer.data);
drect = rect;
drect += dy * w + dx;
@@ -1440,7 +1441,8 @@ static void icon_preview_startjob(void *customdata, bool *stop, bool *do_update)
* already there. Very expensive for large images. Need to find a way to
* only get existing `ibuf`. */
ibuf = BKE_image_acquire_ibuf(ima, &iuser, nullptr);
if (ibuf == nullptr || (ibuf->rect == nullptr && ibuf->rect_float == nullptr)) {
if (ibuf == nullptr ||
(ibuf->byte_buffer.data == nullptr && ibuf->float_buffer.data == nullptr)) {
BKE_image_release_ibuf(ima, ibuf, nullptr);
return;
}
@@ -1458,7 +1460,7 @@ static void icon_preview_startjob(void *customdata, bool *stop, bool *do_update)
memset(sp->pr_rect, 0x88, sp->sizex * sp->sizey * sizeof(uint));
if (!(br->icon_imbuf) || !(br->icon_imbuf->rect)) {
if (!(br->icon_imbuf) || !(br->icon_imbuf->byte_buffer.data)) {
return;
}
+7 -7
View File
@@ -430,7 +430,7 @@ void ED_draw_imbuf_clipping(ImBuf *ibuf,
bool need_fallback = true;
/* Early out */
if (ibuf->rect == NULL && ibuf->rect_float == NULL) {
if (ibuf->byte_buffer.data == NULL && ibuf->float_buffer.data == NULL) {
return;
}
@@ -449,7 +449,7 @@ void ED_draw_imbuf_clipping(ImBuf *ibuf,
state.do_shader_unbind = false;
immDrawPixelsTexSetupAttributes(&state);
if (ibuf->rect_float) {
if (ibuf->float_buffer.data) {
if (ibuf->float_colorspace) {
ok = IMB_colormanagement_setup_glsl_draw_from_space(
view_settings, display_settings, ibuf->float_colorspace, ibuf->dither, true, false);
@@ -465,7 +465,7 @@ void ED_draw_imbuf_clipping(ImBuf *ibuf,
}
if (ok) {
if (ibuf->rect_float) {
if (ibuf->float_buffer.data) {
eGPUTextureFormat format = 0;
if (ibuf->channels == 3) {
@@ -486,7 +486,7 @@ void ED_draw_imbuf_clipping(ImBuf *ibuf,
ibuf->y,
format,
use_filter,
ibuf->rect_float,
ibuf->float_buffer.data,
clip_min_x,
clip_min_y,
clip_max_x,
@@ -496,7 +496,7 @@ void ED_draw_imbuf_clipping(ImBuf *ibuf,
NULL);
}
}
else if (ibuf->rect) {
else if (ibuf->byte_buffer.data) {
/* ibuf->rect is always RGBA */
immDrawPixelsTexTiled_clipping(&state,
x,
@@ -505,7 +505,7 @@ void ED_draw_imbuf_clipping(ImBuf *ibuf,
ibuf->y,
GPU_RGBA8,
use_filter,
ibuf->rect,
ibuf->byte_buffer.data,
clip_min_x,
clip_min_y,
clip_max_x,
@@ -618,7 +618,7 @@ int ED_draw_imbuf_method(ImBuf *ibuf)
/* Use faster GLSL when CPU to GPU transfer is unlikely to be a bottleneck,
* otherwise do color management on CPU side. */
const size_t threshold = sizeof(float[4]) * 2048 * 2048;
const size_t data_size = (ibuf->rect_float) ? sizeof(float) : sizeof(uchar);
const size_t data_size = (ibuf->float_buffer.data) ? sizeof(float) : sizeof(uchar);
const size_t size = ibuf->x * ibuf->y * ibuf->channels * data_size;
return (size > threshold) ? IMAGE_DRAW_METHOD_2DTEXTURE : IMAGE_DRAW_METHOD_GLSL;
+4 -4
View File
@@ -43,7 +43,7 @@
#include "screen_intern.h"
typedef struct ScreenshotData {
uint *dumprect;
uint8_t *dumprect;
int dumpsx, dumpsy;
rcti crop;
bool use_crop;
@@ -61,7 +61,7 @@ static int screenshot_data_create(bContext *C, wmOperator *op, ScrArea *area)
/* do redraw so we don't show popups/menus */
WM_redraw_windows(C);
uint *dumprect = WM_window_pixels_read(C, win, dumprect_size);
uint8_t *dumprect = WM_window_pixels_read(C, win, dumprect_size);
if (dumprect) {
ScreenshotData *scd = MEM_callocN(sizeof(ScreenshotData), "screenshot");
@@ -118,12 +118,12 @@ static int screenshot_exec(bContext *C, wmOperator *op)
/* operator ensures the extension */
ibuf = IMB_allocImBuf(scd->dumpsx, scd->dumpsy, 24, 0);
ibuf->rect = scd->dumprect;
IMB_assign_byte_buffer(ibuf, scd->dumprect, IB_DO_NOT_TAKE_OWNERSHIP);
/* crop to show only single editor */
if (use_crop) {
IMB_rect_crop(ibuf, &scd->crop);
scd->dumprect = ibuf->rect;
scd->dumprect = ibuf->byte_buffer.data;
}
if ((scd->im_format.planes == R_IMF_PLANES_BW) &&
@@ -164,7 +164,7 @@ static void load_tex_task_cb_ex(void *__restrict userdata,
if (mtex->tex && mtex->tex->type == TEX_IMAGE && mtex->tex->ima) {
ImBuf *tex_ibuf = BKE_image_pool_acquire_ibuf(mtex->tex->ima, &mtex->tex->iuser, pool);
/* For consistency, sampling always returns color in linear space. */
if (tex_ibuf && tex_ibuf->rect_float == nullptr) {
if (tex_ibuf && tex_ibuf->float_buffer.data == nullptr) {
convert_to_linear = true;
colorspace = tex_ibuf->rect_colorspace;
}
@@ -419,13 +419,13 @@ static ImBuf *brush_painter_imbuf_new(
if (use_float) {
/* write to float pixel */
float *dstf = ibuf->rect_float + (y * size + x) * 4;
float *dstf = ibuf->float_buffer.data + (y * size + x) * 4;
mul_v3_v3fl(dstf, rgba, rgba[3]); /* premultiply */
dstf[3] = rgba[3];
}
else {
/* write to byte pixel */
uchar *dst = (uchar *)ibuf->rect + (y * size + x) * 4;
uchar *dst = ibuf->byte_buffer.data + (y * size + x) * 4;
rgb_float_to_uchar(dst, rgba);
dst[3] = unit_float_to_uchar_clamp(rgba[3]);
@@ -504,12 +504,12 @@ static void brush_painter_imbuf_update(BrushPainter *painter,
if (use_float) {
/* handle float pixel */
float *bf = ibuf->rect_float + (y * ibuf->x + x) * 4;
float *tf = texibuf->rect_float + (y * texibuf->x + x) * 4;
float *bf = ibuf->float_buffer.data + (y * ibuf->x + x) * 4;
float *tf = texibuf->float_buffer.data + (y * texibuf->x + x) * 4;
/* read from old texture buffer */
if (use_texture_old) {
const float *otf = oldtexibuf->rect_float +
const float *otf = oldtexibuf->float_buffer.data +
((y - origy + yt) * oldtexibuf->x + (x - origx + xt)) * 4;
copy_v4_v4(rgba, otf);
}
@@ -525,12 +525,12 @@ static void brush_painter_imbuf_update(BrushPainter *painter,
uchar crgba[4];
/* handle byte pixel */
uchar *b = (uchar *)ibuf->rect + (y * ibuf->x + x) * 4;
uchar *t = (uchar *)texibuf->rect + (y * texibuf->x + x) * 4;
uchar *b = ibuf->byte_buffer.data + (y * ibuf->x + x) * 4;
uchar *t = texibuf->byte_buffer.data + (y * texibuf->x + x) * 4;
/* read from old texture buffer */
if (use_texture_old) {
uchar *ot = (uchar *)oldtexibuf->rect +
uchar *ot = oldtexibuf->byte_buffer.data +
((y - origy + yt) * oldtexibuf->x + (x - origx + xt)) * 4;
crgba[0] = ot[0];
crgba[1] = ot[1];
@@ -820,8 +820,8 @@ static bool paint_2d_ensure_tile_canvas(ImagePaintState *s, int i)
if (ibuf->channels != 4) {
s->tiles[i].state = PAINT2D_TILE_MISSING;
}
else if ((s->tiles[0].canvas->rect && !ibuf->rect) ||
(s->tiles[0].canvas->rect_float && !ibuf->rect_float))
else if ((s->tiles[0].canvas->byte_buffer.data && !ibuf->byte_buffer.data) ||
(s->tiles[0].canvas->float_buffer.data && !ibuf->float_buffer.data))
{
s->tiles[i].state = PAINT2D_TILE_MISSING;
}
@@ -849,12 +849,12 @@ static bool paint_2d_ensure_tile_canvas(ImagePaintState *s, int i)
/* keep these functions in sync */
static void paint_2d_ibuf_rgb_get(ImBuf *ibuf, int x, int y, float r_rgb[4])
{
if (ibuf->rect_float) {
const float *rrgbf = ibuf->rect_float + (ibuf->x * y + x) * 4;
if (ibuf->float_buffer.data) {
const float *rrgbf = ibuf->float_buffer.data + (ibuf->x * y + x) * 4;
copy_v4_v4(r_rgb, rrgbf);
}
else {
uchar *rrgb = (uchar *)ibuf->rect + (ibuf->x * y + x) * 4;
uchar *rrgb = ibuf->byte_buffer.data + (ibuf->x * y + x) * 4;
straight_uchar_to_premul_float(r_rgb, rrgb);
}
}
@@ -872,8 +872,8 @@ static void paint_2d_ibuf_rgb_set(
}
}
if (ibuf->rect_float) {
float *rrgbf = ibuf->rect_float + (ibuf->x * y + x) * 4;
if (ibuf->float_buffer.data) {
float *rrgbf = ibuf->float_buffer.data + (ibuf->x * y + x) * 4;
float map_alpha = (rgb[3] == 0.0f) ? rrgbf[3] : rrgbf[3] / rgb[3];
mul_v3_v3fl(rrgbf, rgb, map_alpha);
@@ -881,7 +881,7 @@ static void paint_2d_ibuf_rgb_set(
}
else {
uchar straight[4];
uchar *rrgb = (uchar *)ibuf->rect + (ibuf->x * y + x) * 4;
uchar *rrgb = ibuf->byte_buffer.data + (ibuf->x * y + x) * 4;
premul_float_to_straight_uchar(straight, rgb);
rrgb[0] = straight[0];
@@ -1212,13 +1212,19 @@ static void paint_2d_do_making_brush(ImagePaintState *s,
int origx = region->destx - tx * ED_IMAGE_UNDO_TILE_SIZE;
int origy = region->desty - ty * ED_IMAGE_UNDO_TILE_SIZE;
if (tile->canvas->rect_float) {
tmpbuf.rect_float = static_cast<float *>(ED_image_paint_tile_find(
undo_tiles, s->image, tile->canvas, &tile->iuser, tx, ty, &mask, false));
if (tile->canvas->float_buffer.data) {
IMB_assign_float_buffer(
&tmpbuf,
static_cast<float *>(ED_image_paint_tile_find(
undo_tiles, s->image, tile->canvas, &tile->iuser, tx, ty, &mask, false)),
IB_DO_NOT_TAKE_OWNERSHIP);
}
else {
tmpbuf.rect = static_cast<uint *>(ED_image_paint_tile_find(
undo_tiles, s->image, tile->canvas, &tile->iuser, tx, ty, &mask, false));
IMB_assign_byte_buffer(
&tmpbuf,
static_cast<uchar *>(ED_image_paint_tile_find(
undo_tiles, s->image, tile->canvas, &tile->iuser, tx, ty, &mask, false)),
IB_DO_NOT_TAKE_OWNERSHIP);
}
IMB_rectblend(tile->canvas,
@@ -1404,7 +1410,7 @@ static int paint_2d_canvas_set(ImagePaintState *s)
Image *ima = s->brush->clone.image;
ImBuf *ibuf = BKE_image_acquire_ibuf(ima, nullptr, nullptr);
if (!ima || !ibuf || !(ibuf->rect || ibuf->rect_float)) {
if (!ima || !ibuf || !(ibuf->byte_buffer.data || ibuf->float_buffer.data)) {
BKE_image_release_ibuf(ima, ibuf, nullptr);
return 0;
}
@@ -1412,10 +1418,10 @@ static int paint_2d_canvas_set(ImagePaintState *s)
s->clonecanvas = ibuf;
/* temporarily add float rect for cloning */
if (s->tiles[0].canvas->rect_float && !s->clonecanvas->rect_float) {
if (s->tiles[0].canvas->float_buffer.data && !s->clonecanvas->float_buffer.data) {
IMB_float_from_rect(s->clonecanvas);
}
else if (!s->tiles[0].canvas->rect_float && !s->clonecanvas->rect) {
else if (!s->tiles[0].canvas->float_buffer.data && !s->clonecanvas->byte_buffer.data) {
IMB_rect_from_float(s->clonecanvas);
}
}
@@ -1535,8 +1541,11 @@ void paint_2d_stroke(void *ps,
/* OCIO_TODO: float buffers are now always linear, so always use color correction
* this should probably be changed when texture painting color space is supported
*/
brush_painter_2d_require_imbuf(
painter->brush, tile, (ibuf->rect_float != nullptr), !is_data, painter->cache_invert);
brush_painter_2d_require_imbuf(painter->brush,
tile,
(ibuf->float_buffer.data != nullptr),
!is_data,
painter->cache_invert);
brush_painter_2d_refresh_cache(s, painter, tile, new_coord, mval, pressure, distance, size);
@@ -1710,7 +1719,7 @@ static void paint_2d_fill_add_pixel_byte(const int x_px,
if (!BLI_BITMAP_TEST(touched, coordinate)) {
float color_f[4];
uchar *color_b = (uchar *)(ibuf->rect + coordinate);
uchar *color_b = ibuf->byte_buffer.data + 4 * coordinate;
rgba_uchar_to_float(color_f, color_b);
straight_to_premul_v4(color_f);
@@ -1738,7 +1747,7 @@ static void paint_2d_fill_add_pixel_float(const int x_px,
coordinate = ((size_t)y_px) * ibuf->x + x_px;
if (!BLI_BITMAP_TEST(touched, coordinate)) {
if (len_squared_v4v4(ibuf->rect_float + 4 * coordinate, color) <= threshold_sq) {
if (len_squared_v4v4(ibuf->float_buffer.data + 4 * coordinate, color) <= threshold_sq) {
BLI_stack_push(stack, &coordinate);
}
BLI_BITMAP_SET(touched, coordinate, true);
@@ -1810,7 +1819,7 @@ void paint_2d_bucket_fill(const bContext *C,
return;
}
do_float = (ibuf->rect_float != nullptr);
do_float = (ibuf->float_buffer.data != nullptr);
/* first check if our image is float. If it is not we should correct the color to
* be in gamma space. strictly speaking this is not correct, but blender does not paint
* byte images in linear space */
@@ -1830,8 +1839,8 @@ void paint_2d_bucket_fill(const bContext *C,
if (do_float) {
for (x_px = 0; x_px < ibuf->x; x_px++) {
for (y_px = 0; y_px < ibuf->y; y_px++) {
blend_color_mix_float(ibuf->rect_float + 4 * (((size_t)y_px) * ibuf->x + x_px),
ibuf->rect_float + 4 * (((size_t)y_px) * ibuf->x + x_px),
blend_color_mix_float(ibuf->float_buffer.data + 4 * (((size_t)y_px) * ibuf->x + x_px),
ibuf->float_buffer.data + 4 * (((size_t)y_px) * ibuf->x + x_px),
color_f);
}
}
@@ -1839,8 +1848,8 @@ void paint_2d_bucket_fill(const bContext *C,
else {
for (x_px = 0; x_px < ibuf->x; x_px++) {
for (y_px = 0; y_px < ibuf->y; y_px++) {
blend_color_mix_byte((uchar *)(ibuf->rect + ((size_t)y_px) * ibuf->x + x_px),
(uchar *)(ibuf->rect + ((size_t)y_px) * ibuf->x + x_px),
blend_color_mix_byte(ibuf->byte_buffer.data + 4 * (((size_t)y_px) * ibuf->x + x_px),
ibuf->byte_buffer.data + 4 * (((size_t)y_px) * ibuf->x + x_px),
(uchar *)&color_b);
}
}
@@ -1876,10 +1885,10 @@ void paint_2d_bucket_fill(const bContext *C,
coordinate = (((size_t)y_px) * ibuf->x + x_px);
if (do_float) {
copy_v4_v4(pixel_color, ibuf->rect_float + 4 * coordinate);
copy_v4_v4(pixel_color, ibuf->float_buffer.data + 4 * coordinate);
}
else {
int pixel_color_b = *(ibuf->rect + coordinate);
int pixel_color_b = *ibuf->byte_buffer.data + 4 * coordinate;
rgba_uchar_to_float(pixel_color, (uchar *)&pixel_color_b);
straight_to_premul_v4(pixel_color);
}
@@ -1891,8 +1900,8 @@ void paint_2d_bucket_fill(const bContext *C,
while (!BLI_stack_is_empty(stack)) {
BLI_stack_pop(stack, &coordinate);
IMB_blend_color_float(ibuf->rect_float + 4 * (coordinate),
ibuf->rect_float + 4 * (coordinate),
IMB_blend_color_float(ibuf->float_buffer.data + 4 * (coordinate),
ibuf->float_buffer.data + 4 * (coordinate),
color_f,
IMB_BlendMode(br->blend));
@@ -1935,8 +1944,8 @@ void paint_2d_bucket_fill(const bContext *C,
while (!BLI_stack_is_empty(stack)) {
BLI_stack_pop(stack, &coordinate);
IMB_blend_color_byte((uchar *)(ibuf->rect + coordinate),
(uchar *)(ibuf->rect + coordinate),
IMB_blend_color_byte(ibuf->byte_buffer.data + 4 * coordinate,
ibuf->byte_buffer.data + 4 * coordinate,
(uchar *)&color_b,
IMB_BlendMode(br->blend));
@@ -2039,7 +2048,7 @@ void paint_2d_gradient_fill(
line_len_sq_inv = 1.0f / line_len;
line_len = sqrtf(line_len);
do_float = (ibuf->rect_float != nullptr);
do_float = (ibuf->float_buffer.data != nullptr);
/* this will be substituted by something else when selection is available */
ED_imapaint_dirty_region(ima, ibuf, iuser, 0, 0, ibuf->x, ibuf->y, false);
@@ -2065,8 +2074,8 @@ void paint_2d_gradient_fill(
/* convert to premultiplied */
mul_v3_fl(color_f, color_f[3]);
color_f[3] *= brush_alpha;
IMB_blend_color_float(ibuf->rect_float + 4 * (((size_t)y_px) * ibuf->x + x_px),
ibuf->rect_float + 4 * (((size_t)y_px) * ibuf->x + x_px),
IMB_blend_color_float(ibuf->float_buffer.data + 4 * (((size_t)y_px) * ibuf->x + x_px),
ibuf->float_buffer.data + 4 * (((size_t)y_px) * ibuf->x + x_px),
color_f,
IMB_BlendMode(br->blend));
}
@@ -2094,8 +2103,8 @@ void paint_2d_gradient_fill(
linearrgb_to_srgb_v3_v3(color_f, color_f);
rgba_float_to_uchar((uchar *)&color_b, color_f);
((uchar *)&color_b)[3] *= brush_alpha;
IMB_blend_color_byte((uchar *)(ibuf->rect + ((size_t)y_px) * ibuf->x + x_px),
(uchar *)(ibuf->rect + ((size_t)y_px) * ibuf->x + x_px),
IMB_blend_color_byte(ibuf->byte_buffer.data + 4 * (((size_t)y_px) * ibuf->x + x_px),
ibuf->byte_buffer.data + 4 * (((size_t)y_px) * ibuf->x + x_px),
(uchar *)&color_b,
IMB_BlendMode(br->blend));
}
@@ -761,7 +761,7 @@ static bool project_paint_PickColor(
float x, y;
uvco_to_wrapped_pxco(uv, ibuf->x, ibuf->y, &x, &y);
if (ibuf->rect_float) {
if (ibuf->float_buffer.data) {
if (rgba_fp) {
bilinear_interpolation_color_wrap(ibuf, nullptr, rgba_fp, x, y);
}
@@ -792,21 +792,21 @@ static bool project_paint_PickColor(
yi = mod_i(int(uv[1] * ibuf->y), ibuf->y);
if (rgba) {
if (ibuf->rect_float) {
const float *rgba_tmp_fp = ibuf->rect_float + (xi + yi * ibuf->x * 4);
if (ibuf->float_buffer.data) {
const float *rgba_tmp_fp = ibuf->float_buffer.data + (xi + yi * ibuf->x * 4);
premul_float_to_straight_uchar(rgba, rgba_tmp_fp);
}
else {
*((uint *)rgba) = *(uint *)(((char *)ibuf->rect) + ((xi + yi * ibuf->x) * 4));
*((uint *)rgba) = *(uint *)(((char *)ibuf->byte_buffer.data) + ((xi + yi * ibuf->x) * 4));
}
}
if (rgba_fp) {
if (ibuf->rect_float) {
copy_v4_v4(rgba_fp, (ibuf->rect_float + ((xi + yi * ibuf->x) * 4)));
if (ibuf->float_buffer.data) {
copy_v4_v4(rgba_fp, (ibuf->float_buffer.data + ((xi + yi * ibuf->x) * 4)));
}
else {
uchar *tmp_ch = ((uchar *)ibuf->rect) + ((xi + yi * ibuf->x) * 4);
uchar *tmp_ch = ibuf->byte_buffer.data + ((xi + yi * ibuf->x) * 4);
straight_uchar_to_premul_float(rgba_fp, tmp_ch);
}
}
@@ -1653,7 +1653,7 @@ static void project_face_pixel(const float *lt_tri_uv[3],
/* use */
uvco_to_wrapped_pxco(uv_other, ibuf_other->x, ibuf_other->y, &x, &y);
if (ibuf_other->rect_float) { /* from float to float */
if (ibuf_other->float_buffer.data) { /* from float to float */
bilinear_interpolation_color_wrap(ibuf_other, nullptr, rgba_f, x, y);
}
else { /* from char to float */
@@ -1686,7 +1686,7 @@ static float project_paint_uvpixel_mask(const ProjPaintState *ps,
project_face_pixel(lt_other_tri_uv, ibuf_other, w, rgba_ub, rgba_f);
if (ibuf_other->rect_float) { /* from float to float */
if (ibuf_other->float_buffer.data) { /* from float to float */
mask = ((rgba_f[0] + rgba_f[1] + rgba_f[2]) * (1.0f / 3.0f)) * rgba_f[3];
}
else { /* from char to float */
@@ -1928,13 +1928,13 @@ static ProjPixel *project_paint_uvpixel_init(const ProjPaintState *ps,
projPixel->valid = projima->valid[tile_index];
if (ibuf->rect_float) {
projPixel->pixel.f_pt = ibuf->rect_float + ((x_px + y_px * ibuf->x) * 4);
if (ibuf->float_buffer.data) {
projPixel->pixel.f_pt = ibuf->float_buffer.data + ((x_px + y_px * ibuf->x) * 4);
projPixel->origColor.f_pt = (float *)projima->undoRect[tile_index] + 4 * tile_offset;
zero_v4(projPixel->newColor.f);
}
else {
projPixel->pixel.ch_pt = (uchar *)(ibuf->rect + (x_px + y_px * ibuf->x));
projPixel->pixel.ch_pt = ibuf->byte_buffer.data + (x_px + y_px * ibuf->x);
projPixel->origColor.uint_pt = (uint *)projima->undoRect[tile_index] + tile_offset;
projPixel->newColor.uint_ = 0;
}
@@ -1976,8 +1976,8 @@ static ProjPixel *project_paint_uvpixel_init(const ProjPaintState *ps,
/* #BKE_image_acquire_ibuf - TODO: this may be slow. */
if (ibuf->rect_float) {
if (ibuf_other->rect_float) { /* from float to float */
if (ibuf->float_buffer.data) {
if (ibuf_other->float_buffer.data) { /* from float to float */
project_face_pixel(
lt_other_tri_uv, ibuf_other, w, nullptr, ((ProjPixelClone *)projPixel)->clonepx.f);
}
@@ -1995,7 +1995,7 @@ static ProjPixel *project_paint_uvpixel_init(const ProjPaintState *ps,
}
}
else {
if (ibuf_other->rect_float) { /* float to char */
if (ibuf_other->float_buffer.data) { /* float to char */
float rgba[4];
project_face_pixel(lt_other_tri_uv, ibuf_other, w, nullptr, rgba);
premul_to_straight_v4(rgba);
@@ -2019,7 +2019,7 @@ static ProjPixel *project_paint_uvpixel_init(const ProjPaintState *ps,
BKE_image_release_ibuf(other_tpage, ibuf_other, nullptr);
}
else {
if (ibuf->rect_float) {
if (ibuf->float_buffer.data) {
((ProjPixelClone *)projPixel)->clonepx.f[3] = 0;
}
else {
@@ -2033,7 +2033,7 @@ static ProjPixel *project_paint_uvpixel_init(const ProjPaintState *ps,
/* no need to initialize the bucket, we're only checking buckets faces and for this
* the faces are already initialized in project_paint_delayed_face_init(...) */
if (ibuf->rect_float) {
if (ibuf->float_buffer.data) {
if (!project_paint_PickColor(
ps, co, ((ProjPixelClone *)projPixel)->clonepx.f, nullptr, true)) {
/* zero alpha - ignore */
@@ -2051,7 +2051,7 @@ static ProjPixel *project_paint_uvpixel_init(const ProjPaintState *ps,
}
#ifdef PROJ_DEBUG_PAINT
if (ibuf->rect_float) {
if (ibuf->float_buffer.data) {
projPixel->pixel.f_pt[0] = 0;
}
else {
@@ -5302,7 +5302,7 @@ static void do_projectpaint_thread(TaskPool *__restrict /*pool*/, void *ph_v)
last_projIma = projImages + last_index;
last_projIma->touch = true;
is_floatbuf = (last_projIma->ibuf->rect_float != nullptr);
is_floatbuf = (last_projIma->ibuf->float_buffer.data != nullptr);
}
/* end copy */
@@ -5395,7 +5395,7 @@ static void do_projectpaint_thread(TaskPool *__restrict /*pool*/, void *ph_v)
}
else {
if (is_floatbuf) {
BLI_assert(ps->reproject_ibuf->rect_float != nullptr);
BLI_assert(ps->reproject_ibuf->float_buffer.data != nullptr);
bicubic_interpolation_color(ps->reproject_ibuf,
nullptr,
@@ -5412,7 +5412,7 @@ static void do_projectpaint_thread(TaskPool *__restrict /*pool*/, void *ph_v)
}
}
else {
BLI_assert(ps->reproject_ibuf->rect != nullptr);
BLI_assert(ps->reproject_ibuf->byte_buffer.data != nullptr);
bicubic_interpolation_color(ps->reproject_ibuf,
projPixel->newColor.ch,
@@ -5529,7 +5529,7 @@ static void do_projectpaint_thread(TaskPool *__restrict /*pool*/, void *ph_v)
last_projIma = projImages + last_index;
last_projIma->touch = true;
is_floatbuf = (last_projIma->ibuf->rect_float != nullptr);
is_floatbuf = (last_projIma->ibuf->float_buffer.data != nullptr);
}
/* end copy */
@@ -5669,20 +5669,20 @@ static bool project_paint_op(void *state, const float lastpos[2], const float po
bool uchar_dest = false;
/* Check if the destination images are float or uchar. */
for (i = 0; i < ps->image_tot; i++) {
if (ps->projImages[i].ibuf->rect != nullptr) {
if (ps->projImages[i].ibuf->byte_buffer.data != nullptr) {
uchar_dest = true;
}
if (ps->projImages[i].ibuf->rect_float != nullptr) {
if (ps->projImages[i].ibuf->float_buffer.data != nullptr) {
float_dest = true;
}
}
/* Generate missing data if needed. */
if (float_dest && ps->reproject_ibuf->rect_float == nullptr) {
if (float_dest && ps->reproject_ibuf->float_buffer.data == nullptr) {
IMB_float_from_rect(ps->reproject_ibuf);
ps->reproject_ibuf_free_float = true;
}
if (uchar_dest && ps->reproject_ibuf->rect == nullptr) {
if (uchar_dest && ps->reproject_ibuf->byte_buffer.data == nullptr) {
IMB_rect_from_float(ps->reproject_ibuf);
ps->reproject_ibuf_free_uchar = true;
}
@@ -6163,7 +6163,7 @@ static int texture_paint_camera_project_exec(bContext *C, wmOperator *op)
ps.reproject_ibuf = BKE_image_acquire_ibuf(image, nullptr, nullptr);
if ((ps.reproject_ibuf == nullptr) ||
((ps.reproject_ibuf->rect || ps.reproject_ibuf->rect_float) == false))
((ps.reproject_ibuf->byte_buffer.data || ps.reproject_ibuf->float_buffer.data) == false))
{
BKE_report(op->reports, RPT_ERROR, "Image data could not be found");
return OPERATOR_CANCELLED;
@@ -472,7 +472,7 @@ static int palette_extract_img_exec(bContext *C, wmOperator *op)
ibuf = BKE_image_acquire_ibuf(image, &iuser, &lock);
if (ibuf && ibuf->rect) {
if (ibuf && ibuf->byte_buffer.data) {
/* Extract all colors. */
const int range = int(pow(10.0f, threshold));
for (int row = 0; row < ibuf->y; row++) {
@@ -324,7 +324,7 @@ static bool paint_brush_update(bContext *C,
if (brush->mtex.tex && brush->mtex.tex->type == TEX_IMAGE && brush->mtex.tex->ima) {
ImBuf *tex_ibuf = BKE_image_pool_acquire_ibuf(
brush->mtex.tex->ima, &brush->mtex.tex->iuser, nullptr);
if (tex_ibuf && tex_ibuf->rect_float == nullptr) {
if (tex_ibuf && tex_ibuf->float_buffer.data == nullptr) {
ups->do_linear_conversion = true;
ups->colorspace = tex_ibuf->rect_colorspace;
}
@@ -472,11 +472,11 @@ void paint_sample_color(
}
ImBuf *ibuf = BKE_image_acquire_ibuf(image, &iuser, nullptr);
if (ibuf && (ibuf->rect || ibuf->rect_float)) {
if (ibuf && (ibuf->byte_buffer.data || ibuf->float_buffer.data)) {
u = u * ibuf->x;
v = v * ibuf->y;
if (ibuf->rect_float) {
if (ibuf->float_buffer.data) {
float rgba_f[4];
if (interp == SHD_INTERP_CLOSEST) {
nearest_interpolation_color_wrap(ibuf, nullptr, rgba_f, u, v);
@@ -73,12 +73,12 @@ class ImageBufferFloat4 {
float4 read_pixel(ImBuf *image_buffer) const
{
return &image_buffer->rect_float[pixel_offset * 4];
return &image_buffer->float_buffer.data[pixel_offset * 4];
}
void write_pixel(ImBuf *image_buffer, const float4 pixel_data) const
{
copy_v4_v4(&image_buffer->rect_float[pixel_offset * 4], pixel_data);
copy_v4_v4(&image_buffer->float_buffer.data[pixel_offset * 4], pixel_data);
}
const char *get_colorspace_name(ImBuf *image_buffer)
@@ -107,15 +107,16 @@ class ImageBufferByte4 {
{
float4 result;
rgba_uchar_to_float(result,
static_cast<const uchar *>(
static_cast<const void *>(&(image_buffer->rect[pixel_offset]))));
static_cast<const uchar *>(static_cast<const void *>(
&(image_buffer->byte_buffer.data[4 * pixel_offset]))));
return result;
}
void write_pixel(ImBuf *image_buffer, const float4 pixel_data) const
{
rgba_float_to_uchar(
static_cast<uchar *>(static_cast<void *>(&image_buffer->rect[pixel_offset])), pixel_data);
rgba_float_to_uchar(static_cast<uchar *>(static_cast<void *>(
&image_buffer->byte_buffer.data[4 * pixel_offset])),
pixel_data);
}
const char *get_colorspace_name(ImBuf *image_buffer)
@@ -381,7 +382,7 @@ static void do_paint_pixels(void *__restrict userdata,
continue;
}
if (image_buffer->rect_float != nullptr) {
if (image_buffer->float_buffer.data != nullptr) {
kernel_float4.init_brush_color(image_buffer, brush_color);
}
else {
@@ -393,7 +394,7 @@ static void do_paint_pixels(void *__restrict userdata,
continue;
}
bool pixels_painted = false;
if (image_buffer->rect_float != nullptr) {
if (image_buffer->float_buffer.data != nullptr) {
pixels_painted = kernel_float4.paint(pbvh_data.geom_primitives,
node_data.uv_primitives,
pixel_row,
@@ -802,7 +802,7 @@ void uiTemplateMovieclipInformation(uiLayout *layout,
ofs += BLI_snprintf_rlen(str + ofs, sizeof(str) - ofs, TIP_("%d x %d"), width, height);
if (ibuf) {
if (ibuf->rect_float) {
if (ibuf->float_buffer.data) {
if (ibuf->channels != 4) {
ofs += BLI_snprintf_rlen(
str + ofs, sizeof(str) - ofs, TIP_(", %d float channel(s)"), ibuf->channels);
@@ -243,7 +243,7 @@ ImBuf *ED_space_clip_get_buffer(const SpaceClip *sc)
ibuf = BKE_movieclip_get_postprocessed_ibuf(sc->clip, &sc->user, sc->postproc_flag);
if (ibuf && (ibuf->rect || ibuf->rect_float)) {
if (ibuf && (ibuf->byte_buffer.data || ibuf->float_buffer.data)) {
return ibuf;
}
@@ -266,7 +266,7 @@ ImBuf *ED_space_clip_get_stable_buffer(const SpaceClip *sc,
ibuf = BKE_movieclip_get_stable_ibuf(
sc->clip, &sc->user, loc, scale, angle, sc->postproc_flag);
if (ibuf && (ibuf->rect || ibuf->rect_float)) {
if (ibuf && (ibuf->byte_buffer.data || ibuf->float_buffer.data)) {
return ibuf;
}
@@ -323,13 +323,13 @@ bool ED_space_clip_color_sample(const SpaceClip *sc,
CLAMP(x, 0, ibuf->x - 1);
CLAMP(y, 0, ibuf->y - 1);
if (ibuf->rect_float) {
fp = (ibuf->rect_float + (ibuf->channels) * (y * ibuf->x + x));
if (ibuf->float_buffer.data) {
fp = (ibuf->float_buffer.data + (ibuf->channels) * (y * ibuf->x + x));
copy_v3_v3(r_col, fp);
ret = true;
}
else if (ibuf->rect) {
cp = (uchar *)(ibuf->rect + y * ibuf->x + x);
else if (ibuf->byte_buffer.data) {
cp = ibuf->byte_buffer.data + 4 * (y * ibuf->x + x);
rgb_uchar_to_float(r_col, cp);
IMB_colormanagement_colorspace_to_scene_linear_v3(r_col, ibuf->rect_colorspace);
ret = true;
@@ -435,7 +435,7 @@ static void file_draw_preview(const FileDirEntry *file,
imb->y,
GPU_RGBA8,
true,
imb->rect,
imb->byte_buffer.data,
scale,
scale,
1.0f,
@@ -1114,10 +1114,12 @@ void filelist_init_icons(void)
if (tile < SPECIAL_IMG_MAX) {
ibuf = IMB_allocImBuf(SPECIAL_IMG_SIZE, SPECIAL_IMG_SIZE, 32, IB_rect);
for (k = 0; k < SPECIAL_IMG_SIZE; k++) {
memcpy(&ibuf->rect[k * SPECIAL_IMG_SIZE],
&bbuf->rect[(k + y * SPECIAL_IMG_SIZE) * SPECIAL_IMG_SIZE * SPECIAL_IMG_COLS +
x * SPECIAL_IMG_SIZE],
SPECIAL_IMG_SIZE * sizeof(int));
memcpy(
&ibuf->byte_buffer.data[4 * (k * SPECIAL_IMG_SIZE)],
&bbuf->byte_buffer
.data[4 * ((k + y * SPECIAL_IMG_SIZE) * SPECIAL_IMG_SIZE * SPECIAL_IMG_COLS +
x * SPECIAL_IMG_SIZE)],
SPECIAL_IMG_SIZE * sizeof(uint8_t) * 4);
}
gSpecialFileImages[tile] = ibuf;
}
@@ -946,7 +946,7 @@ void uiTemplateImage(uiLayout *layout,
void *lock;
ImBuf *ibuf = BKE_image_acquire_ibuf(ima, iuser, &lock);
if (ibuf && ibuf->rect_float && (ibuf->flags & IB_halffloat) == 0) {
if (ibuf && ibuf->float_buffer.data && (ibuf->flags & IB_halffloat) == 0) {
uiItemR(col, &imaptr, "use_half_precision", 0, NULL, ICON_NONE);
}
BKE_image_release_ibuf(ima, ibuf, lock);
@@ -1200,7 +1200,7 @@ void uiTemplateImageInfo(uiLayout *layout, bContext *C, Image *ima, ImageUser *i
ofs += BLI_snprintf_rlen(str + ofs, len - ofs, TIP_("%d x %d, "), ibuf->x, ibuf->y);
if (ibuf->rect_float) {
if (ibuf->float_buffer.data) {
if (ibuf->channels != 4) {
ofs += BLI_snprintf_rlen(
str + ofs, len - ofs, TIP_("%d float channel(s)"), ibuf->channels);
@@ -1220,7 +1220,7 @@ void uiTemplateImageInfo(uiLayout *layout, bContext *C, Image *ima, ImageUser *i
ofs += BLI_strncpy_rlen(str + ofs, TIP_(" RGB byte"), len - ofs);
}
}
if (ibuf->zbuf || ibuf->zbuf_float) {
if (ibuf->z_buffer.data || ibuf->float_z_buffer.data) {
ofs += BLI_strncpy_rlen(str + ofs, TIP_(" + Z"), len - ofs);
}
@@ -167,7 +167,7 @@ ImBuf *ED_space_image_acquire_buffer(SpaceImage *sima, void **r_lock, int tile)
return ibuf;
}
if (ibuf->rect || ibuf->rect_float) {
if (ibuf->byte_buffer.data || ibuf->float_buffer.data) {
return ibuf;
}
BKE_image_release_ibuf(sima->image, ibuf, *r_lock);
@@ -197,7 +197,7 @@ int ED_space_image_get_display_channel_mask(ImBuf *ibuf)
const bool color = ibuf->channels >= 3;
const bool alpha = ibuf->channels == 4;
const bool zbuf = ibuf->zbuf || ibuf->zbuf_float || (ibuf->channels == 1);
const bool zbuf = ibuf->z_buffer.data || ibuf->float_z_buffer.data || (ibuf->channels == 1);
if (!alpha) {
result &= ~(SI_USE_ALPHA | SI_SHOW_ALPHA);
+20 -20
View File
@@ -231,7 +231,7 @@ static bool image_from_context_has_data_poll(bContext *C)
void *lock;
ImBuf *ibuf = BKE_image_acquire_ibuf(ima, iuser, &lock);
const bool has_buffer = (ibuf && (ibuf->rect || ibuf->rect_float));
const bool has_buffer = (ibuf && (ibuf->byte_buffer.data || ibuf->float_buffer.data));
BKE_image_release_ibuf(ima, ibuf, lock);
return has_buffer;
}
@@ -2743,8 +2743,8 @@ static int image_flip_exec(bContext *C, wmOperator *op)
const int size_x = ibuf->x;
const int size_y = ibuf->y;
if (ibuf->rect_float) {
float *float_pixels = (float *)ibuf->rect_float;
if (ibuf->float_buffer.data) {
float *float_pixels = ibuf->float_buffer.data;
float *orig_float_pixels = MEM_dupallocN(float_pixels);
for (int x = 0; x < size_x; x++) {
@@ -2761,23 +2761,23 @@ static int image_flip_exec(bContext *C, wmOperator *op)
}
MEM_freeN(orig_float_pixels);
if (ibuf->rect) {
if (ibuf->byte_buffer.data) {
IMB_rect_from_float(ibuf);
}
}
else if (ibuf->rect) {
char *char_pixels = (char *)ibuf->rect;
char *orig_char_pixels = MEM_dupallocN(char_pixels);
else if (ibuf->byte_buffer.data) {
uchar *char_pixels = ibuf->byte_buffer.data;
uchar *orig_char_pixels = MEM_dupallocN(char_pixels);
for (int x = 0; x < size_x; x++) {
const int source_pixel_x = use_flip_x ? size_x - x - 1 : x;
for (int y = 0; y < size_y; y++) {
const int source_pixel_y = use_flip_y ? size_y - y - 1 : y;
const char *source_pixel =
const uchar *source_pixel =
&orig_char_pixels[4 * (source_pixel_x + source_pixel_y * size_x)];
char *target_pixel = &char_pixels[4 * (x + y * size_x)];
uchar *target_pixel = &char_pixels[4 * (x + y * size_x)];
copy_v4_v4_char(target_pixel, source_pixel);
copy_v4_v4_uchar(target_pixel, source_pixel);
}
}
MEM_freeN(orig_char_pixels);
@@ -2981,9 +2981,9 @@ static int image_invert_exec(bContext *C, wmOperator *op)
}
/* TODO: make this into an IMB_invert_channels(ibuf,r,g,b,a) method!? */
if (ibuf->rect_float) {
if (ibuf->float_buffer.data) {
float *fp = (float *)ibuf->rect_float;
float *fp = ibuf->float_buffer.data;
for (i = ((size_t)ibuf->x) * ibuf->y; i > 0; i--, fp += 4) {
if (r) {
fp[0] = 1.0f - fp[0];
@@ -2999,13 +2999,13 @@ static int image_invert_exec(bContext *C, wmOperator *op)
}
}
if (ibuf->rect) {
if (ibuf->byte_buffer.data) {
IMB_rect_from_float(ibuf);
}
}
else if (ibuf->rect) {
else if (ibuf->byte_buffer.data) {
char *cp = (char *)ibuf->rect;
uchar *cp = ibuf->byte_buffer.data;
for (i = ((size_t)ibuf->x) * ibuf->y; i > 0; i--, cp += 4) {
if (r) {
cp[0] = 255 - cp[0];
@@ -3371,13 +3371,13 @@ bool ED_space_image_color_sample(
CLAMP(x, 0, ibuf->x - 1);
CLAMP(y, 0, ibuf->y - 1);
if (ibuf->rect_float) {
fp = (ibuf->rect_float + (ibuf->channels) * (y * ibuf->x + x));
if (ibuf->float_buffer.data) {
fp = (ibuf->float_buffer.data + (ibuf->channels) * (y * ibuf->x + x));
copy_v3_v3(r_col, fp);
ret = true;
}
else if (ibuf->rect) {
cp = (uchar *)(ibuf->rect + y * ibuf->x + x);
else if (ibuf->byte_buffer.data) {
cp = ibuf->byte_buffer.data + 4 * (y * ibuf->x + x);
rgb_uchar_to_float(r_col, cp);
IMB_colormanagement_colorspace_to_scene_linear_v3(r_col, ibuf->rect_colorspace);
ret = true;
@@ -4024,7 +4024,7 @@ static void tile_fill_init(PointerRNA *ptr, Image *ima, ImageTile *tile)
/* Initialize properties from reference tile. */
RNA_int_set(ptr, "width", ibuf->x);
RNA_int_set(ptr, "height", ibuf->y);
RNA_boolean_set(ptr, "float", ibuf->rect_float != NULL);
RNA_boolean_set(ptr, "float", ibuf->float_buffer.data != NULL);
RNA_boolean_set(ptr, "alpha", ibuf->planes > 24);
BKE_image_release_ibuf(ima, ibuf, NULL);
@@ -117,7 +117,7 @@ struct PaintTile {
ImageUser iuser;
union {
float *fp;
uint32_t *uint;
uint8_t *byte_ptr;
void *pt;
} rect;
uint16_t *mask;
@@ -189,6 +189,21 @@ void *ED_image_paint_tile_find(PaintTileMap *paint_tile_map,
return ptile->rect.pt;
}
/* Set the given buffer data as an owning data of the imbuf's buffer.
* Returns the data pointer which was stolen from the imbuf before assignment. */
static uint8_t *image_undo_steal_and_assign_byte_buffer(ImBuf *ibuf, uint8_t *new_buffer_data)
{
uint8_t *old_buffer_data = IMB_steal_byte_buffer(ibuf);
IMB_assign_byte_buffer(ibuf, new_buffer_data, IB_TAKE_OWNERSHIP);
return old_buffer_data;
}
static float *image_undo_steal_and_assign_float_buffer(ImBuf *ibuf, float *new_buffer_data)
{
float *old_buffer_data = IMB_steal_float_buffer(ibuf);
IMB_assign_float_buffer(ibuf, new_buffer_data, IB_TAKE_OWNERSHIP);
return old_buffer_data;
}
void *ED_image_paint_tile_push(PaintTileMap *paint_tile_map,
Image *image,
ImBuf *ibuf,
@@ -204,7 +219,7 @@ void *ED_image_paint_tile_push(PaintTileMap *paint_tile_map,
if (use_thread_lock) {
BLI_spin_lock(&paint_tiles_lock);
}
const bool has_float = (ibuf->rect_float != nullptr);
const bool has_float = (ibuf->float_buffer.data != nullptr);
/* check if tile is already pushed */
@@ -240,7 +255,7 @@ void *ED_image_paint_tile_push(PaintTileMap *paint_tile_map,
MEM_callocN(sizeof(uint16_t) * square_i(ED_IMAGE_UNDO_TILE_SIZE), "PaintTile.mask"));
}
ptile->rect.pt = MEM_callocN((ibuf->rect_float ? sizeof(float[4]) : sizeof(char[4])) *
ptile->rect.pt = MEM_callocN((ibuf->float_buffer.data ? sizeof(float[4]) : sizeof(char[4])) *
square_i(ED_IMAGE_UNDO_TILE_SIZE),
"PaintTile.rect");
@@ -261,10 +276,10 @@ void *ED_image_paint_tile_push(PaintTileMap *paint_tile_map,
ED_IMAGE_UNDO_TILE_SIZE);
if (has_float) {
std::swap(ptile->rect.fp, (*tmpibuf)->rect_float);
ptile->rect.fp = image_undo_steal_and_assign_float_buffer(*tmpibuf, ptile->rect.fp);
}
else {
std::swap(ptile->rect.uint, (*tmpibuf)->rect);
ptile->rect.byte_ptr = image_undo_steal_and_assign_byte_buffer(*tmpibuf, ptile->rect.byte_ptr);
}
PaintTileKey key = {};
@@ -296,15 +311,18 @@ static void ptile_restore_runtime_map(PaintTileMap *paint_tile_map)
for (PaintTile *ptile : paint_tile_map->map.values()) {
Image *image = ptile->image;
ImBuf *ibuf = BKE_image_acquire_ibuf(image, &ptile->iuser, nullptr);
const bool has_float = (ibuf->rect_float != nullptr);
const bool has_float = (ibuf->float_buffer.data != nullptr);
if (has_float) {
std::swap(ptile->rect.fp, tmpibuf->rect_float);
ptile->rect.fp = image_undo_steal_and_assign_float_buffer(tmpibuf, ptile->rect.fp);
}
else {
std::swap(ptile->rect.uint, tmpibuf->rect);
ptile->rect.byte_ptr = image_undo_steal_and_assign_byte_buffer(tmpibuf,
ptile->rect.byte_ptr);
}
/* TODO(sergey): Look into implementing API which does not require such temporary buffer
* assignment. */
IMB_rectcpy(ibuf,
tmpibuf,
ptile->x_tile * ED_IMAGE_UNDO_TILE_SIZE,
@@ -315,16 +333,17 @@ static void ptile_restore_runtime_map(PaintTileMap *paint_tile_map)
ED_IMAGE_UNDO_TILE_SIZE);
if (has_float) {
std::swap(ptile->rect.fp, tmpibuf->rect_float);
ptile->rect.fp = image_undo_steal_and_assign_float_buffer(tmpibuf, ptile->rect.fp);
}
else {
std::swap(ptile->rect.uint, tmpibuf->rect);
ptile->rect.byte_ptr = image_undo_steal_and_assign_byte_buffer(tmpibuf,
ptile->rect.byte_ptr);
}
/* Force OpenGL reload (maybe partial update will operate better?) */
BKE_image_free_gputextures(image);
if (ibuf->rect_float) {
if (ibuf->float_buffer.data) {
ibuf->userflags |= IB_RECT_INVALID; /* force recreate of char rect */
}
if (ibuf->mipmap[0]) {
@@ -353,7 +372,7 @@ static uint32_t index_from_xy(uint32_t tile_x, uint32_t tile_y, const uint32_t t
struct UndoImageTile {
union {
float *fp;
uint32_t *uint_ptr;
uint8_t *byte_ptr;
void *pt;
} rect;
int users;
@@ -368,7 +387,7 @@ static UndoImageTile *utile_alloc(bool has_float)
MEM_mallocN(sizeof(float[4]) * square_i(ED_IMAGE_UNDO_TILE_SIZE), __func__));
}
else {
utile->rect.uint_ptr = static_cast<uint32_t *>(
utile->rect.byte_ptr = static_cast<uint8_t *>(
MEM_mallocN(sizeof(uint32_t) * square_i(ED_IMAGE_UNDO_TILE_SIZE), __func__));
}
return utile;
@@ -377,43 +396,47 @@ static UndoImageTile *utile_alloc(bool has_float)
static void utile_init_from_imbuf(
UndoImageTile *utile, const uint32_t x, const uint32_t y, const ImBuf *ibuf, ImBuf *tmpibuf)
{
const bool has_float = ibuf->rect_float;
const bool has_float = ibuf->float_buffer.data;
if (has_float) {
std::swap(utile->rect.fp, tmpibuf->rect_float);
utile->rect.fp = image_undo_steal_and_assign_float_buffer(tmpibuf, utile->rect.fp);
}
else {
std::swap(utile->rect.uint_ptr, tmpibuf->rect);
utile->rect.byte_ptr = image_undo_steal_and_assign_byte_buffer(tmpibuf, utile->rect.byte_ptr);
}
/* TODO(sergey): Look into implementing API which does not require such temporary buffer
* assignment. */
IMB_rectcpy(tmpibuf, ibuf, 0, 0, x, y, ED_IMAGE_UNDO_TILE_SIZE, ED_IMAGE_UNDO_TILE_SIZE);
if (has_float) {
std::swap(utile->rect.fp, tmpibuf->rect_float);
utile->rect.fp = image_undo_steal_and_assign_float_buffer(tmpibuf, utile->rect.fp);
}
else {
std::swap(utile->rect.uint_ptr, tmpibuf->rect);
utile->rect.byte_ptr = image_undo_steal_and_assign_byte_buffer(tmpibuf, utile->rect.byte_ptr);
}
}
static void utile_restore(
const UndoImageTile *utile, const uint x, const uint y, ImBuf *ibuf, ImBuf *tmpibuf)
{
const bool has_float = ibuf->rect_float;
float *prev_rect_float = tmpibuf->rect_float;
uint32_t *prev_rect = tmpibuf->rect;
const bool has_float = ibuf->float_buffer.data;
float *prev_rect_float = tmpibuf->float_buffer.data;
uint8_t *prev_rect = tmpibuf->byte_buffer.data;
if (has_float) {
tmpibuf->rect_float = utile->rect.fp;
tmpibuf->float_buffer.data = utile->rect.fp;
}
else {
tmpibuf->rect = utile->rect.uint_ptr;
tmpibuf->byte_buffer.data = utile->rect.byte_ptr;
}
/* TODO(sergey): Look into implementing API which does not require such temporary buffer
* assignment. */
IMB_rectcpy(ibuf, tmpibuf, x, y, 0, 0, ED_IMAGE_UNDO_TILE_SIZE, ED_IMAGE_UNDO_TILE_SIZE);
tmpibuf->rect_float = prev_rect_float;
tmpibuf->rect = prev_rect;
tmpibuf->float_buffer.data = prev_rect_float;
tmpibuf->byte_buffer.data = prev_rect;
}
static void utile_decref(UndoImageTile *utile)
@@ -473,7 +496,7 @@ static UndoImageBuf *ubuf_from_image_no_tiles(Image *image, const ImBuf *ibuf)
STRNCPY(ubuf->ibuf_filepath, ibuf->filepath);
ubuf->image_state.source = image->source;
ubuf->image_state.use_float = ibuf->rect_float != nullptr;
ubuf->image_state.use_float = ibuf->float_buffer.data != nullptr;
return ubuf;
}
@@ -482,7 +505,7 @@ static void ubuf_from_image_all_tiles(UndoImageBuf *ubuf, const ImBuf *ibuf)
{
ImBuf *tmpibuf = imbuf_alloc_temp_tile();
const bool has_float = ibuf->rect_float;
const bool has_float = ibuf->float_buffer.data;
int i = 0;
for (uint y_tile = 0; y_tile < ubuf->tiles_dims[1]; y_tile += 1) {
uint y = y_tile << ED_IMAGE_UNDO_TILE_BITS;
@@ -509,12 +532,13 @@ static void ubuf_ensure_compat_ibuf(const UndoImageBuf *ubuf, ImBuf *ibuf)
{
/* We could have both float and rect buffers,
* in this case free the float buffer if it's unused. */
if ((ibuf->rect_float != nullptr) && (ubuf->image_state.use_float == false)) {
if ((ibuf->float_buffer.data != nullptr) && (ubuf->image_state.use_float == false)) {
imb_freerectfloatImBuf(ibuf);
}
if (ibuf->x == ubuf->image_dims[0] && ibuf->y == ubuf->image_dims[1] &&
(ubuf->image_state.use_float ? (void *)ibuf->rect_float : (void *)ibuf->rect))
(ubuf->image_state.use_float ? (void *)ibuf->float_buffer.data :
(void *)ibuf->byte_buffer.data))
{
return;
}
@@ -602,7 +626,7 @@ static void uhandle_restore_list(ListBase *undo_handles, bool use_init)
/* TODO(@jbakker): only mark areas that are actually updated to improve performance. */
BKE_image_partial_update_mark_full_update(image);
if (ibuf->rect_float) {
if (ibuf->float_buffer.data) {
ibuf->userflags |= IB_RECT_INVALID; /* Force recreate of char `rect` */
}
if (ibuf->mipmap[0]) {
@@ -832,7 +856,7 @@ static bool image_undosys_step_encode(struct bContext *C, struct Main * /*bmain*
ImBuf *ibuf = BKE_image_acquire_ibuf(uh->image_ref.ptr, &uh->iuser, nullptr);
const bool has_float = ibuf->rect_float;
const bool has_float = ibuf->float_buffer.data;
BLI_assert(ubuf_pre->post == nullptr);
ubuf_pre->post = ubuf_from_image_no_tiles(uh->image_ref.ptr, ibuf);
+13 -13
View File
@@ -510,14 +510,14 @@ bool ED_space_node_color_sample(
CLAMP(x, 0, ibuf->x - 1);
CLAMP(y, 0, ibuf->y - 1);
if (ibuf->rect_float) {
fp = (ibuf->rect_float + (ibuf->channels) * (y * ibuf->x + x));
if (ibuf->float_buffer.data) {
fp = (ibuf->float_buffer.data + (ibuf->channels) * (y * ibuf->x + x));
/* #IB_PROFILE_NONE is default but in fact its linear. */
copy_v3_v3(r_col, fp);
ret = true;
}
else if (ibuf->rect) {
cp = (uchar *)(ibuf->rect + y * ibuf->x + x);
else if (ibuf->byte_buffer.data) {
cp = ibuf->byte_buffer.data + 4 * (y * ibuf->x + x);
rgb_uchar_to_float(r_col, cp);
IMB_colormanagement_colorspace_to_scene_linear_v3(r_col, ibuf->rect_colorspace);
ret = true;
@@ -549,7 +549,7 @@ static void sample_apply(bContext *C, wmOperator *op, const wmEvent *event)
return;
}
if (!ibuf->rect) {
if (!ibuf->byte_buffer.data) {
IMB_rect_from_float(ibuf);
}
@@ -577,8 +577,8 @@ static void sample_apply(bContext *C, wmOperator *op, const wmEvent *event)
info->zp = nullptr;
info->zfp = nullptr;
if (ibuf->rect) {
cp = (uchar *)(ibuf->rect + y * ibuf->x + x);
if (ibuf->byte_buffer.data) {
cp = ibuf->byte_buffer.data + 4 * (y * ibuf->x + x);
info->col[0] = cp[0];
info->col[1] = cp[1];
@@ -596,8 +596,8 @@ static void sample_apply(bContext *C, wmOperator *op, const wmEvent *event)
info->color_manage = true;
}
if (ibuf->rect_float) {
fp = (ibuf->rect_float + (ibuf->channels) * (y * ibuf->x + x));
if (ibuf->float_buffer.data) {
fp = (ibuf->float_buffer.data + (ibuf->channels) * (y * ibuf->x + x));
info->colf[0] = fp[0];
info->colf[1] = fp[1];
@@ -607,12 +607,12 @@ static void sample_apply(bContext *C, wmOperator *op, const wmEvent *event)
info->color_manage = true;
}
if (ibuf->zbuf) {
info->z = ibuf->zbuf[y * ibuf->x + x];
if (ibuf->z_buffer.data) {
info->z = ibuf->z_buffer.data[y * ibuf->x + x];
info->zp = &info->z;
}
if (ibuf->zbuf_float) {
info->zf = ibuf->zbuf_float[y * ibuf->x + x];
if (ibuf->float_z_buffer.data) {
info->zf = ibuf->float_z_buffer.data[y * ibuf->x + x];
info->zfp = &info->zf;
}
@@ -1762,8 +1762,8 @@ static void *sequencer_OCIO_transform_ibuf(const bContext *C,
*r_glsl_used = false;
display_buffer = NULL;
}
else if (ibuf->rect_float) {
display_buffer = ibuf->rect_float;
else if (ibuf->float_buffer.data) {
display_buffer = ibuf->float_buffer.data;
*r_data = GPU_DATA_FLOAT;
if (ibuf->channels == 4) {
@@ -1787,8 +1787,8 @@ static void *sequencer_OCIO_transform_ibuf(const bContext *C,
*r_glsl_used = IMB_colormanagement_setup_glsl_draw_ctx(C, ibuf->dither, true);
}
}
else if (ibuf->rect) {
display_buffer = ibuf->rect;
else if (ibuf->byte_buffer.data) {
display_buffer = ibuf->byte_buffer.data;
*r_glsl_used = IMB_colormanagement_setup_glsl_draw_from_space_ctx(
C, ibuf->rect_colorspace, ibuf->dither, false);
@@ -1799,7 +1799,7 @@ static void *sequencer_OCIO_transform_ibuf(const bContext *C,
/* There is data to be displayed, but GLSL is not initialized
* properly, in this case we fallback to CPU-based display transform. */
if ((ibuf->rect || ibuf->rect_float) && !*r_glsl_used) {
if ((ibuf->byte_buffer.data || ibuf->float_buffer.data) && !*r_glsl_used) {
display_buffer = IMB_display_buffer_acquire_ctx(C, ibuf, r_buffer_cache_handle);
*r_format = GPU_RGBA8;
*r_data = GPU_DATA_UBYTE;
@@ -1896,11 +1896,11 @@ static void sequencer_draw_display_buffer(const bContext *C,
if (scope) {
ibuf = scope;
if (ibuf->rect_float && ibuf->rect == NULL) {
if (ibuf->float_buffer.data && ibuf->byte_buffer.data == NULL) {
IMB_rect_from_float(ibuf);
}
display_buffer = (uchar *)ibuf->rect;
display_buffer = ibuf->byte_buffer.data;
format = GPU_RGBA8;
data = GPU_DATA_UBYTE;
}
@@ -1992,7 +1992,7 @@ static ImBuf *sequencer_get_scope(Scene *scene, SpaceSeq *sseq, ImBuf *ibuf, boo
if (!scopes->zebra_ibuf) {
ImBuf *display_ibuf = IMB_dupImBuf(ibuf);
if (display_ibuf->rect_float) {
if (display_ibuf->float_buffer.data) {
IMB_colormanagement_imbuf_make_display_space(
display_ibuf, &scene->view_settings, &scene->display_settings);
}
@@ -126,8 +126,8 @@ static ImBuf *make_waveform_view_from_ibuf_byte(ImBuf *ibuf)
{
ImBuf *rval = IMB_allocImBuf(ibuf->x + 3, 515, 32, IB_rect);
int x, y;
const uchar *src = (uchar *)ibuf->rect;
uchar *tgt = (uchar *)rval->rect;
const uchar *src = ibuf->byte_buffer.data;
uchar *tgt = rval->byte_buffer.data;
int w = ibuf->x + 3;
int h = 515;
float waveform_gamma = 0.2;
@@ -167,8 +167,8 @@ static ImBuf *make_waveform_view_from_ibuf_float(ImBuf *ibuf)
{
ImBuf *rval = IMB_allocImBuf(ibuf->x + 3, 515, 32, IB_rect);
int x, y;
const float *src = ibuf->rect_float;
uchar *tgt = (uchar *)rval->rect;
const float *src = ibuf->float_buffer.data;
uchar *tgt = rval->byte_buffer.data;
int w = ibuf->x + 3;
int h = 515;
float waveform_gamma = 0.2;
@@ -210,7 +210,7 @@ static ImBuf *make_waveform_view_from_ibuf_float(ImBuf *ibuf)
ImBuf *make_waveform_view_from_ibuf(ImBuf *ibuf)
{
if (ibuf->rect_float) {
if (ibuf->float_buffer.data) {
return make_waveform_view_from_ibuf_float(ibuf);
}
return make_waveform_view_from_ibuf_byte(ibuf);
@@ -220,8 +220,8 @@ static ImBuf *make_sep_waveform_view_from_ibuf_byte(ImBuf *ibuf)
{
ImBuf *rval = IMB_allocImBuf(ibuf->x + 3, 515, 32, IB_rect);
int x, y;
const uchar *src = (const uchar *)ibuf->rect;
uchar *tgt = (uchar *)rval->rect;
const uchar *src = ibuf->byte_buffer.data;
uchar *tgt = rval->byte_buffer.data;
int w = ibuf->x + 3;
int sw = ibuf->x / 3;
int h = 515;
@@ -265,8 +265,8 @@ static ImBuf *make_sep_waveform_view_from_ibuf_float(ImBuf *ibuf)
{
ImBuf *rval = IMB_allocImBuf(ibuf->x + 3, 515, 32, IB_rect);
int x, y;
const float *src = ibuf->rect_float;
uchar *tgt = (uchar *)rval->rect;
const float *src = ibuf->float_buffer.data;
uchar *tgt = rval->byte_buffer.data;
int w = ibuf->x + 3;
int sw = ibuf->x / 3;
int h = 515;
@@ -312,7 +312,7 @@ static ImBuf *make_sep_waveform_view_from_ibuf_float(ImBuf *ibuf)
ImBuf *make_sep_waveform_view_from_ibuf(ImBuf *ibuf)
{
if (ibuf->rect_float) {
if (ibuf->float_buffer.data) {
return make_sep_waveform_view_from_ibuf_float(ibuf);
}
return make_sep_waveform_view_from_ibuf_byte(ibuf);
@@ -321,8 +321,8 @@ ImBuf *make_sep_waveform_view_from_ibuf(ImBuf *ibuf)
static void draw_zebra_byte(ImBuf *src, ImBuf *ibuf, float perc)
{
uint limit = 255.0f * perc / 100.0f;
uchar *p = (uchar *)src->rect;
uchar *o = (uchar *)ibuf->rect;
uchar *p = src->byte_buffer.data;
uchar *o = ibuf->byte_buffer.data;
int x;
int y;
@@ -351,8 +351,8 @@ static void draw_zebra_byte(ImBuf *src, ImBuf *ibuf, float perc)
static void draw_zebra_float(ImBuf *src, ImBuf *ibuf, float perc)
{
float limit = perc / 100.0f;
const float *p = src->rect_float;
uchar *o = (uchar *)ibuf->rect;
const float *p = src->float_buffer.data;
uchar *o = ibuf->byte_buffer.data;
int x;
int y;
@@ -383,7 +383,7 @@ ImBuf *make_zebra_view_from_ibuf(ImBuf *ibuf, float perc)
{
ImBuf *new_ibuf = IMB_allocImBuf(ibuf->x, ibuf->y, 32, IB_rect);
if (ibuf->rect_float) {
if (ibuf->float_buffer.data) {
draw_zebra_float(ibuf, new_ibuf, perc);
}
else {
@@ -394,7 +394,7 @@ ImBuf *make_zebra_view_from_ibuf(ImBuf *ibuf, float perc)
static void draw_histogram_marker(ImBuf *ibuf, int x)
{
uchar *p = (uchar *)ibuf->rect;
uchar *p = ibuf->byte_buffer.data;
int barh = ibuf->y * 0.1;
p += 4 * (x + ibuf->x * (ibuf->y - barh + 1));
@@ -407,7 +407,7 @@ static void draw_histogram_marker(ImBuf *ibuf, int x)
static void draw_histogram_bar(ImBuf *ibuf, int x, float val, int col)
{
uchar *p = (uchar *)ibuf->rect;
uchar *p = ibuf->byte_buffer.data;
int barh = ibuf->y * val * 0.9f;
p += 4 * (x + ibuf->x);
@@ -430,7 +430,7 @@ static void make_histogram_view_from_ibuf_byte_fn(void *__restrict userdata,
{
MakeHistogramViewData *data = userdata;
const ImBuf *ibuf = data->ibuf;
const uchar *src = (uchar *)ibuf->rect;
const uchar *src = ibuf->byte_buffer.data;
uint32_t(*cur_bins)[HIS_STEPS] = tls->userdata_chunk;
@@ -506,7 +506,7 @@ static ImBuf *make_histogram_view_from_ibuf_byte(ImBuf *ibuf)
}
}
wform_put_border((uchar *)rval->rect, rval->x, rval->y);
wform_put_border(rval->byte_buffer.data, rval->x, rval->y);
return rval;
}
@@ -529,7 +529,7 @@ static void make_histogram_view_from_ibuf_float_fn(void *__restrict userdata,
{
const MakeHistogramViewData *data = userdata;
const ImBuf *ibuf = data->ibuf;
const float *src = ibuf->rect_float;
const float *src = ibuf->float_buffer.data;
uint32_t(*cur_bins)[HIS_STEPS] = tls->userdata_chunk;
@@ -590,7 +590,7 @@ static ImBuf *make_histogram_view_from_ibuf_float(ImBuf *ibuf)
draw_histogram_marker(rval, get_bin_float(0.0));
draw_histogram_marker(rval, get_bin_float(1.0));
wform_put_border((uchar *)rval->rect, rval->x, rval->y);
wform_put_border(rval->byte_buffer.data, rval->x, rval->y);
return rval;
}
@@ -599,16 +599,16 @@ static ImBuf *make_histogram_view_from_ibuf_float(ImBuf *ibuf)
ImBuf *make_histogram_view_from_ibuf(ImBuf *ibuf)
{
if (ibuf->rect_float) {
if (ibuf->float_buffer.data) {
return make_histogram_view_from_ibuf_float(ibuf);
}
return make_histogram_view_from_ibuf_byte(ibuf);
}
static void vectorscope_put_cross(uchar r, uchar g, uchar b, char *tgt, int w, int h, int size)
static void vectorscope_put_cross(uchar r, uchar g, uchar b, uchar *tgt, int w, int h, int size)
{
float rgb[3], yuv[3];
char *p;
uchar *p;
rgb[0] = (float)r / 255.0f;
rgb[1] = (float)g / 255.0f;
@@ -623,7 +623,7 @@ static void vectorscope_put_cross(uchar r, uchar g, uchar b, char *tgt, int w, i
for (int y = -size; y <= size; y++) {
for (int x = -size; x <= size; x++) {
char *q = p + 4 * (y * w + x);
uchar *q = p + 4 * (y * w + x);
q[0] = r;
q[1] = g;
q[2] = b;
@@ -636,8 +636,8 @@ static ImBuf *make_vectorscope_view_from_ibuf_byte(ImBuf *ibuf)
{
ImBuf *rval = IMB_allocImBuf(515, 515, 32, IB_rect);
int x, y;
const char *src = (const char *)ibuf->rect;
char *tgt = (char *)rval->rect;
const uchar *src = ibuf->byte_buffer.data;
uchar *tgt = rval->byte_buffer.data;
float rgb[3], yuv[3];
int w = 515;
int h = 515;
@@ -659,8 +659,8 @@ static ImBuf *make_vectorscope_view_from_ibuf_byte(ImBuf *ibuf)
for (y = 0; y < ibuf->y; y++) {
for (x = 0; x < ibuf->x; x++) {
const char *src1 = src + 4 * (ibuf->x * y + x);
char *p;
const uchar *src1 = src + 4 * (ibuf->x * y + x);
uchar *p;
rgb[0] = (float)src1[0] / 255.0f;
rgb[1] = (float)src1[1] / 255.0f;
@@ -681,8 +681,8 @@ static ImBuf *make_vectorscope_view_from_ibuf_float(ImBuf *ibuf)
{
ImBuf *rval = IMB_allocImBuf(515, 515, 32, IB_rect);
int x, y;
const float *src = ibuf->rect_float;
char *tgt = (char *)rval->rect;
const float *src = ibuf->float_buffer.data;
uchar *tgt = rval->byte_buffer.data;
float rgb[3], yuv[3];
int w = 515;
int h = 515;
@@ -705,7 +705,7 @@ static ImBuf *make_vectorscope_view_from_ibuf_float(ImBuf *ibuf)
for (y = 0; y < ibuf->y; y++) {
for (x = 0; x < ibuf->x; x++) {
const float *src1 = src + 4 * (ibuf->x * y + x);
const char *p;
const uchar *p;
memcpy(rgb, src1, sizeof(float[3]));
@@ -725,7 +725,7 @@ static ImBuf *make_vectorscope_view_from_ibuf_float(ImBuf *ibuf)
ImBuf *make_vectorscope_view_from_ibuf(ImBuf *ibuf)
{
if (ibuf->rect_float) {
if (ibuf->float_buffer.data) {
return make_vectorscope_view_from_ibuf_float(ibuf);
}
return make_vectorscope_view_from_ibuf_byte(ibuf);
@@ -541,14 +541,14 @@ void draw_seq_strip_thumbnail(View2D *v2d,
/* Transparency on overlap. */
if (seq->flag & SEQ_OVERLAP) {
GPU_blend(GPU_BLEND_ALPHA);
if (ibuf->rect) {
uchar *buf = (uchar *)ibuf->rect;
if (ibuf->byte_buffer.data) {
uchar *buf = ibuf->byte_buffer.data;
for (int pixel = ibuf->x * ibuf->y; pixel--; buf += 4) {
buf[3] = OVERLAP_ALPHA;
}
}
else if (ibuf->rect_float) {
float *buf = (float *)ibuf->rect_float;
else if (ibuf->float_buffer.data) {
float *buf = ibuf->float_buffer.data;
for (int pixel = ibuf->x * ibuf->y; pixel--; buf += ibuf->channels) {
buf[3] = (OVERLAP_ALPHA / 255.0f);
}
@@ -1973,7 +1973,7 @@ ImBuf *ED_view3d_draw_offscreen_imbuf(Depsgraph *depsgraph,
* When using workbench the color differences haven't been reported as a bug. But users also use
* the viewport rendering to render Eevee scenes. In the later situation the saved colors are
* totally wrong. */
const bool do_color_management = (ibuf->rect_float == nullptr);
const bool do_color_management = (ibuf->float_buffer.data == nullptr);
ED_view3d_draw_offscreen(depsgraph,
scene,
drawtype,
@@ -1991,11 +1991,11 @@ ImBuf *ED_view3d_draw_offscreen_imbuf(Depsgraph *depsgraph,
ofs,
nullptr);
if (ibuf->rect_float) {
GPU_offscreen_read_color(ofs, GPU_DATA_FLOAT, ibuf->rect_float);
if (ibuf->float_buffer.data) {
GPU_offscreen_read_color(ofs, GPU_DATA_FLOAT, ibuf->float_buffer.data);
}
else if (ibuf->rect) {
GPU_offscreen_read_color(ofs, GPU_DATA_UBYTE, ibuf->rect);
else if (ibuf->byte_buffer.data) {
GPU_offscreen_read_color(ofs, GPU_DATA_UBYTE, ibuf->byte_buffer.data);
}
/* unbind */
@@ -2011,7 +2011,7 @@ ImBuf *ED_view3d_draw_offscreen_imbuf(Depsgraph *depsgraph,
GPU_framebuffer_bind(old_fb);
}
if (ibuf->rect_float && ibuf->rect) {
if (ibuf->float_buffer.data && ibuf->byte_buffer.data) {
IMB_rect_from_float(ibuf);
}
+16 -14
View File
@@ -79,7 +79,7 @@ static void image_sample_pixel_color_ubyte(const ImBuf *ibuf,
uchar r_col[4],
float r_col_linear[4])
{
const uchar *cp = (uchar *)(ibuf->rect + coord[1] * ibuf->x + coord[0]);
const uchar *cp = ibuf->byte_buffer.data + 4 * (coord[1] * ibuf->x + coord[0]);
copy_v4_v4_uchar(r_col, cp);
rgba_uchar_to_float(r_col_linear, r_col);
IMB_colormanagement_colorspace_to_scene_linear_v4(r_col_linear, false, ibuf->rect_colorspace);
@@ -87,7 +87,7 @@ static void image_sample_pixel_color_ubyte(const ImBuf *ibuf,
static void image_sample_pixel_color_float(ImBuf *ibuf, const int coord[2], float r_col[4])
{
const float *cp = ibuf->rect_float + (ibuf->channels) * (coord[1] * ibuf->x + coord[0]);
const float *cp = ibuf->float_buffer.data + (ibuf->channels) * (coord[1] * ibuf->x + coord[0]);
copy_v4_v4(r_col, cp);
}
@@ -198,7 +198,7 @@ static void image_sample_apply(bContext *C, wmOperator *op, const wmEvent *event
sample_rect.xmax = min_ii(ibuf->x, sample_rect.xmin + info->sample_size) - 1;
sample_rect.ymax = min_ii(ibuf->y, sample_rect.ymin + info->sample_size) - 1;
if (ibuf->rect) {
if (ibuf->byte_buffer.data) {
image_sample_rect_color_ubyte(ibuf, &sample_rect, info->col, info->linearcol);
rgba_uchar_to_float(info->colf, info->col);
@@ -206,7 +206,7 @@ static void image_sample_apply(bContext *C, wmOperator *op, const wmEvent *event
info->colfp = info->colf;
info->color_manage = true;
}
if (ibuf->rect_float) {
if (ibuf->float_buffer.data) {
image_sample_rect_color_float(ibuf, &sample_rect, info->colf);
if (ibuf->channels == 4) {
@@ -227,19 +227,21 @@ static void image_sample_apply(bContext *C, wmOperator *op, const wmEvent *event
info->color_manage = true;
}
if (ibuf->zbuf) {
if (ibuf->z_buffer.data) {
/* TODO: blend depth (not urgent). */
info->z = ibuf->zbuf[y * ibuf->x + x];
info->z = ibuf->z_buffer.data[y * ibuf->x + x];
info->zp = &info->z;
if (ibuf->zbuf == (int *)ibuf->rect) {
/* NOTE: Follows legacy code. Although it is unclear how z-buffer can be the same as a 4
* channel RGBA 8bpp buffer. */
if (ibuf->z_buffer.data == (int *)ibuf->byte_buffer.data) {
info->colp = NULL;
}
}
if (ibuf->zbuf_float) {
if (ibuf->float_z_buffer.data) {
/* TODO: blend depth (not urgent). */
info->zf = ibuf->zbuf_float[y * ibuf->x + x];
info->zf = ibuf->float_z_buffer.data[y * ibuf->x + x];
info->zfp = &info->zf;
if (ibuf->zbuf_float == ibuf->rect_float) {
if (ibuf->float_z_buffer.data == ibuf->float_buffer.data) {
info->colfp = NULL;
}
}
@@ -322,8 +324,8 @@ static void sequencer_sample_apply(bContext *C, wmOperator *op, const wmEvent *e
info->colp = NULL;
info->colfp = NULL;
if (ibuf->rect) {
cp = (uchar *)(ibuf->rect + y * ibuf->x + x);
if (ibuf->byte_buffer.data) {
cp = ibuf->byte_buffer.data + 4 * (y * ibuf->x + x);
info->col[0] = cp[0];
info->col[1] = cp[1];
@@ -343,8 +345,8 @@ static void sequencer_sample_apply(bContext *C, wmOperator *op, const wmEvent *e
info->color_manage = true;
}
if (ibuf->rect_float) {
fp = (ibuf->rect_float + (ibuf->channels) * (y * ibuf->x + x));
if (ibuf->float_buffer.data) {
fp = (ibuf->float_buffer.data + (ibuf->channels) * (y * ibuf->x + x));
info->colf[0] = fp[0];
info->colf[1] = fp[1];
@@ -376,11 +376,11 @@ void Canvas::loadMap(const char *iFileName, const char *iMapName, uint iNbLevels
int h = qimg->y;
int rowbytes = w * 4;
GrayImage tmp(w, h);
char *pix;
uchar *pix;
for (y = 0; y < h; ++y) {
for (x = 0; x < w; ++x) {
pix = (char *)qimg->rect + y * rowbytes + x * 4;
pix = qimg->byte_buffer.data + y * rowbytes + x * 4;
float c = (pix[0] * 11 + pix[1] * 16 + pix[2] * 5) / 32;
tmp.setPixel(x, y, c);
}
@@ -417,7 +417,7 @@ void Canvas::loadMap(const char *iFileName, const char *iMapName, uint iNbLevels
for (x = 0; x < ow; ++x) {
int c = pyramid->pixel(x, y, i); // 255 * pyramid->pixel(x, y, i);
// soc qtmp.setPixel(x, y, qRgb(c, c, c));
pix = (char *)qtmp->rect + y * rowbytes + x * 4;
pix = qtmp->byte_buffer.data + y * rowbytes + x * 4;
pix[0] = pix[1] = pix[2] = c;
}
}
@@ -244,7 +244,7 @@ void SteerableViewMap::saveSteerableViewMap() const
// soc QImage qtmp(ow, oh, QImage::Format_RGB32);
ImBuf *ibuf = IMB_allocImBuf(ow, oh, 32, IB_rect);
int rowbytes = ow * 4;
char *pix;
uchar *pix;
for (int y = 0; y < oh; ++y) { // soc
for (int x = 0; x < ow; ++x) { // soc
@@ -255,7 +255,7 @@ void SteerableViewMap::saveSteerableViewMap() const
// int c = (int)(_imagesPyramids[i]->pixel(x, y, j));
// soc qtmp.setPixel(x, y, qRgb(c, c, c));
pix = (char *)ibuf->rect + y * rowbytes + x * 4;
pix = ibuf->byte_buffer.data + y * rowbytes + x * 4;
pix[0] = pix[1] = pix[2] = c;
}
}
+30 -4
View File
@@ -43,6 +43,8 @@
#include "../blenlib/BLI_sys_types.h"
#include "../gpu/GPU_texture.h"
#include "IMB_imbuf_types.h"
#ifdef __cplusplus
extern "C" {
#endif
@@ -130,19 +132,43 @@ bool IMB_initImBuf(
* (transferring ownership to the in imbuf).
* \attention Defined in allocimbuf.c
*/
struct ImBuf *IMB_allocFromBufferOwn(
unsigned int *rect, float *rectf, unsigned int w, unsigned int h, unsigned int channels);
struct ImBuf *IMB_allocFromBufferOwn(uint8_t *byte_buffer,
float *float_buffer,
unsigned int w,
unsigned int h,
unsigned int channels);
/**
* Create a copy of a pixel buffer and wrap it to a new ImBuf
* \attention Defined in allocimbuf.c
*/
struct ImBuf *IMB_allocFromBuffer(const unsigned int *rect,
const float *rectf,
struct ImBuf *IMB_allocFromBuffer(const uint8_t *byte_buffer,
const float *float_buffer,
unsigned int w,
unsigned int h,
unsigned int channels);
/* Assign the content of the corresponding buffer with the given data and ownership.
* The current content of the buffer is released corresponding to its ownership configuration.
*
* NOTE: Does not modify the the topology (width, height, number of channels) or the mipmaps in any
* way. */
void IMB_assign_byte_buffer(struct ImBuf *ibuf, uint8_t *buffer_data, ImBufOwnership ownership);
void IMB_assign_float_buffer(struct ImBuf *ibuf, float *buffer_data, ImBufOwnership ownership);
void IMB_assign_z_buffer(struct ImBuf *ibuf, int *buffer_data, ImBufOwnership ownership);
void IMB_assign_float_z_buffer(struct ImBuf *ibuf, float *buffer_data, ImBufOwnership ownership);
/* Make corresponding buffers available for modification.
* Is achieved by ensuring that the given ImBuf is the only owner of the underlying buffer data. */
void IMB_make_writable_byte_buffer(struct ImBuf *ibuf);
void IMB_make_writable_float_buffer(struct ImBuf *ibuf);
/* Steal the buffer data pointer: the ImBuf is no longer an owner of this data.
* NOTE: If the ImBuf does not own the data the behavior is undefined. */
uint8_t *IMB_steal_byte_buffer(struct ImBuf *ibuf);
float *IMB_steal_float_buffer(struct ImBuf *ibuf);
uint8_t *IMB_steal_encoded_buffer(struct ImBuf *ibuf);
/**
* Increase reference count to imbuf
* (to delete an imbuf you have to call freeImBuf as many times as it
+48 -11
View File
@@ -5,6 +5,8 @@
#include "DNA_vec_types.h" /* for rcti */
#include "BLI_sys_types.h"
#ifdef __cplusplus
extern "C" {
#endif
@@ -151,6 +153,42 @@ typedef enum eImBufFlags {
/** \} */
/* -------------------------------------------------------------------- */
/** \name Imbuf buffer storage
* \{ */
/* Specialization of an ownership whenever a bare pointer is provided to the ImBuf buffers
* assignment API. */
typedef enum ImBufOwnership {
/* The ImBuf simply shares pointer with data owned by someone else, and will not perform any
* memory management when the ImBuf frees the buffer. */
IB_DO_NOT_TAKE_OWNERSHIP = 0,
/* The ImBuf takes ownership of the buffer data, and will use MEM_freeN() to free this memory
* when the ImBuf needs to free the data. */
IB_TAKE_OWNERSHIP = 1,
} ImBufOwnership;
/* Different storage specialization. */
/* TODO(sergey): Once everything is C++ replace with a template. */
typedef struct ImBufIntBuffer {
int *data;
ImBufOwnership ownership;
} ImBufIntBuffer;
typedef struct ImBufByteBuffer {
uint8_t *data;
ImBufOwnership ownership;
} ImBufByteBuffer;
typedef struct ImBufFloatBuffer {
float *data;
ImBufOwnership ownership;
} ImBufFloatBuffer;
/** \} */
/* -------------------------------------------------------------------- */
/** \name Image Buffer
* \{ */
@@ -171,8 +209,6 @@ typedef struct ImBuf {
/* flags */
/** Controls which components should exist. */
int flags;
/** what is malloced internal, and can be freed */
int mall;
/* pixels */
@@ -180,23 +216,24 @@ typedef struct ImBuf {
* - color space defaults to `sRGB`.
* - alpha defaults to 'straight'.
*/
unsigned int *rect;
ImBufByteBuffer byte_buffer;
/** Image pixel buffer (float representation):
* - color space defaults to 'linear' (`rec709`).
* - alpha defaults to 'premul'.
* \note May need gamma correction to `sRGB` when generating 8bit representations.
* \note Formats that support higher more than 8 but channels load as floats.
*/
float *rect_float;
ImBufFloatBuffer float_buffer;
/** Resolution in pixels per meter. Multiply by `0.0254` for DPI. */
double ppm[2];
/* zbuffer */
/** z buffer data, original zbuffer */
int *zbuf;
ImBufIntBuffer z_buffer;
/** z buffer data, camera coordinates */
float *zbuf_float;
ImBufFloatBuffer float_z_buffer;
/* parameters used by conversion between byte and float */
/** random dither value, for conversion from float -> byte rect */
@@ -231,11 +268,11 @@ typedef struct ImBuf {
/* some parameters to pass along for packing images */
/** Compressed image only used with PNG and EXR currently. */
unsigned char *encodedbuffer;
/** Size of data written to `encodedbuffer`. */
unsigned int encodedsize;
/** Size of `encodedbuffer` */
unsigned int encodedbuffersize;
ImBufByteBuffer encoded_buffer;
/** Size of data written to `encoded_buffer`. */
unsigned int encoded_size;
/** Size of `encoded_buffer` */
unsigned int encoded_buffer_size;
/* color management */
/** color space of byte buffer */
+4 -2
View File
@@ -8,14 +8,16 @@
#pragma once
#include "BLI_sys_types.h"
struct ImBuf;
void imb_filterx(struct ImBuf *ibuf);
void IMB_premultiply_rect(unsigned int *rect, char planes, int w, int h);
void IMB_premultiply_rect(uint8_t *rect, char planes, int w, int h);
void IMB_premultiply_rect_float(float *rect_float, int channels, int w, int h);
void IMB_unpremultiply_rect(unsigned int *rect, char planes, int w, int h);
void IMB_unpremultiply_rect(uint8_t *rect, char planes, int w, int h);
void IMB_unpremultiply_rect_float(float *rect_float, int channels, int w, int h);
/**
+276 -141
View File
@@ -61,6 +61,89 @@ void imb_mmap_unlock(void)
}
#endif
/* Free the specified buffer storage, freeing memory when needed and restoring the state of the
* buffer to its defaults. */
template<class BufferType> static void imb_free_buffer(BufferType &buffer)
{
if (buffer.data) {
switch (buffer.ownership) {
case IB_DO_NOT_TAKE_OWNERSHIP:
break;
case IB_TAKE_OWNERSHIP:
MEM_freeN(buffer.data);
break;
}
}
/* Reset buffer to defaults. */
buffer.data = nullptr;
buffer.ownership = IB_DO_NOT_TAKE_OWNERSHIP;
}
/* Allocate pixel storage of the given buffer. The buffer owns the allocated memory.
* Returns true of allocation succeeded, false otherwise. */
template<class BufferType>
bool imb_alloc_buffer(
BufferType &buffer, const uint x, const uint y, const uint channels, const size_t type_size)
{
buffer.data = static_cast<decltype(BufferType::data)>(
imb_alloc_pixels(x, y, channels, type_size, __func__));
if (!buffer.data) {
return false;
}
buffer.ownership = IB_TAKE_OWNERSHIP;
return true;
}
/* Make the buffer available for modification.
* Is achieved by ensuring that the buffer is the only owner of its data. */
template<class BufferType> void imb_make_writeable_buffer(BufferType &buffer)
{
if (!buffer.data) {
return;
}
switch (buffer.ownership) {
case IB_DO_NOT_TAKE_OWNERSHIP:
buffer.data = static_cast<decltype(BufferType::data)>(MEM_dupallocN(buffer.data));
buffer.ownership = IB_TAKE_OWNERSHIP;
break;
case IB_TAKE_OWNERSHIP:
break;
}
}
template<class BufferType>
auto imb_steal_buffer_data(BufferType &buffer) -> decltype(BufferType::data)
{
if (!buffer.data) {
return nullptr;
}
switch (buffer.ownership) {
case IB_DO_NOT_TAKE_OWNERSHIP:
BLI_assert(!"Unexpected behavior: stealing non-owned data pointer");
return nullptr;
case IB_TAKE_OWNERSHIP: {
decltype(BufferType::data) data = buffer.data;
buffer.data = nullptr;
buffer.ownership = IB_DO_NOT_TAKE_OWNERSHIP;
return data;
}
}
BLI_assert_unreachable();
return nullptr;
}
void imb_freemipmapImBuf(ImBuf *ibuf)
{
int a;
@@ -83,15 +166,11 @@ void imb_freerectfloatImBuf(ImBuf *ibuf)
return;
}
if (ibuf->rect_float && (ibuf->mall & IB_rectfloat)) {
MEM_freeN(ibuf->rect_float);
ibuf->rect_float = nullptr;
}
imb_free_buffer(ibuf->float_buffer);
imb_freemipmapImBuf(ibuf);
ibuf->rect_float = nullptr;
ibuf->mall &= ~IB_rectfloat;
ibuf->flags &= ~IB_rectfloat;
}
void imb_freerectImBuf(ImBuf *ibuf)
@@ -100,14 +179,11 @@ void imb_freerectImBuf(ImBuf *ibuf)
return;
}
if (ibuf->rect && (ibuf->mall & IB_rect)) {
MEM_freeN(ibuf->rect);
}
ibuf->rect = nullptr;
imb_free_buffer(ibuf->byte_buffer);
imb_freemipmapImBuf(ibuf);
ibuf->mall &= ~IB_rect;
ibuf->flags &= ~IB_rect;
}
static void freeencodedbufferImBuf(ImBuf *ibuf)
@@ -116,14 +192,12 @@ static void freeencodedbufferImBuf(ImBuf *ibuf)
return;
}
if (ibuf->encodedbuffer && (ibuf->mall & IB_mem)) {
MEM_freeN(ibuf->encodedbuffer);
}
imb_free_buffer(ibuf->encoded_buffer);
ibuf->encodedbuffer = nullptr;
ibuf->encodedbuffersize = 0;
ibuf->encodedsize = 0;
ibuf->mall &= ~IB_mem;
ibuf->encoded_buffer_size = 0;
ibuf->encoded_size = 0;
ibuf->flags &= ~IB_mem;
}
void IMB_freezbufImBuf(ImBuf *ibuf)
@@ -132,12 +206,9 @@ void IMB_freezbufImBuf(ImBuf *ibuf)
return;
}
if (ibuf->zbuf && (ibuf->mall & IB_zbuf)) {
MEM_freeN(ibuf->zbuf);
}
imb_free_buffer(ibuf->z_buffer);
ibuf->zbuf = nullptr;
ibuf->mall &= ~IB_zbuf;
ibuf->flags &= ~IB_zbuf;
}
void IMB_freezbuffloatImBuf(ImBuf *ibuf)
@@ -146,12 +217,9 @@ void IMB_freezbuffloatImBuf(ImBuf *ibuf)
return;
}
if (ibuf->zbuf_float && (ibuf->mall & IB_zbuffloat)) {
MEM_freeN(ibuf->zbuf_float);
}
imb_free_buffer(ibuf->float_z_buffer);
ibuf->zbuf_float = nullptr;
ibuf->mall &= ~IB_zbuffloat;
ibuf->flags &= ~IB_zbuffloat;
}
void imb_freerectImbuf_all(ImBuf *ibuf)
@@ -234,14 +302,12 @@ bool addzbufImBuf(ImBuf *ibuf)
IMB_freezbufImBuf(ibuf);
if ((ibuf->zbuf = static_cast<int *>(
imb_alloc_pixels(ibuf->x, ibuf->y, 1, sizeof(uint), __func__))))
{
ibuf->mall |= IB_zbuf;
ibuf->flags |= IB_zbuf;
return true;
if (!imb_alloc_buffer(ibuf->z_buffer, ibuf->x, ibuf->y, 1, sizeof(uint))) {
return false;
}
ibuf->flags |= IB_zbuf;
return false;
}
@@ -253,15 +319,13 @@ bool addzbuffloatImBuf(ImBuf *ibuf)
IMB_freezbuffloatImBuf(ibuf);
if ((ibuf->zbuf_float = static_cast<float *>(
imb_alloc_pixels(ibuf->x, ibuf->y, 1, sizeof(float), __func__))))
{
ibuf->mall |= IB_zbuffloat;
ibuf->flags |= IB_zbuffloat;
return true;
if (!imb_alloc_buffer(ibuf->float_z_buffer, ibuf->x, ibuf->y, 1, sizeof(float))) {
return false;
}
return false;
ibuf->flags |= IB_zbuffloat;
return true;
}
bool imb_addencodedbufferImBuf(ImBuf *ibuf)
@@ -272,61 +336,52 @@ bool imb_addencodedbufferImBuf(ImBuf *ibuf)
freeencodedbufferImBuf(ibuf);
if (ibuf->encodedbuffersize == 0) {
ibuf->encodedbuffersize = 10000;
if (ibuf->encoded_buffer_size == 0) {
ibuf->encoded_buffer_size = 10000;
}
ibuf->encodedsize = 0;
ibuf->encoded_size = 0;
if ((ibuf->encodedbuffer = static_cast<uchar *>(MEM_mallocN(ibuf->encodedbuffersize, __func__))))
{
ibuf->mall |= IB_mem;
ibuf->flags |= IB_mem;
return true;
if (!imb_alloc_buffer(ibuf->encoded_buffer, ibuf->encoded_buffer_size, 1, 1, sizeof(uint8_t))) {
return false;
}
return false;
ibuf->flags |= IB_mem;
return true;
}
bool imb_enlargeencodedbufferImBuf(ImBuf *ibuf)
{
uint newsize, encodedsize;
void *newbuffer;
if (ibuf == nullptr) {
return false;
}
if (ibuf->encodedbuffersize < ibuf->encodedsize) {
if (ibuf->encoded_buffer_size < ibuf->encoded_size) {
printf("%s: error in parameters\n", __func__);
return false;
}
newsize = 2 * ibuf->encodedbuffersize;
uint newsize = 2 * ibuf->encoded_buffer_size;
if (newsize < 10000) {
newsize = 10000;
}
newbuffer = MEM_mallocN(newsize, __func__);
if (newbuffer == nullptr) {
ImBufByteBuffer new_buffer;
if (!imb_alloc_buffer(new_buffer, newsize, 1, 1, sizeof(uint8_t))) {
return false;
}
if (ibuf->encodedbuffer) {
memcpy(newbuffer, ibuf->encodedbuffer, ibuf->encodedsize);
if (ibuf->encoded_buffer.data) {
memcpy(new_buffer.data, ibuf->encoded_buffer.data, ibuf->encoded_size);
}
else {
ibuf->encodedsize = 0;
ibuf->encoded_size = 0;
}
encodedsize = ibuf->encodedsize;
imb_free_buffer(ibuf->encoded_buffer);
freeencodedbufferImBuf(ibuf);
ibuf->encodedbuffersize = newsize;
ibuf->encodedsize = encodedsize;
ibuf->encodedbuffer = static_cast<uchar *>(newbuffer);
ibuf->mall |= IB_mem;
ibuf->encoded_buffer_size = newsize;
ibuf->flags |= IB_mem;
return true;
@@ -350,20 +405,21 @@ bool imb_addrectfloatImBuf(ImBuf *ibuf, const uint channels)
return false;
}
if (ibuf->rect_float) {
/* NOTE: Follows the historical code.
* Is unclear if it is desired or not to free mipmaps. If mipmaps are to be preserved a simple
* `imb_free_buffer(ibuf->float_buffer)` can be used instead. */
if (ibuf->float_buffer.data) {
imb_freerectfloatImBuf(ibuf); /* frees mipmap too, hrm */
}
ibuf->channels = channels;
if ((ibuf->rect_float = static_cast<float *>(
imb_alloc_pixels(ibuf->x, ibuf->y, channels, sizeof(float), __func__))))
{
ibuf->mall |= IB_rectfloat;
ibuf->flags |= IB_rectfloat;
return true;
if (!imb_alloc_buffer(ibuf->float_buffer, ibuf->x, ibuf->y, channels, sizeof(float))) {
return false;
}
return false;
ibuf->channels = channels;
ibuf->flags |= IB_rectfloat;
return true;
}
bool imb_addrectImBuf(ImBuf *ibuf)
@@ -376,63 +432,141 @@ bool imb_addrectImBuf(ImBuf *ibuf)
/* Don't call imb_freerectImBuf, it frees mipmaps,
* this call is used only too give float buffers display. */
if (ibuf->rect && (ibuf->mall & IB_rect)) {
MEM_freeN(ibuf->rect);
}
ibuf->rect = nullptr;
imb_free_buffer(ibuf->byte_buffer);
if ((ibuf->rect = static_cast<uint *>(
imb_alloc_pixels(ibuf->x, ibuf->y, 4, sizeof(uchar), __func__))))
{
ibuf->mall |= IB_rect;
ibuf->flags |= IB_rect;
if (ibuf->planes > 32) {
return addzbufImBuf(ibuf);
}
return true;
if (!imb_alloc_buffer(ibuf->byte_buffer, ibuf->x, ibuf->y, 4, sizeof(uint8_t))) {
return false;
}
return false;
ibuf->flags |= IB_rect;
if (ibuf->planes > 32) {
return addzbufImBuf(ibuf);
}
return true;
}
struct ImBuf *IMB_allocFromBufferOwn(uint *rect, float *rectf, uint w, uint h, uint channels)
uint8_t *IMB_steal_byte_buffer(ImBuf *ibuf)
{
ImBuf *ibuf = nullptr;
uint8_t *data = imb_steal_buffer_data(ibuf->byte_buffer);
ibuf->flags &= ~IB_rect;
return data;
}
if (!(rect || rectf)) {
float *IMB_steal_float_buffer(ImBuf *ibuf)
{
float *data = imb_steal_buffer_data(ibuf->float_buffer);
ibuf->flags &= ~IB_rectfloat;
return data;
}
uint8_t *IMB_steal_encoded_buffer(ImBuf *ibuf)
{
uint8_t *data = imb_steal_buffer_data(ibuf->encoded_buffer);
ibuf->encoded_size = 0;
ibuf->encoded_buffer_size = 0;
ibuf->flags &= ~IB_mem;
return data;
}
void IMB_make_writable_byte_buffer(ImBuf *ibuf)
{
imb_make_writeable_buffer(ibuf->byte_buffer);
}
void IMB_make_writable_float_buffer(ImBuf *ibuf)
{
imb_make_writeable_buffer(ibuf->float_buffer);
}
void IMB_assign_byte_buffer(ImBuf *ibuf, uint8_t *buffer_data, const ImBufOwnership ownership)
{
imb_free_buffer(ibuf->byte_buffer);
ibuf->flags &= ~IB_rect;
if (buffer_data) {
ibuf->byte_buffer.data = buffer_data;
ibuf->byte_buffer.ownership = ownership;
ibuf->flags |= IB_rect;
}
}
void IMB_assign_float_buffer(ImBuf *ibuf, float *buffer_data, const ImBufOwnership ownership)
{
imb_free_buffer(ibuf->float_buffer);
ibuf->flags &= ~IB_rectfloat;
if (buffer_data) {
ibuf->float_buffer.data = buffer_data;
ibuf->float_buffer.ownership = ownership;
ibuf->flags |= IB_rectfloat;
}
}
void IMB_assign_z_buffer(struct ImBuf *ibuf, int *buffer_data, ImBufOwnership ownership)
{
imb_free_buffer(ibuf->z_buffer);
ibuf->flags &= ~IB_zbuf;
if (buffer_data) {
ibuf->z_buffer.ownership = ownership;
ibuf->z_buffer.data = buffer_data;
ibuf->flags |= IB_zbuf;
}
}
void IMB_assign_float_z_buffer(struct ImBuf *ibuf, float *buffer_data, ImBufOwnership ownership)
{
imb_free_buffer(ibuf->float_z_buffer);
ibuf->flags &= ~IB_zbuffloat;
if (buffer_data) {
ibuf->float_z_buffer.ownership = ownership;
ibuf->float_z_buffer.data = buffer_data;
ibuf->flags |= IB_zbuffloat;
}
}
ImBuf *IMB_allocFromBufferOwn(
uint8_t *byte_buffer, float *float_buffer, uint w, uint h, uint channels)
{
if (!(byte_buffer || float_buffer)) {
return nullptr;
}
ibuf = IMB_allocImBuf(w, h, 32, 0);
ImBuf *ibuf = IMB_allocImBuf(w, h, 32, 0);
ibuf->channels = channels;
/* Avoid #MEM_dupallocN since the buffers might not be allocated using guarded-allocation. */
if (rectf) {
BLI_assert(MEM_allocN_len(rectf) == sizeof(float[4]) * w * h);
ibuf->rect_float = rectf;
ibuf->flags |= IB_rectfloat;
ibuf->mall |= IB_rectfloat;
if (float_buffer) {
/* TODO(sergey): The 4 channels is the historical code. Should probably be `channels`, but
* needs a dedicated investigation. */
BLI_assert(MEM_allocN_len(float_buffer) == sizeof(float[4]) * w * h);
IMB_assign_float_buffer(ibuf, float_buffer, IB_TAKE_OWNERSHIP);
}
if (rect) {
BLI_assert(MEM_allocN_len(rect) == sizeof(uchar[4]) * w * h);
ibuf->rect = rect;
ibuf->flags |= IB_rect;
ibuf->mall |= IB_rect;
if (byte_buffer) {
BLI_assert(MEM_allocN_len(byte_buffer) == sizeof(uint8_t[4]) * w * h);
IMB_assign_byte_buffer(ibuf, byte_buffer, IB_TAKE_OWNERSHIP);
}
return ibuf;
}
struct ImBuf *IMB_allocFromBuffer(
const uint *rect, const float *rectf, uint w, uint h, uint channels)
const uint8_t *byte_buffer, const float *float_buffer, uint w, uint h, uint channels)
{
ImBuf *ibuf = nullptr;
if (!(rect || rectf)) {
if (!(byte_buffer || float_buffer)) {
return nullptr;
}
@@ -440,22 +574,20 @@ struct ImBuf *IMB_allocFromBuffer(
ibuf->channels = channels;
/* Avoid #MEM_dupallocN since the buffers might not be allocated using guarded-allocation. */
if (rectf) {
const size_t size = sizeof(float[4]) * w * h;
ibuf->rect_float = static_cast<float *>(MEM_mallocN(size, __func__));
memcpy(ibuf->rect_float, rectf, size);
/* NOTE: Avoid #MEM_dupallocN since the buffers might not be allocated using guarded-allocation.
*/
if (float_buffer) {
/* TODO(sergey): The 4 channels is the historical code. Should probably be `channels`, but
* needs a dedicated investigation. */
imb_alloc_buffer(ibuf->float_buffer, w, h, 4, sizeof(float));
ibuf->flags |= IB_rectfloat;
ibuf->mall |= IB_rectfloat;
memcpy(ibuf->float_buffer.data, float_buffer, sizeof(float[4]) * w * h);
}
if (rect) {
const size_t size = sizeof(uchar[4]) * w * h;
ibuf->rect = static_cast<uint *>(MEM_mallocN(size, __func__));
memcpy(ibuf->rect, rect, size);
ibuf->flags |= IB_rect;
ibuf->mall |= IB_rect;
if (byte_buffer) {
imb_alloc_buffer(ibuf->byte_buffer, w, h, 4, sizeof(uint8_t));
memcpy(ibuf->byte_buffer.data, byte_buffer, sizeof(uint8_t[4]) * w * h);
}
return ibuf;
@@ -530,16 +662,18 @@ ImBuf *IMB_dupImBuf(const ImBuf *ibuf1)
return nullptr;
}
if (ibuf1->rect) {
/* TODO(sergey): Use implicit sharing. */
if (ibuf1->byte_buffer.data) {
flags |= IB_rect;
}
if (ibuf1->rect_float) {
if (ibuf1->float_buffer.data) {
flags |= IB_rectfloat;
}
if (ibuf1->zbuf) {
if (ibuf1->z_buffer.data) {
flags |= IB_zbuf;
}
if (ibuf1->zbuf_float) {
if (ibuf1->float_z_buffer.data) {
flags |= IB_zbuffloat;
}
@@ -552,47 +686,48 @@ ImBuf *IMB_dupImBuf(const ImBuf *ibuf1)
}
if (flags & IB_rect) {
memcpy(ibuf2->rect, ibuf1->rect, size_t(x) * y * sizeof(int));
memcpy(ibuf2->byte_buffer.data, ibuf1->byte_buffer.data, size_t(x) * y * 4 * sizeof(uint8_t));
}
if (flags & IB_rectfloat) {
memcpy(ibuf2->rect_float, ibuf1->rect_float, size_t(ibuf1->channels) * x * y * sizeof(float));
memcpy(ibuf2->float_buffer.data,
ibuf1->float_buffer.data,
size_t(ibuf1->channels) * x * y * sizeof(float));
}
if (flags & IB_zbuf) {
memcpy(ibuf2->zbuf, ibuf1->zbuf, size_t(x) * y * sizeof(int));
memcpy(ibuf2->z_buffer.data, ibuf1->z_buffer.data, size_t(x) * y * sizeof(int));
}
if (flags & IB_zbuffloat) {
memcpy(ibuf2->zbuf_float, ibuf1->zbuf_float, size_t(x) * y * sizeof(float));
memcpy(ibuf2->float_buffer.data, ibuf1->float_buffer.data, size_t(x) * y * sizeof(float));
}
if (ibuf1->encodedbuffer) {
ibuf2->encodedbuffersize = ibuf1->encodedbuffersize;
if (ibuf1->encoded_buffer.data) {
ibuf2->encoded_buffer_size = ibuf1->encoded_buffer_size;
if (imb_addencodedbufferImBuf(ibuf2) == false) {
IMB_freeImBuf(ibuf2);
return nullptr;
}
memcpy(ibuf2->encodedbuffer, ibuf1->encodedbuffer, ibuf1->encodedsize);
memcpy(ibuf2->encoded_buffer.data, ibuf1->encoded_buffer.data, ibuf1->encoded_size);
}
/* silly trick to copy the entire contents of ibuf1 struct over to ibuf */
tbuf = *ibuf1;
/* fix pointers */
tbuf.rect = ibuf2->rect;
tbuf.rect_float = ibuf2->rect_float;
tbuf.encodedbuffer = ibuf2->encodedbuffer;
tbuf.zbuf = ibuf2->zbuf;
tbuf.zbuf_float = ibuf2->zbuf_float;
tbuf.byte_buffer = ibuf2->byte_buffer;
tbuf.float_buffer = ibuf2->float_buffer;
tbuf.encoded_buffer = ibuf2->encoded_buffer;
tbuf.z_buffer = ibuf2->z_buffer;
tbuf.float_z_buffer = ibuf2->float_z_buffer;
for (a = 0; a < IMB_MIPMAP_LEVELS; a++) {
tbuf.mipmap[a] = nullptr;
}
tbuf.dds_data.data = nullptr;
/* set malloc flag */
tbuf.mall = ibuf2->mall;
tbuf.refcounter = 0;
/* for now don't duplicate metadata */
@@ -618,11 +753,11 @@ size_t IMB_get_size_in_memory(ImBuf *ibuf)
size += sizeof(ImBuf);
if (ibuf->rect) {
if (ibuf->byte_buffer.data) {
channel_size += sizeof(char);
}
if (ibuf->rect_float) {
if (ibuf->float_buffer.data) {
channel_size += sizeof(float);
}
+15 -5
View File
@@ -482,7 +482,9 @@ static ImBuf *avi_fetchibuf(struct anim *anim, int position)
}
for (y = 0; y < anim->y; y++) {
memcpy(&(ibuf->rect)[((anim->y - y) - 1) * anim->x], &tmp[y * anim->x], anim->x * 4);
memcpy(&(ibuf->byte_buffer.data)[((anim->y - y) - 1) * anim->x],
&tmp[y * anim->x],
anim->x * 4);
}
MEM_freeN(tmp);
@@ -909,8 +911,14 @@ static void ffmpeg_postprocess(struct anim *anim, AVFrame *input)
const int src_linesize[4] = {-anim->pFrameRGB->linesize[0], 0, 0, 0};
int dst_size = av_image_get_buffer_size(
AVPixelFormat(anim->pFrameRGB->format), anim->pFrameRGB->width, anim->pFrameRGB->height, 1);
av_image_copy_to_buffer(
(uint8_t *)ibuf->rect, dst_size, src, src_linesize, AV_PIX_FMT_RGBA, anim->x, anim->y, 1);
av_image_copy_to_buffer((uint8_t *)ibuf->byte_buffer.data,
dst_size,
src,
src_linesize,
AV_PIX_FMT_RGBA,
anim->x,
anim->y,
1);
if (filter_y) {
IMB_filtery(ibuf);
}
@@ -1459,9 +1467,11 @@ static ImBuf *ffmpeg_fetchibuf(struct anim *anim, int position, IMB_Timecode_Typ
}
anim->cur_frame_final = IMB_allocImBuf(anim->x, anim->y, planes, 0);
anim->cur_frame_final->rect = static_cast<uint *>(
/* Allocate the storage explicitly to ensure the memory is aligned. */
uint8_t *buffer_data = static_cast<uint8_t *>(
MEM_mallocN_aligned(size_t(4) * anim->x * anim->y, 32, "ffmpeg ibuf"));
anim->cur_frame_final->mall |= IB_rect;
IMB_assign_byte_buffer(anim->cur_frame_final, buffer_data, IB_TAKE_OWNERSHIP);
anim->cur_frame_final->rect_colorspace = colormanage_colorspace_get_named(anim->colorspace);
@@ -48,7 +48,7 @@ static struct ImBuf *imb_load_dpx_cineon(
}
if (!(flags & IB_test)) {
if (logImageGetDataRGBA(image, ibuf->rect_float, 1) != 0) {
if (logImageGetDataRGBA(image, ibuf->float_buffer.data, 1) != 0) {
logImageClose(image);
IMB_freeImBuf(ibuf);
return nullptr;
@@ -117,7 +117,7 @@ static int imb_save_dpx_cineon(ImBuf *ibuf, const char *filepath, int use_cineon
return 0;
}
if (ibuf->rect_float != nullptr && bitspersample != 8) {
if (ibuf->float_buffer.data != nullptr && bitspersample != 8) {
/* Don't use the float buffer to save 8 BPP picture to prevent color banding
* (there's no dithering algorithm behind the #logImageSetDataRGBA function). */
@@ -126,7 +126,7 @@ static int imb_save_dpx_cineon(ImBuf *ibuf, const char *filepath, int use_cineon
for (y = 0; y < ibuf->y; y++) {
float *dst_ptr = fbuf + 4 * ((ibuf->y - y - 1) * ibuf->x);
float *src_ptr = ibuf->rect_float + 4 * (y * ibuf->x);
float *src_ptr = ibuf->float_buffer.data + 4 * (y * ibuf->x);
memcpy(dst_ptr, src_ptr, 4 * ibuf->x * sizeof(float));
}
@@ -136,7 +136,7 @@ static int imb_save_dpx_cineon(ImBuf *ibuf, const char *filepath, int use_cineon
MEM_freeN(fbuf);
}
else {
if (ibuf->rect == nullptr) {
if (ibuf->byte_buffer.data == nullptr) {
IMB_rect_from_float(ibuf);
}
@@ -150,7 +150,7 @@ static int imb_save_dpx_cineon(ImBuf *ibuf, const char *filepath, int use_cineon
for (y = 0; y < ibuf->y; y++) {
for (x = 0; x < ibuf->x; x++) {
fbuf_ptr = fbuf + 4 * ((ibuf->y - y - 1) * ibuf->x + x);
rect_ptr = (uchar *)ibuf->rect + 4 * (y * ibuf->x + x);
rect_ptr = ibuf->byte_buffer.data + 4 * (y * ibuf->x + x);
fbuf_ptr[0] = float(rect_ptr[0]) / 255.0f;
fbuf_ptr[1] = float(rect_ptr[1]) / 255.0f;
fbuf_ptr[2] = float(rect_ptr[2]) / 255.0f;
+40 -50
View File
@@ -385,7 +385,7 @@ static uchar *colormanage_cache_get(ImBuf *ibuf,
return nullptr;
}
return (uchar *)cache_ibuf->rect;
return (uchar *)cache_ibuf->byte_buffer.data;
}
return nullptr;
@@ -412,10 +412,7 @@ static void colormanage_cache_put(ImBuf *ibuf,
/* buffer itself */
cache_ibuf = IMB_allocImBuf(ibuf->x, ibuf->y, ibuf->planes, 0);
cache_ibuf->rect = (uint *)display_buffer;
cache_ibuf->mall |= IB_rect;
cache_ibuf->flags |= IB_rect;
IMB_assign_byte_buffer(cache_ibuf, display_buffer, IB_TAKE_OWNERSHIP);
/* Store data which is needed to check whether cached buffer
* could be used for color managed display settings. */
@@ -1050,15 +1047,15 @@ void colormanage_imbuf_make_linear(ImBuf *ibuf, const char *from_colorspace)
return;
}
if (ibuf->rect_float) {
if (ibuf->float_buffer.data) {
const char *to_colorspace = global_role_scene_linear;
const bool predivide = IMB_alpha_affects_rgb(ibuf);
if (ibuf->rect) {
if (ibuf->byte_buffer.data) {
imb_freerectImBuf(ibuf);
}
IMB_colormanagement_transform(ibuf->rect_float,
IMB_colormanagement_transform(ibuf->float_buffer.data,
ibuf->x,
ibuf->y,
ibuf->channels,
@@ -1751,7 +1748,7 @@ static void colormanage_display_buffer_process_ex(
* this would save byte -> float -> byte conversions making display buffer
* computation noticeable faster
*/
if (ibuf->rect_float == nullptr && ibuf->rect_colorspace) {
if (ibuf->float_buffer.data == nullptr && ibuf->rect_colorspace) {
skip_transform = is_ibuf_rect_in_display_space(ibuf, view_settings, display_settings);
}
@@ -1760,8 +1757,8 @@ static void colormanage_display_buffer_process_ex(
}
display_buffer_apply_threaded(ibuf,
ibuf->rect_float,
(uchar *)ibuf->rect,
ibuf->float_buffer.data,
ibuf->byte_buffer.data,
display_buffer,
display_buffer_byte,
cm_processor);
@@ -2193,12 +2190,13 @@ void IMB_colormanagement_imbuf_to_byte_texture(uchar *out_buffer,
{
/* Byte buffer storage, only for sRGB, scene linear and data texture since other
* color space conversions can't be done on the GPU. */
BLI_assert(ibuf->rect && ibuf->rect_float == nullptr);
BLI_assert(ibuf->byte_buffer.data);
BLI_assert(ibuf->float_buffer.data == nullptr);
BLI_assert(IMB_colormanagement_space_is_srgb(ibuf->rect_colorspace) ||
IMB_colormanagement_space_is_scene_linear(ibuf->rect_colorspace) ||
IMB_colormanagement_space_is_data(ibuf->rect_colorspace));
const uchar *in_buffer = (uchar *)ibuf->rect;
const uchar *in_buffer = ibuf->byte_buffer.data;
const bool use_premultiply = IMB_alpha_affects_rgb(ibuf) && store_premultiplied;
for (int y = 0; y < height; y++) {
@@ -2275,9 +2273,9 @@ void IMB_colormanagement_imbuf_to_float_texture(float *out_buffer,
{
/* Float texture are stored in scene linear color space, with premultiplied
* alpha depending on the image alpha mode. */
if (ibuf->rect_float) {
if (ibuf->float_buffer.data) {
/* Float source buffer. */
const float *in_buffer = ibuf->rect_float;
const float *in_buffer = ibuf->float_buffer.data;
const int in_channels = ibuf->channels;
const bool use_unpremultiply = IMB_alpha_affects_rgb(ibuf) && !store_premultiplied;
@@ -2320,7 +2318,7 @@ void IMB_colormanagement_imbuf_to_float_texture(float *out_buffer,
}
else {
/* Byte source buffer. */
const uchar *in_buffer = (uchar *)ibuf->rect;
const uchar *in_buffer = ibuf->byte_buffer.data;
const bool use_premultiply = IMB_alpha_affects_rgb(ibuf) && store_premultiplied;
OCIO_ConstCPUProcessorRcPtr *processor = (ibuf->rect_colorspace) ?
@@ -2458,12 +2456,12 @@ static void colormanagement_imbuf_make_display_space(
const ColorManagedDisplaySettings *display_settings,
bool make_byte)
{
if (!ibuf->rect && make_byte) {
if (!ibuf->byte_buffer.data && make_byte) {
imb_addrectImBuf(ibuf);
}
colormanage_display_buffer_process_ex(
ibuf, ibuf->rect_float, (uchar *)ibuf->rect, view_settings, display_settings);
ibuf, ibuf->float_buffer.data, ibuf->byte_buffer.data, view_settings, display_settings);
}
void IMB_colormanagement_imbuf_make_display_space(
@@ -2491,15 +2489,8 @@ static ImBuf *imbuf_ensure_editable(ImBuf *ibuf, ImBuf *colormanaged_ibuf, bool
/* Render pipeline is constructing image buffer itself,
* but it's re-using byte and float buffers from render result make copy of this buffers
* here sine this buffers would be transformed to other color space here. */
if (ibuf->rect && (ibuf->mall & IB_rect) == 0) {
ibuf->rect = static_cast<uint *>(MEM_dupallocN(ibuf->rect));
ibuf->mall |= IB_rect;
}
if (ibuf->rect_float && (ibuf->mall & IB_rectfloat) == 0) {
ibuf->rect_float = static_cast<float *>(MEM_dupallocN(ibuf->rect_float));
ibuf->mall |= IB_rectfloat;
}
IMB_make_writable_byte_buffer(ibuf);
IMB_make_writable_float_buffer(ibuf);
return ibuf;
}
@@ -2512,7 +2503,7 @@ ImBuf *IMB_colormanagement_imbuf_for_write(ImBuf *ibuf,
ImBuf *colormanaged_ibuf = ibuf;
/* Update byte buffer if exists but invalid. */
if (ibuf->rect_float && ibuf->rect &&
if (ibuf->float_buffer.data && ibuf->byte_buffer.data &&
(ibuf->userflags & (IB_DISPLAY_BUFFER_INVALID | IB_RECT_INVALID)) != 0)
{
IMB_rect_from_float(ibuf);
@@ -2545,14 +2536,14 @@ ImBuf *IMB_colormanagement_imbuf_for_write(ImBuf *ibuf,
colormanaged_ibuf = imbuf_ensure_editable(ibuf, colormanaged_ibuf, allocate_result);
if (colormanaged_ibuf->rect_float && colormanaged_ibuf->channels == 4) {
if (colormanaged_ibuf->float_buffer.data && colormanaged_ibuf->channels == 4) {
IMB_alpha_under_color_float(
colormanaged_ibuf->rect_float, colormanaged_ibuf->x, colormanaged_ibuf->y, color);
colormanaged_ibuf->float_buffer.data, colormanaged_ibuf->x, colormanaged_ibuf->y, color);
}
if (colormanaged_ibuf->rect) {
if (colormanaged_ibuf->byte_buffer.data) {
IMB_alpha_under_color_byte(
(uchar *)colormanaged_ibuf->rect, colormanaged_ibuf->x, colormanaged_ibuf->y, color);
colormanaged_ibuf->byte_buffer.data, colormanaged_ibuf->x, colormanaged_ibuf->y, color);
}
}
@@ -2565,7 +2556,7 @@ ImBuf *IMB_colormanagement_imbuf_for_write(ImBuf *ibuf,
&image_format->display_settings,
byte_output);
if (colormanaged_ibuf->rect_float) {
if (colormanaged_ibuf->float_buffer.data) {
/* Float buffer isn't linear anymore,
* image format write callback should check for this flag and assume
* no space conversion should happen if ibuf->float_colorspace != nullptr. */
@@ -2580,20 +2571,19 @@ ImBuf *IMB_colormanagement_imbuf_for_write(ImBuf *ibuf,
/* Linear render or regular file output: conversion between two color spaces. */
/* Detect which color space we need to convert between. */
const char *from_colorspace = (ibuf->rect_float && !(byte_output && ibuf->rect)) ?
/* From float buffer. */
(ibuf->float_colorspace) ? ibuf->float_colorspace->name :
global_role_scene_linear :
/* From byte buffer. */
(ibuf->rect_colorspace) ? ibuf->rect_colorspace->name :
global_role_default_byte;
const char *from_colorspace =
(ibuf->float_buffer.data && !(byte_output && ibuf->byte_buffer.data)) ?
/* From float buffer. */
(ibuf->float_colorspace) ? ibuf->float_colorspace->name : global_role_scene_linear :
/* From byte buffer. */
(ibuf->rect_colorspace) ? ibuf->rect_colorspace->name : global_role_default_byte;
const char *to_colorspace = image_format->linear_colorspace_settings.name;
/* TODO: can we check with OCIO if color spaces are the same but have different names? */
if (to_colorspace[0] == '\0' || STREQ(from_colorspace, to_colorspace)) {
/* No conversion needed, but may still need to allocate byte buffer for output. */
if (byte_output && !ibuf->rect) {
if (byte_output && !ibuf->byte_buffer.data) {
ibuf->rect_colorspace = ibuf->float_colorspace;
IMB_rect_from_float(ibuf);
}
@@ -2605,9 +2595,9 @@ ImBuf *IMB_colormanagement_imbuf_for_write(ImBuf *ibuf,
if (byte_output) {
colormanaged_ibuf->rect_colorspace = colormanage_colorspace_get_named(to_colorspace);
if (colormanaged_ibuf->rect) {
if (colormanaged_ibuf->byte_buffer.data) {
/* Byte to byte. */
IMB_colormanagement_transform_byte_threaded((uchar *)colormanaged_ibuf->rect,
IMB_colormanagement_transform_byte_threaded(colormanaged_ibuf->byte_buffer.data,
colormanaged_ibuf->x,
colormanaged_ibuf->y,
colormanaged_ibuf->channels,
@@ -2620,7 +2610,7 @@ ImBuf *IMB_colormanagement_imbuf_for_write(ImBuf *ibuf,
}
}
else {
if (!colormanaged_ibuf->rect_float) {
if (!colormanaged_ibuf->float_buffer.data) {
/* Byte to float. */
IMB_float_from_rect(colormanaged_ibuf);
imb_freerectImBuf(colormanaged_ibuf);
@@ -2629,9 +2619,9 @@ ImBuf *IMB_colormanagement_imbuf_for_write(ImBuf *ibuf,
from_colorspace = global_role_scene_linear;
}
if (colormanaged_ibuf->rect_float) {
if (colormanaged_ibuf->float_buffer.data) {
/* Float to float. */
IMB_colormanagement_transform(colormanaged_ibuf->rect_float,
IMB_colormanagement_transform(colormanaged_ibuf->float_buffer.data,
colormanaged_ibuf->x,
colormanaged_ibuf->y,
colormanaged_ibuf->channels,
@@ -2685,9 +2675,9 @@ uchar *IMB_display_buffer_acquire(ImBuf *ibuf,
/* early out: no float buffer and byte buffer is already in display space,
* let's just use if
*/
if (ibuf->rect_float == nullptr && ibuf->rect_colorspace && ibuf->channels == 4) {
if (ibuf->float_buffer.data == nullptr && ibuf->rect_colorspace && ibuf->channels == 4) {
if (is_ibuf_rect_in_display_space(ibuf, applied_view_settings, display_settings)) {
return (uchar *)ibuf->rect;
return ibuf->byte_buffer.data;
}
}
@@ -2697,8 +2687,8 @@ uchar *IMB_display_buffer_acquire(ImBuf *ibuf,
if (ibuf->invalid_rect.xmin != ibuf->invalid_rect.xmax) {
if ((ibuf->userflags & IB_DISPLAY_BUFFER_INVALID) == 0) {
IMB_partial_display_buffer_update_threaded(ibuf,
ibuf->rect_float,
(uchar *)ibuf->rect,
ibuf->float_buffer.data,
ibuf->byte_buffer.data,
ibuf->x,
0,
0,
+17 -19
View File
@@ -696,12 +696,12 @@ void IMB_buffer_byte_from_byte(uchar *rect_to,
void IMB_rect_from_float(ImBuf *ibuf)
{
/* verify we have a float buffer */
if (ibuf->rect_float == nullptr) {
if (ibuf->float_buffer.data == nullptr) {
return;
}
/* create byte rect if it didn't exist yet */
if (ibuf->rect == nullptr) {
if (ibuf->byte_buffer.data == nullptr) {
if (imb_addrectImBuf(ibuf) == 0) {
return;
}
@@ -716,7 +716,7 @@ void IMB_rect_from_float(ImBuf *ibuf)
COLOR_ROLE_DEFAULT_BYTE) :
ibuf->rect_colorspace->name;
float *buffer = static_cast<float *>(MEM_dupallocN(ibuf->rect_float));
float *buffer = static_cast<float *>(MEM_dupallocN(ibuf->float_buffer.data));
/* first make float buffer in byte space */
const bool predivide = IMB_alpha_affects_rgb(ibuf);
@@ -729,7 +729,7 @@ void IMB_rect_from_float(ImBuf *ibuf)
}
/* convert float to byte */
IMB_buffer_byte_from_float((uchar *)ibuf->rect,
IMB_buffer_byte_from_float(ibuf->byte_buffer.data,
buffer,
ibuf->channels,
ibuf->dither,
@@ -751,9 +751,10 @@ void IMB_float_from_rect_ex(struct ImBuf *dst,
const struct ImBuf *src,
const rcti *region_to_update)
{
BLI_assert_msg(dst->rect_float != nullptr,
BLI_assert_msg(dst->float_buffer.data != nullptr,
"Destination buffer should have a float buffer assigned.");
BLI_assert_msg(src->rect != nullptr, "Source buffer should have a byte buffer assigned.");
BLI_assert_msg(src->byte_buffer.data != nullptr,
"Source buffer should have a byte buffer assigned.");
BLI_assert_msg(dst->x == src->x, "Source and destination buffer should have the same dimension");
BLI_assert_msg(dst->y == src->y, "Source and destination buffer should have the same dimension");
BLI_assert_msg(dst->channels = 4, "Destination buffer should have 4 channels.");
@@ -766,9 +767,9 @@ void IMB_float_from_rect_ex(struct ImBuf *dst,
BLI_assert_msg(region_to_update->ymax <= dst->y,
"Region to update should be clipped to the given buffers.");
float *rect_float = dst->rect_float;
float *rect_float = dst->float_buffer.data;
rect_float += (region_to_update->xmin + region_to_update->ymin * dst->x) * 4;
uchar *rect = (uchar *)src->rect;
uchar *rect = src->byte_buffer.data;
rect += (region_to_update->xmin + region_to_update->ymin * dst->x) * 4;
const int region_width = BLI_rcti_size_x(region_to_update);
const int region_height = BLI_rcti_size_y(region_to_update);
@@ -804,10 +805,8 @@ void IMB_float_from_rect_ex(struct ImBuf *dst,
void IMB_float_from_rect(ImBuf *ibuf)
{
float *rect_float;
/* verify if we byte and float buffers */
if (ibuf->rect == nullptr) {
if (ibuf->byte_buffer.data == nullptr) {
return;
}
@@ -815,7 +814,7 @@ void IMB_float_from_rect(ImBuf *ibuf)
* so work-in-progress color space conversion doesn't
* interfere with other parts of blender
*/
rect_float = ibuf->rect_float;
float *rect_float = ibuf->float_buffer.data;
if (rect_float == nullptr) {
const size_t size = IMB_get_rect_len(ibuf) * sizeof(float[4]);
rect_float = static_cast<float *>(MEM_callocN(size, "IMB_float_from_rect"));
@@ -825,9 +824,8 @@ void IMB_float_from_rect(ImBuf *ibuf)
}
ibuf->channels = 4;
ibuf->rect_float = rect_float;
ibuf->mall |= IB_rectfloat;
ibuf->flags |= IB_rectfloat;
IMB_assign_float_buffer(ibuf, rect_float, IB_TAKE_OWNERSHIP);
}
rcti region_to_update;
@@ -843,8 +841,8 @@ void IMB_float_from_rect(ImBuf *ibuf)
void IMB_color_to_bw(ImBuf *ibuf)
{
float *rct_fl = ibuf->rect_float;
uchar *rct = (uchar *)ibuf->rect;
float *rct_fl = ibuf->float_buffer.data;
uchar *rct = ibuf->byte_buffer.data;
size_t i;
if (rct_fl) {
@@ -889,8 +887,8 @@ void IMB_buffer_float_premultiply(float *buf, int width, int height)
void IMB_saturation(ImBuf *ibuf, float sat)
{
size_t i;
uchar *rct = (uchar *)ibuf->rect;
float *rct_fl = ibuf->rect_float;
uchar *rct = ibuf->byte_buffer.data;
float *rct_fl = ibuf->float_buffer.data;
float hsv[3];
if (rct) {
+42 -49
View File
@@ -101,16 +101,12 @@ static void filtcolumf(float *point, int y, int skip)
void IMB_filtery(struct ImBuf *ibuf)
{
uchar *point;
float *pointf;
int x, y, skip;
uchar *point = ibuf->byte_buffer.data;
float *pointf = ibuf->float_buffer.data;
point = (uchar *)ibuf->rect;
pointf = ibuf->rect_float;
x = ibuf->x;
y = ibuf->y;
skip = x << 2;
int x = ibuf->x;
int y = ibuf->y;
int skip = x << 2;
for (; x > 0; x--) {
if (point) {
@@ -142,16 +138,12 @@ void IMB_filtery(struct ImBuf *ibuf)
void imb_filterx(struct ImBuf *ibuf)
{
uchar *point;
float *pointf;
int x, y, skip;
uchar *point = ibuf->byte_buffer.data;
float *pointf = ibuf->float_buffer.data;
point = (uchar *)ibuf->rect;
pointf = ibuf->rect_float;
x = ibuf->x;
y = ibuf->y;
skip = (x << 2) - 3;
int x = ibuf->x;
int y = ibuf->y;
int skip = (x << 2) - 3;
for (; y > 0; y--) {
if (point) {
@@ -189,14 +181,14 @@ static void imb_filterN(ImBuf *out, ImBuf *in)
const int channels = in->channels;
const int rowlen = in->x;
if (in->rect && out->rect) {
if (in->byte_buffer.data && out->byte_buffer.data) {
for (int y = 0; y < in->y; y++) {
/* setup rows */
const char *row2 = (const char *)in->rect + y * channels * rowlen;
const char *row2 = (const char *)in->byte_buffer.data + y * channels * rowlen;
const char *row1 = (y == 0) ? row2 : row2 - channels * rowlen;
const char *row3 = (y == in->y - 1) ? row2 : row2 + channels * rowlen;
char *cp = (char *)out->rect + y * channels * rowlen;
char *cp = (char *)out->byte_buffer.data + y * channels * rowlen;
for (int x = 0; x < rowlen; x++) {
const char *r11, *r13, *r21, *r23, *r31, *r33;
@@ -243,14 +235,14 @@ static void imb_filterN(ImBuf *out, ImBuf *in)
}
}
if (in->rect_float && out->rect_float) {
if (in->float_buffer.data && out->float_buffer.data) {
for (int y = 0; y < in->y; y++) {
/* setup rows */
const float *row2 = (const float *)in->rect_float + y * channels * rowlen;
const float *row2 = (const float *)in->float_buffer.data + y * channels * rowlen;
const float *row1 = (y == 0) ? row2 : row2 - channels * rowlen;
const float *row3 = (y == in->y - 1) ? row2 : row2 + channels * rowlen;
float *cp = (float *)out->rect_float + y * channels * rowlen;
float *cp = (float *)out->float_buffer.data + y * channels * rowlen;
for (int x = 0; x < rowlen; x++) {
const float *r11, *r13, *r21, *r23, *r31, *r33;
@@ -351,11 +343,11 @@ void IMB_mask_filter_extend(char *mask, int width, int height)
void IMB_mask_clear(ImBuf *ibuf, const char *mask, int val)
{
int x, y;
if (ibuf->rect_float) {
if (ibuf->float_buffer.data) {
for (x = 0; x < ibuf->x; x++) {
for (y = 0; y < ibuf->y; y++) {
if (mask[ibuf->x * y + x] == val) {
float *col = ibuf->rect_float + 4 * (ibuf->x * y + x);
float *col = ibuf->float_buffer.data + 4 * (ibuf->x * y + x);
col[0] = col[1] = col[2] = col[3] = 0.0f;
}
}
@@ -366,7 +358,7 @@ void IMB_mask_clear(ImBuf *ibuf, const char *mask, int val)
for (x = 0; x < ibuf->x; x++) {
for (y = 0; y < ibuf->y; y++) {
if (mask[ibuf->x * y + x] == val) {
char *col = (char *)(ibuf->rect + ibuf->x * y + x);
char *col = (char *)(ibuf->byte_buffer.data + 4 * ibuf->x * y + x);
col[0] = col[1] = col[2] = col[3] = 0;
}
}
@@ -409,13 +401,14 @@ void IMB_filter_extend(struct ImBuf *ibuf, char *mask, int filter)
const int width = ibuf->x;
const int height = ibuf->y;
const int depth = 4; /* always 4 channels */
const int chsize = ibuf->rect_float ? sizeof(float) : sizeof(uchar);
const int chsize = ibuf->float_buffer.data ? sizeof(float) : sizeof(uchar);
const size_t bsize = size_t(width) * height * depth * chsize;
const bool is_float = (ibuf->rect_float != nullptr);
void *dstbuf = (void *)MEM_dupallocN(ibuf->rect_float ? (void *)ibuf->rect_float :
(void *)ibuf->rect);
const bool is_float = (ibuf->float_buffer.data != nullptr);
void *dstbuf = MEM_dupallocN(ibuf->float_buffer.data ? (void *)ibuf->float_buffer.data :
(void *)ibuf->byte_buffer.data);
char *dstmask = mask == nullptr ? nullptr : (char *)MEM_dupallocN(mask);
void *srcbuf = ibuf->rect_float ? (void *)ibuf->rect_float : (void *)ibuf->rect;
void *srcbuf = ibuf->float_buffer.data ? (void *)ibuf->float_buffer.data :
(void *)ibuf->byte_buffer.data;
char *srcmask = mask;
int cannot_early_out = 1, r, n, k, i, j, c;
float weight[25];
@@ -582,7 +575,7 @@ void IMB_makemipmap(ImBuf *ibuf, int use_filter)
imb_freemipmapImBuf(ibuf);
/* no mipmap for non RGBA images */
if (ibuf->rect_float && ibuf->channels < 4) {
if (ibuf->float_buffer.data && ibuf->channels < 4) {
return;
}
@@ -617,13 +610,13 @@ ImBuf *IMB_getmipmap(ImBuf *ibuf, int level)
return (level == 0) ? ibuf : ibuf->mipmap[level - 1];
}
void IMB_premultiply_rect(uint *rect, char planes, int w, int h)
void IMB_premultiply_rect(uint8_t *rect, char planes, int w, int h)
{
char *cp;
uint8_t *cp;
int x, y, val;
if (planes == 24) { /* put alpha at 255 */
cp = (char *)(rect);
cp = rect;
for (y = 0; y < h; y++) {
for (x = 0; x < w; x++, cp += 4) {
@@ -632,7 +625,7 @@ void IMB_premultiply_rect(uint *rect, char planes, int w, int h)
}
}
else {
cp = (char *)(rect);
cp = rect;
for (y = 0; y < h; y++) {
for (x = 0; x < w; x++, cp += 4) {
@@ -669,23 +662,23 @@ void IMB_premultiply_alpha(ImBuf *ibuf)
return;
}
if (ibuf->rect) {
IMB_premultiply_rect(ibuf->rect, ibuf->planes, ibuf->x, ibuf->y);
if (ibuf->byte_buffer.data) {
IMB_premultiply_rect(ibuf->byte_buffer.data, ibuf->planes, ibuf->x, ibuf->y);
}
if (ibuf->rect_float) {
IMB_premultiply_rect_float(ibuf->rect_float, ibuf->channels, ibuf->x, ibuf->y);
if (ibuf->float_buffer.data) {
IMB_premultiply_rect_float(ibuf->float_buffer.data, ibuf->channels, ibuf->x, ibuf->y);
}
}
void IMB_unpremultiply_rect(uint *rect, char planes, int w, int h)
void IMB_unpremultiply_rect(uint8_t *rect, char planes, int w, int h)
{
char *cp;
uchar *cp;
int x, y;
float val;
if (planes == 24) { /* put alpha at 255 */
cp = (char *)(rect);
cp = rect;
for (y = 0; y < h; y++) {
for (x = 0; x < w; x++, cp += 4) {
@@ -694,7 +687,7 @@ void IMB_unpremultiply_rect(uint *rect, char planes, int w, int h)
}
}
else {
cp = (char *)(rect);
cp = rect;
for (y = 0; y < h; y++) {
for (x = 0; x < w; x++, cp += 4) {
@@ -731,11 +724,11 @@ void IMB_unpremultiply_alpha(ImBuf *ibuf)
return;
}
if (ibuf->rect) {
IMB_unpremultiply_rect(ibuf->rect, ibuf->planes, ibuf->x, ibuf->y);
if (ibuf->byte_buffer.data) {
IMB_unpremultiply_rect(ibuf->byte_buffer.data, ibuf->planes, ibuf->x, ibuf->y);
}
if (ibuf->rect_float) {
IMB_unpremultiply_rect_float(ibuf->rect_float, ibuf->channels, ibuf->x, ibuf->y);
if (ibuf->float_buffer.data) {
IMB_unpremultiply_rect_float(ibuf->float_buffer.data, ibuf->channels, ibuf->x, ibuf->y);
}
}
+1 -1
View File
@@ -48,7 +48,7 @@ ImBuf *imb_load_tiff(const uchar *mem, size_t size, int flags, char colorspace[I
bool imb_save_tiff(struct ImBuf *ibuf, const char *filepath, int flags)
{
const bool is_16bit = ((ibuf->foptions.flag & TIF_16BIT) && ibuf->rect_float);
const bool is_16bit = ((ibuf->foptions.flag & TIF_16BIT) && ibuf->float_buffer.data);
const int file_channels = ibuf->planes >> 3;
const TypeDesc data_format = is_16bit ? TypeDesc::UINT16 : TypeDesc::UINT8;
+36 -34
View File
@@ -26,10 +26,10 @@
void IMB_convert_rgba_to_abgr(struct ImBuf *ibuf)
{
size_t size;
uchar rt, *cp = (uchar *)ibuf->rect;
float rtf, *cpf = ibuf->rect_float;
uchar rt, *cp = ibuf->byte_buffer.data;
float rtf, *cpf = ibuf->float_buffer.data;
if (ibuf->rect) {
if (ibuf->byte_buffer.data) {
size = ibuf->x * ibuf->y;
while (size-- > 0) {
@@ -43,7 +43,7 @@ void IMB_convert_rgba_to_abgr(struct ImBuf *ibuf)
}
}
if (ibuf->rect_float) {
if (ibuf->float_buffer.data) {
size = ibuf->x * ibuf->y;
while (size-- > 0) {
@@ -63,12 +63,12 @@ static void pixel_from_buffer(const struct ImBuf *ibuf, uchar **outI, float **ou
{
size_t offset = size_t(ibuf->x) * y * 4 + 4 * x;
if (ibuf->rect) {
*outI = (uchar *)ibuf->rect + offset;
if (ibuf->byte_buffer.data) {
*outI = ibuf->byte_buffer.data + offset;
}
if (ibuf->rect_float) {
*outF = ibuf->rect_float + offset;
if (ibuf->float_buffer.data) {
*outF = ibuf->float_buffer.data + offset;
}
}
@@ -80,10 +80,10 @@ void bicubic_interpolation_color(
const struct ImBuf *in, uchar outI[4], float outF[4], float u, float v)
{
if (outF) {
BLI_bicubic_interpolation_fl(in->rect_float, outF, in->x, in->y, 4, u, v);
BLI_bicubic_interpolation_fl(in->float_buffer.data, outF, in->x, in->y, 4, u, v);
}
else {
BLI_bicubic_interpolation_char((uchar *)in->rect, outI, in->x, in->y, 4, u, v);
BLI_bicubic_interpolation_char(in->byte_buffer.data, outI, in->x, in->y, 4, u, v);
}
}
@@ -92,7 +92,7 @@ void bicubic_interpolation(const ImBuf *in, ImBuf *out, float u, float v, int xo
uchar *outI = nullptr;
float *outF = nullptr;
if (in == nullptr || (in->rect == nullptr && in->rect_float == nullptr)) {
if (in == nullptr || (in->byte_buffer.data == nullptr && in->float_buffer.data == nullptr)) {
return;
}
@@ -112,26 +112,26 @@ void bilinear_interpolation_color_fl(
const struct ImBuf *in, uchar /*outI*/[4], float outF[4], float u, float v)
{
BLI_assert(outF);
BLI_assert(in->rect_float);
BLI_bilinear_interpolation_fl(in->rect_float, outF, in->x, in->y, 4, u, v);
BLI_assert(in->float_buffer.data);
BLI_bilinear_interpolation_fl(in->float_buffer.data, outF, in->x, in->y, 4, u, v);
}
void bilinear_interpolation_color_char(
const struct ImBuf *in, uchar outI[4], float /*outF*/[4], float u, float v)
{
BLI_assert(outI);
BLI_assert(in->rect);
BLI_bilinear_interpolation_char((uchar *)in->rect, outI, in->x, in->y, 4, u, v);
BLI_assert(in->byte_buffer.data);
BLI_bilinear_interpolation_char(in->byte_buffer.data, outI, in->x, in->y, 4, u, v);
}
void bilinear_interpolation_color(
const struct ImBuf *in, uchar outI[4], float outF[4], float u, float v)
{
if (outF) {
BLI_bilinear_interpolation_fl(in->rect_float, outF, in->x, in->y, 4, u, v);
BLI_bilinear_interpolation_fl(in->float_buffer.data, outF, in->x, in->y, 4, u, v);
}
else {
BLI_bilinear_interpolation_char((uchar *)in->rect, outI, in->x, in->y, 4, u, v);
BLI_bilinear_interpolation_char(in->byte_buffer.data, outI, in->x, in->y, 4, u, v);
}
}
@@ -181,11 +181,12 @@ void bilinear_interpolation_color_wrap(
ma_mb = (1.0f - a) * (1.0f - b);
if (outF) {
float *in_rect_float = in->float_buffer.data;
/* sample including outside of edges of image */
row1 = in->rect_float + size_t(in->x) * y1 * 4 + 4 * x1;
row2 = in->rect_float + size_t(in->x) * y2 * 4 + 4 * x1;
row3 = in->rect_float + size_t(in->x) * y1 * 4 + 4 * x2;
row4 = in->rect_float + size_t(in->x) * y2 * 4 + 4 * x2;
row1 = in_rect_float + size_t(in->x) * y1 * 4 + 4 * x1;
row2 = in_rect_float + size_t(in->x) * y2 * 4 + 4 * x1;
row3 = in_rect_float + size_t(in->x) * y1 * 4 + 4 * x2;
row4 = in_rect_float + size_t(in->x) * y2 * 4 + 4 * x2;
outF[0] = ma_mb * row1[0] + a_mb * row3[0] + ma_b * row2[0] + a_b * row4[0];
outF[1] = ma_mb * row1[1] + a_mb * row3[1] + ma_b * row2[1] + a_b * row4[1];
@@ -196,11 +197,12 @@ void bilinear_interpolation_color_wrap(
clamp_v4(outF, 0.0f, 1.0f);
}
if (outI) {
uchar *in_rect = in->byte_buffer.data;
/* sample including outside of edges of image */
row1I = (uchar *)in->rect + size_t(in->x) * y1 * 4 + 4 * x1;
row2I = (uchar *)in->rect + size_t(in->x) * y2 * 4 + 4 * x1;
row3I = (uchar *)in->rect + size_t(in->x) * y1 * 4 + 4 * x2;
row4I = (uchar *)in->rect + size_t(in->x) * y2 * 4 + 4 * x2;
row1I = in_rect + size_t(in->x) * y1 * 4 + 4 * x1;
row2I = in_rect + size_t(in->x) * y2 * 4 + 4 * x1;
row3I = in_rect + size_t(in->x) * y1 * 4 + 4 * x2;
row4I = in_rect + size_t(in->x) * y2 * 4 + 4 * x2;
/* Tested with white images and this should not wrap back to zero. */
outI[0] = roundf(ma_mb * row1I[0] + a_mb * row3I[0] + ma_b * row2I[0] + a_b * row4I[0]);
@@ -215,7 +217,7 @@ void bilinear_interpolation(const ImBuf *in, ImBuf *out, float u, float v, int x
uchar *outI = nullptr;
float *outF = nullptr;
if (in == nullptr || (in->rect == nullptr && in->rect_float == nullptr)) {
if (in == nullptr || (in->byte_buffer.data == nullptr && in->float_buffer.data == nullptr)) {
return;
}
@@ -235,7 +237,7 @@ void nearest_interpolation_color_char(
const struct ImBuf *in, uchar outI[4], float /*outF*/[4], float u, float v)
{
BLI_assert(outI);
BLI_assert(in->rect);
BLI_assert(in->byte_buffer.data);
/* ImBuf in must have a valid rect or rect_float, assume this is already checked */
int x1 = int(u);
int y1 = int(v);
@@ -247,7 +249,7 @@ void nearest_interpolation_color_char(
}
const size_t offset = (size_t(in->x) * y1 + x1) * 4;
const uchar *dataI = (uchar *)in->rect + offset;
const uchar *dataI = in->byte_buffer.data + offset;
outI[0] = dataI[0];
outI[1] = dataI[1];
outI[2] = dataI[2];
@@ -258,7 +260,7 @@ void nearest_interpolation_color_fl(
const struct ImBuf *in, uchar /*outI*/[4], float outF[4], float u, float v)
{
BLI_assert(outF);
BLI_assert(in->rect_float);
BLI_assert(in->float_buffer.data);
/* ImBuf in must have a valid rect or rect_float, assume this is already checked */
int x1 = int(u);
int y1 = int(v);
@@ -270,7 +272,7 @@ void nearest_interpolation_color_fl(
}
const size_t offset = (size_t(in->x) * y1 + x1) * 4;
const float *dataF = in->rect_float + offset;
const float *dataF = in->float_buffer.data + offset;
copy_v4_v4(outF, dataF);
}
@@ -308,14 +310,14 @@ void nearest_interpolation_color_wrap(
y += in->y;
}
dataI = (uchar *)in->rect + size_t(in->x) * y * 4 + 4 * x;
dataI = in->byte_buffer.data + size_t(in->x) * y * 4 + 4 * x;
if (outI) {
outI[0] = dataI[0];
outI[1] = dataI[1];
outI[2] = dataI[2];
outI[3] = dataI[3];
}
dataF = in->rect_float + size_t(in->x) * y * 4 + 4 * x;
dataF = in->float_buffer.data + size_t(in->x) * y * 4 + 4 * x;
if (outF) {
outF[0] = dataF[0];
outF[1] = dataF[1];
@@ -329,7 +331,7 @@ void nearest_interpolation(const ImBuf *in, ImBuf *out, float u, float v, int xo
uchar *outI = nullptr;
float *outF = nullptr;
if (in == nullptr || (in->rect == nullptr && in->rect_float == nullptr)) {
if (in == nullptr || (in->byte_buffer.data == nullptr && in->float_buffer.data == nullptr)) {
return;
}
@@ -481,7 +483,7 @@ void IMB_alpha_under_color_byte(uchar *rect, int x, int y, const float backcol[3
void IMB_sampleImageAtLocation(ImBuf *ibuf, float x, float y, bool make_linear_rgb, float color[4])
{
if (ibuf->rect_float) {
if (ibuf->float_buffer.data) {
nearest_interpolation_color(ibuf, nullptr, color, x, y);
}
else {
+2 -3
View File
@@ -1392,10 +1392,9 @@ static void index_rebuild_fallback(FallbackIndexBuilderContext *context,
IMB_convert_rgba_to_abgr(s_ibuf);
AVI_write_frame(context->proxy_ctx[i], pos, AVI_FORMAT_RGB32, s_ibuf->rect, x * y * 4);
/* note that libavi free's the buffer... */
s_ibuf->rect = nullptr;
uint8_t *rect = IMB_steal_byte_buffer(s_ibuf);
AVI_write_frame(context->proxy_ctx[i], pos, AVI_FORMAT_RGB32, rect, x * y * 4);
IMB_freeImBuf(s_ibuf);
}
+18 -17
View File
@@ -210,12 +210,12 @@ static void test_endian_zbuf(struct ImBuf *ibuf)
return;
#endif
if (ibuf->zbuf == nullptr) {
if (ibuf->z_buffer.data == nullptr) {
return;
}
len = ibuf->x * ibuf->y;
zval = ibuf->zbuf;
zval = ibuf->z_buffer.data;
while (len--) {
zval[0] = BIG_LONG(zval[0]);
@@ -336,8 +336,8 @@ struct ImBuf *imb_loadiris(const uchar *mem, size_t size, int flags, char colors
if (ibuf->planes > 32) {
ibuf->planes = 32;
}
base = ibuf->rect;
zbase = (uint *)ibuf->zbuf;
base = (uint *)ibuf->byte_buffer.data;
zbase = (uint *)ibuf->z_buffer.data;
if (badorder) {
for (size_t z = 0; z < zsize; z++) {
@@ -389,7 +389,7 @@ struct ImBuf *imb_loadiris(const uchar *mem, size_t size, int flags, char colors
goto fail_rle;
}
fbase = ibuf->rect_float;
fbase = ibuf->float_buffer.data;
if (badorder) {
for (size_t z = 0; z < zsize; z++) {
@@ -452,8 +452,8 @@ struct ImBuf *imb_loadiris(const uchar *mem, size_t size, int flags, char colors
ibuf->planes = 32;
}
base = ibuf->rect;
zbase = (uint *)ibuf->zbuf;
base = (uint *)ibuf->byte_buffer.data;
zbase = (uint *)ibuf->z_buffer.data;
MFILE_SEEK(inf, HEADER_SIZE);
rledat = MFILE_DATA(inf);
@@ -484,7 +484,7 @@ struct ImBuf *imb_loadiris(const uchar *mem, size_t size, int flags, char colors
goto fail_uncompressed;
}
fbase = ibuf->rect_float;
fbase = ibuf->float_buffer.data;
MFILE_SEEK(inf, HEADER_SIZE);
rledat = MFILE_DATA(inf);
@@ -514,7 +514,7 @@ struct ImBuf *imb_loadiris(const uchar *mem, size_t size, int flags, char colors
uchar *rect;
if (image.zsize == 1) {
rect = (uchar *)ibuf->rect;
rect = ibuf->byte_buffer.data;
for (size_t x = size_t(ibuf->x) * size_t(ibuf->y); x > 0; x--) {
rect[0] = 255;
rect[1] = rect[2] = rect[3];
@@ -523,7 +523,7 @@ struct ImBuf *imb_loadiris(const uchar *mem, size_t size, int flags, char colors
}
else if (image.zsize == 2) {
/* Gray-scale with alpha. */
rect = (uchar *)ibuf->rect;
rect = ibuf->byte_buffer.data;
for (size_t x = size_t(ibuf->x) * size_t(ibuf->y); x > 0; x--) {
rect[0] = rect[2];
rect[1] = rect[2] = rect[3];
@@ -532,7 +532,7 @@ struct ImBuf *imb_loadiris(const uchar *mem, size_t size, int flags, char colors
}
else if (image.zsize == 3) {
/* add alpha */
rect = (uchar *)ibuf->rect;
rect = ibuf->byte_buffer.data;
for (size_t x = size_t(ibuf->x) * size_t(ibuf->y); x > 0; x--) {
rect[0] = 255;
rect += 4;
@@ -542,7 +542,7 @@ struct ImBuf *imb_loadiris(const uchar *mem, size_t size, int flags, char colors
else { /* bpp == 2 */
if (image.zsize == 1) {
fbase = ibuf->rect_float;
fbase = ibuf->float_buffer.data;
for (size_t x = size_t(ibuf->x) * size_t(ibuf->y); x > 0; x--) {
fbase[0] = 1;
fbase[1] = fbase[2] = fbase[3];
@@ -551,7 +551,7 @@ struct ImBuf *imb_loadiris(const uchar *mem, size_t size, int flags, char colors
}
else if (image.zsize == 2) {
/* Gray-scale with alpha. */
fbase = ibuf->rect_float;
fbase = ibuf->float_buffer.data;
for (size_t x = size_t(ibuf->x) * size_t(ibuf->y); x > 0; x--) {
fbase[0] = fbase[2];
fbase[1] = fbase[2] = fbase[3];
@@ -560,7 +560,7 @@ struct ImBuf *imb_loadiris(const uchar *mem, size_t size, int flags, char colors
}
else if (image.zsize == 3) {
/* add alpha */
fbase = ibuf->rect_float;
fbase = ibuf->float_buffer.data;
for (size_t x = size_t(ibuf->x) * size_t(ibuf->y); x > 0; x--) {
fbase[0] = 1;
fbase += 4;
@@ -579,7 +579,7 @@ struct ImBuf *imb_loadiris(const uchar *mem, size_t size, int flags, char colors
test_endian_zbuf(ibuf);
if (ibuf->rect) {
if (ibuf->byte_buffer.data) {
IMB_convert_rgba_to_abgr(ibuf);
}
@@ -965,14 +965,15 @@ bool imb_saveiris(struct ImBuf *ibuf, const char *filepath, int flags)
short zsize;
zsize = (ibuf->planes + 7) >> 3;
if (flags & IB_zbuf && ibuf->zbuf != nullptr) {
if (flags & IB_zbuf && ibuf->z_buffer.data != nullptr) {
zsize = 8;
}
IMB_convert_rgba_to_abgr(ibuf);
test_endian_zbuf(ibuf);
const bool ok = output_iris(filepath, ibuf->rect, ibuf->zbuf, ibuf->x, ibuf->y, zsize);
const bool ok = output_iris(
filepath, (uint *)ibuf->byte_buffer.data, ibuf->z_buffer.data, ibuf->x, ibuf->y, zsize);
/* restore! Quite clumsy, 2 times a switch... maybe better a malloc ? */
IMB_convert_rgba_to_abgr(ibuf);
+4 -4
View File
@@ -450,7 +450,7 @@ static ImBuf *imb_load_jp2_stream(opj_stream_t *stream,
}
if (use_float) {
float *rect_float = ibuf->rect_float;
float *rect_float = ibuf->float_buffer.data;
if (image->numcomps < 3) {
r = image->comps[0].data;
@@ -503,7 +503,7 @@ static ImBuf *imb_load_jp2_stream(opj_stream_t *stream,
}
}
else {
uchar *rect_uchar = (uchar *)ibuf->rect;
uchar *rect_uchar = ibuf->byte_buffer.data;
if (image->numcomps < 3) {
r = image->comps[0].data;
@@ -907,8 +907,8 @@ static opj_image_t *ibuftoimage(ImBuf *ibuf, opj_cparameters_t *parameters)
image->y1 = image->y0 + (h - 1) * subsampling_dy + 1 + image->y0;
/* set image data */
rect_uchar = (uchar *)ibuf->rect;
rect_float = ibuf->rect_float;
rect_uchar = ibuf->byte_buffer.data;
rect_float = ibuf->float_buffer.data;
/* set the destination channels */
r = image->comps[0].data;
+2 -2
View File
@@ -315,7 +315,7 @@ static ImBuf *ibJpegImageFromCinfo(struct jpeg_decompress_struct *cinfo,
for (y = ibuf->y - 1; y >= 0; y--) {
jpeg_read_scanlines(cinfo, row_pointer, 1);
rect = (uchar *)(ibuf->rect + y * ibuf->x);
rect = ibuf->byte_buffer.data + 4 * y * ibuf->x;
buffer = row_pointer[0];
switch (depth) {
@@ -626,7 +626,7 @@ static void write_jpeg(struct jpeg_compress_struct *cinfo, struct ImBuf *ibuf)
sizeof(JSAMPLE) * cinfo->input_components * cinfo->image_width, "jpeg row_pointer"));
for (y = ibuf->y - 1; y >= 0; y--) {
rect = (uchar *)(ibuf->rect + y * ibuf->x);
rect = ibuf->byte_buffer.data + 4 * y * ibuf->x;
buffer = row_pointer[0];
switch (cinfo->in_color_space) {
@@ -41,17 +41,17 @@ class ImBufMemWriter : public Filesystem::IOProxy {
{
/* If buffer is too small increase it. */
size_t end = offset + size;
while (end > ibuf_->encodedbuffersize) {
while (end > ibuf_->encoded_buffer_size) {
if (!imb_enlargeencodedbufferImBuf(ibuf_)) {
/* Out of memory. */
return 0;
}
}
memcpy(ibuf_->encodedbuffer + offset, buf, size);
memcpy(ibuf_->encoded_buffer.data + offset, buf, size);
if (end > ibuf_->encodedsize) {
ibuf_->encodedsize = end;
if (end > ibuf_->encoded_size) {
ibuf_->encoded_size = end;
}
return size;
@@ -59,7 +59,7 @@ class ImBufMemWriter : public Filesystem::IOProxy {
size_t size() const override
{
return ibuf_->encodedsize;
return ibuf_->encoded_size;
}
private:
@@ -116,8 +116,8 @@ static ImBuf *load_pixels(
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);
uchar *rect = is_float ? reinterpret_cast<uchar *>(ibuf->float_buffer.data) :
reinterpret_cast<uchar *>(ibuf->byte_buffer.data);
void *ibuf_data = rect + ((stride_t(height) - 1) * ibuf_ystride);
bool ok = in->read_image(
@@ -340,19 +340,19 @@ WriteContext imb_create_write_context(const char *file_format,
const int width = ibuf->x;
const int height = ibuf->y;
const bool use_float = prefer_float && (ibuf->rect_float != nullptr);
const bool use_float = prefer_float && (ibuf->float_buffer.data != 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_start = reinterpret_cast<uchar *>(ibuf->rect_float);
ctx.mem_start = reinterpret_cast<uchar *>(ibuf->float_buffer.data);
ctx.mem_spec = ImageSpec(width, height, mem_channels, TypeDesc::FLOAT);
}
else {
const int mem_channels = 4;
ctx.mem_xstride = sizeof(uchar) * mem_channels;
ctx.mem_ystride = width * ctx.mem_xstride;
ctx.mem_start = reinterpret_cast<uchar *>(ibuf->rect);
ctx.mem_start = ibuf->byte_buffer.data;
ctx.mem_spec = ImageSpec(width, height, mem_channels, TypeDesc::UINT8);
}
@@ -280,9 +280,9 @@ class OMemStream : public OStream {
void write(const char c[], int n) override
{
ensure_size(offset + n);
memcpy(ibuf->encodedbuffer + offset, c, n);
memcpy(ibuf->encoded_buffer.data + offset, c, n);
offset += n;
ibuf->encodedsize += n;
ibuf->encoded_size += n;
}
exr_file_offset_t tellp() override
@@ -300,7 +300,7 @@ class OMemStream : public OStream {
void ensure_size(exr_file_offset_t size)
{
/* if buffer is too small increase it. */
while (size > ibuf->encodedbuffersize) {
while (size > ibuf->encoded_buffer_size) {
if (!imb_enlargeencodedbufferImBuf(ibuf)) {
throw Iex::ErrnoExc("Out of memory.");
}
@@ -462,7 +462,8 @@ static bool imb_save_openexr_half(ImBuf *ibuf, const char *filepath, const int f
{
const int channels = ibuf->channels;
const bool is_alpha = (channels >= 4) && (ibuf->planes == 32);
const bool is_zbuf = (flags & IB_zbuffloat) && ibuf->zbuf_float != nullptr; /* summarize */
const bool is_zbuf = (flags & IB_zbuffloat) &&
ibuf->float_z_buffer.data != nullptr; /* summarize */
const int width = ibuf->x;
const int height = ibuf->y;
OStream *file_stream = nullptr;
@@ -512,15 +513,15 @@ static bool imb_save_openexr_half(ImBuf *ibuf, const char *filepath, const int f
if (is_zbuf) {
frameBuffer.insert("Z",
Slice(Imf::FLOAT,
(char *)(ibuf->zbuf_float + (height - 1) * width),
(char *)(ibuf->float_z_buffer.data + (height - 1) * width),
sizeof(float),
sizeof(float) * -width));
}
if (ibuf->rect_float) {
if (ibuf->float_buffer.data) {
float *from;
for (int i = ibuf->y - 1; i >= 0; i--) {
from = ibuf->rect_float + channels * i * width;
from = ibuf->float_buffer.data + channels * i * width;
for (int j = ibuf->x; j > 0; j--) {
to->r = float_to_half_safe(from[0]);
@@ -536,7 +537,7 @@ static bool imb_save_openexr_half(ImBuf *ibuf, const char *filepath, const int f
uchar *from;
for (int i = ibuf->y - 1; i >= 0; i--) {
from = (uchar *)ibuf->rect + 4 * i * width;
from = ibuf->byte_buffer.data + 4 * i * width;
for (int j = ibuf->x; j > 0; j--) {
to->r = srgb_to_linearrgb(float(from[0]) / 255.0f);
@@ -575,7 +576,8 @@ static bool imb_save_openexr_float(ImBuf *ibuf, const char *filepath, const int
{
const int channels = ibuf->channels;
const bool is_alpha = (channels >= 4) && (ibuf->planes == 32);
const bool is_zbuf = (flags & IB_zbuffloat) && ibuf->zbuf_float != nullptr; /* summarize */
const bool is_zbuf = (flags & IB_zbuffloat) &&
ibuf->float_z_buffer.data != nullptr; /* summarize */
const int width = ibuf->x;
const int height = ibuf->y;
OStream *file_stream = nullptr;
@@ -613,7 +615,7 @@ static bool imb_save_openexr_float(ImBuf *ibuf, const char *filepath, const int
/* Last scan-line, stride negative. */
float *rect[4] = {nullptr, nullptr, nullptr, nullptr};
rect[0] = ibuf->rect_float + channels * (height - 1) * width;
rect[0] = ibuf->float_buffer.data + channels * (height - 1) * width;
rect[1] = (channels >= 2) ? rect[0] + 1 : rect[0];
rect[2] = (channels >= 3) ? rect[0] + 2 : rect[0];
rect[3] = (channels >= 4) ?
@@ -629,7 +631,7 @@ static bool imb_save_openexr_float(ImBuf *ibuf, const char *filepath, const int
if (is_zbuf) {
frameBuffer.insert("Z",
Slice(Imf::FLOAT,
(char *)(ibuf->zbuf_float + (height - 1) * width),
(char *)(ibuf->float_z_buffer.data + (height - 1) * width),
sizeof(float),
sizeof(float) * -width));
}
@@ -656,7 +658,7 @@ bool imb_save_openexr(struct ImBuf *ibuf, const char *filepath, int flags)
{
if (flags & IB_mem) {
imb_addencodedbufferImBuf(ibuf);
ibuf->encodedsize = 0;
ibuf->encoded_size = 0;
}
if (ibuf->foptions.flag & OPENEXR_HALF) {
@@ -664,7 +666,7 @@ bool imb_save_openexr(struct ImBuf *ibuf, const char *filepath, int flags)
}
/* when no float rect, we save as half (16 bits is sufficient) */
if (ibuf->rect_float == nullptr) {
if (ibuf->float_buffer.data == nullptr) {
return imb_save_openexr_half(ibuf, filepath, flags);
}
@@ -2081,7 +2083,7 @@ struct ImBuf *imb_load_openexr(const uchar *mem,
/* Inverse correct first pixel for data-window
* coordinates (- dw.min.y because of y flip). */
first = ibuf->rect_float - 4 * (dw.min.x - dw.min.y * width);
first = ibuf->float_buffer.data - 4 * (dw.min.x - dw.min.y * width);
/* But, since we read y-flipped (negative y stride) we move to last scan-line. */
first += 4 * (height - 1) * width;
@@ -2110,7 +2112,7 @@ struct ImBuf *imb_load_openexr(const uchar *mem,
float *firstz;
addzbuffloatImBuf(ibuf);
firstz = ibuf->zbuf_float - (dw.min.x - dw.min.y * width);
firstz = ibuf->float_z_buffer.data - (dw.min.x - dw.min.y * width);
firstz += (height - 1) * width;
frameBuffer.insert(
"Z", Slice(Imf::FLOAT, (char *)firstz, sizeof(float), -width * sizeof(float)));
@@ -2135,7 +2137,7 @@ struct ImBuf *imb_load_openexr(const uchar *mem,
if (num_rgb_channels == 0 && has_luma && exr_has_chroma(*file)) {
for (size_t a = 0; a < size_t(ibuf->x) * ibuf->y; a++) {
float *color = ibuf->rect_float + a * 4;
float *color = ibuf->float_buffer.data + a * 4;
ycc_to_rgb(color[0] * 255.0f,
color[1] * 255.0f,
color[2] * 255.0f,
@@ -2148,7 +2150,7 @@ struct ImBuf *imb_load_openexr(const uchar *mem,
else if (num_rgb_channels <= 1) {
/* Convert 1 to 3 channels. */
for (size_t a = 0; a < size_t(ibuf->x) * ibuf->y; a++) {
float *color = ibuf->rect_float + a * 4;
float *color = ibuf->float_buffer.data + a * 4;
if (num_rgb_channels <= 1) {
color[1] = color[0];
}
@@ -2238,7 +2240,7 @@ struct ImBuf *imb_load_filepath_thumbnail_openexr(const char *filepath,
if (file->header().hasPreviewImage()) {
const Imf::PreviewImage &preview = file->header().previewImage();
ImBuf *ibuf = IMB_allocFromBuffer(
(uint *)preview.pixels(), nullptr, preview.width(), preview.height(), 4);
(uint8_t *)preview.pixels(), nullptr, preview.width(), preview.height(), 4);
delete file;
delete stream;
IMB_flipy(ibuf);
@@ -2272,7 +2274,7 @@ struct ImBuf *imb_load_filepath_thumbnail_openexr(const char *filepath,
for (int w = 0; w < dest_w; w++) {
/* For each destination pixel find single corresponding source pixel. */
int source_x = int(MIN2((w / scale_factor), dw.max.x - 1));
float *dest_px = &ibuf->rect_float[(h * dest_w + w) * 4];
float *dest_px = &ibuf->float_buffer.data[(h * dest_w + w) * 4];
dest_px[0] = pixels[source_x].r;
dest_px[1] = pixels[source_x].g;
dest_px[2] = pixels[source_x].b;
+3 -3
View File
@@ -35,7 +35,7 @@ static void imb_handle_alpha(ImBuf *ibuf,
char effective_colorspace[IM_MAX_SPACE])
{
if (colorspace) {
if (ibuf->rect != nullptr && ibuf->rect_float == nullptr) {
if (ibuf->byte_buffer.data != nullptr && ibuf->float_buffer.data == nullptr) {
/* byte buffer is never internally converted to some standard space,
* store pointer to its color space descriptor instead
*/
@@ -59,7 +59,7 @@ static void imb_handle_alpha(ImBuf *ibuf,
}
else {
if (alpha_flags & IB_alphamode_premul) {
if (ibuf->rect) {
if (ibuf->byte_buffer.data) {
IMB_unpremultiply_alpha(ibuf);
}
else {
@@ -67,7 +67,7 @@ static void imb_handle_alpha(ImBuf *ibuf,
}
}
else {
if (ibuf->rect_float) {
if (ibuf->float_buffer.data) {
IMB_premultiply_alpha(ibuf);
}
else {
+42 -30
View File
@@ -252,10 +252,11 @@ void IMB_rect_crop(ImBuf *ibuf, const rcti *crop)
return;
}
rect_crop_4bytes((void **)&ibuf->rect, size_src, crop);
rect_crop_4bytes((void **)&ibuf->zbuf, size_src, crop);
rect_crop_4bytes((void **)&ibuf->zbuf_float, size_src, crop);
rect_crop_16bytes((void **)&ibuf->rect_float, size_src, crop);
/* TODO(sergey: Validate ownership. */
rect_crop_4bytes((void **)&ibuf->byte_buffer.data, size_src, crop);
rect_crop_4bytes((void **)&ibuf->z_buffer.data, size_src, crop);
rect_crop_4bytes((void **)&ibuf->float_z_buffer.data, size_src, crop);
rect_crop_16bytes((void **)&ibuf->float_buffer.data, size_src, crop);
ibuf->x = size_dst[0];
ibuf->y = size_dst[1];
@@ -289,10 +290,11 @@ void IMB_rect_size_set(ImBuf *ibuf, const uint size[2])
return;
}
rect_realloc_4bytes((void **)&ibuf->rect, size);
rect_realloc_4bytes((void **)&ibuf->zbuf, size);
rect_realloc_4bytes((void **)&ibuf->zbuf_float, size);
rect_realloc_16bytes((void **)&ibuf->rect_float, size);
/* TODO(sergey: Validate ownership. */
rect_realloc_4bytes((void **)&ibuf->byte_buffer.data, size);
rect_realloc_4bytes((void **)&ibuf->z_buffer.data, size);
rect_realloc_4bytes((void **)&ibuf->float_z_buffer.data, size);
rect_realloc_16bytes((void **)&ibuf->float_buffer.data, size);
ibuf->x = size[0];
ibuf->y = size[1];
@@ -533,16 +535,18 @@ void IMB_rectblend(ImBuf *dbuf,
return;
}
const bool do_char = (sbuf && sbuf->rect && dbuf->rect && obuf->rect);
const bool do_float = (sbuf && sbuf->rect_float && dbuf->rect_float && obuf->rect_float);
const bool do_char = (sbuf && sbuf->byte_buffer.data && dbuf->byte_buffer.data &&
obuf->byte_buffer.data);
const bool do_float = (sbuf && sbuf->float_buffer.data && dbuf->float_buffer.data &&
obuf->float_buffer.data);
if (do_char) {
drect = dbuf->rect + size_t(desty) * dbuf->x + destx;
orect = obuf->rect + size_t(origy) * obuf->x + origx;
drect = (uint *)dbuf->byte_buffer.data + size_t(desty) * dbuf->x + destx;
orect = (uint *)obuf->byte_buffer.data + size_t(origy) * obuf->x + origx;
}
if (do_float) {
drectf = dbuf->rect_float + (size_t(desty) * dbuf->x + destx) * 4;
orectf = obuf->rect_float + (size_t(origy) * obuf->x + origx) * 4;
drectf = dbuf->float_buffer.data + (size_t(desty) * dbuf->x + destx) * 4;
orectf = obuf->float_buffer.data + (size_t(origy) * obuf->x + origx) * 4;
}
if (dmaskrect) {
@@ -554,10 +558,10 @@ void IMB_rectblend(ImBuf *dbuf,
if (sbuf) {
if (do_char) {
srect = sbuf->rect + size_t(srcy) * sbuf->x + srcx;
srect = (uint *)sbuf->byte_buffer.data + size_t(srcy) * sbuf->x + srcx;
}
if (do_float) {
srectf = sbuf->rect_float + (size_t(srcy) * sbuf->x + srcx) * 4;
srectf = sbuf->float_buffer.data + (size_t(srcy) * sbuf->x + srcx) * 4;
}
srcskip = sbuf->x;
@@ -1049,8 +1053,8 @@ void IMB_rectfill(ImBuf *drect, const float col[4])
{
int num;
if (drect->rect) {
uint *rrect = drect->rect;
if (drect->byte_buffer.data) {
uint *rrect = (uint *)drect->byte_buffer.data;
char ccol[4];
ccol[0] = int(col[0] * 255);
@@ -1064,8 +1068,8 @@ void IMB_rectfill(ImBuf *drect, const float col[4])
}
}
if (drect->rect_float) {
float *rrectf = drect->rect_float;
if (drect->float_buffer.data) {
float *rrectf = drect->float_buffer.data;
num = drect->x * drect->y;
for (; num > 0; num--) {
@@ -1111,13 +1115,13 @@ void IMB_rectfill_area_replace(
for (int x = x1; x < x2; x++) {
size_t offset = size_t(ibuf->x) * y * 4 + 4 * x;
if (ibuf->rect) {
uchar *rrect = (uchar *)ibuf->rect + offset;
if (ibuf->byte_buffer.data) {
uchar *rrect = ibuf->byte_buffer.data + offset;
memcpy(rrect, col_char, sizeof(uchar[4]));
}
if (ibuf->rect_float) {
float *rrectf = ibuf->rect_float + offset;
if (ibuf->float_buffer.data) {
float *rrectf = ibuf->float_buffer.data + offset;
memcpy(rrectf, col, sizeof(float[4]));
}
}
@@ -1246,24 +1250,32 @@ void IMB_rectfill_area(ImBuf *ibuf,
if (!ibuf) {
return;
}
buf_rectfill_area(
(uchar *)ibuf->rect, ibuf->rect_float, ibuf->x, ibuf->y, col, display, x1, y1, x2, y2);
buf_rectfill_area(ibuf->byte_buffer.data,
ibuf->float_buffer.data,
ibuf->x,
ibuf->y,
col,
display,
x1,
y1,
x2,
y2);
}
void IMB_rectfill_alpha(ImBuf *ibuf, const float value)
{
int i;
if (ibuf->rect_float && (ibuf->channels == 4)) {
float *fbuf = ibuf->rect_float + 3;
if (ibuf->float_buffer.data && (ibuf->channels == 4)) {
float *fbuf = ibuf->float_buffer.data + 3;
for (i = ibuf->x * ibuf->y; i > 0; i--, fbuf += 4) {
*fbuf = value;
}
}
if (ibuf->rect) {
if (ibuf->byte_buffer.data) {
const uchar cvalue = value * 255;
uchar *cbuf = ((uchar *)ibuf->rect) + 3;
uchar *cbuf = ibuf->byte_buffer.data + 3;
for (i = ibuf->x * ibuf->y; i > 0; i--, cbuf += 4) {
*cbuf = cvalue;
}
+13 -12
View File
@@ -21,7 +21,7 @@ void IMB_flipy(struct ImBuf *ibuf)
return;
}
if (ibuf->rect) {
if (ibuf->byte_buffer.data) {
uint *top, *bottom, *line;
x_size = ibuf->x;
@@ -29,7 +29,7 @@ void IMB_flipy(struct ImBuf *ibuf)
const size_t stride = x_size * sizeof(int);
top = ibuf->rect;
top = (uint *)ibuf->byte_buffer.data;
bottom = top + ((y_size - 1) * x_size);
line = static_cast<uint *>(MEM_mallocN(stride, "linebuf"));
@@ -46,7 +46,7 @@ void IMB_flipy(struct ImBuf *ibuf)
MEM_freeN(line);
}
if (ibuf->rect_float) {
if (ibuf->float_buffer.data) {
float *topf = nullptr, *bottomf = nullptr, *linef = nullptr;
x_size = ibuf->x;
@@ -54,7 +54,7 @@ void IMB_flipy(struct ImBuf *ibuf)
const size_t stride = x_size * 4 * sizeof(float);
topf = ibuf->rect_float;
topf = ibuf->float_buffer.data;
bottomf = topf + 4 * ((y_size - 1) * x_size);
linef = static_cast<float *>(MEM_mallocN(stride, "linebuf"));
@@ -84,24 +84,25 @@ void IMB_flipx(struct ImBuf *ibuf)
x = ibuf->x;
y = ibuf->y;
if (ibuf->rect) {
if (ibuf->byte_buffer.data) {
uint *rect = (uint *)ibuf->byte_buffer.data;
for (yi = y - 1; yi >= 0; yi--) {
const size_t x_offset = size_t(x) * yi;
for (xr = x - 1, xl = 0; xr >= xl; xr--, xl++) {
SWAP(uint, ibuf->rect[x_offset + xr], ibuf->rect[x_offset + xl]);
SWAP(uint, rect[x_offset + xr], rect[x_offset + xl]);
}
}
}
if (ibuf->rect_float) {
if (ibuf->float_buffer.data) {
float *rect_float = ibuf->float_buffer.data;
for (yi = y - 1; yi >= 0; yi--) {
const size_t x_offset = size_t(x) * yi;
for (xr = x - 1, xl = 0; xr >= xl; xr--, xl++) {
memcpy(&px_f, &ibuf->rect_float[(x_offset + xr) * 4], sizeof(float[4]));
memcpy(&ibuf->rect_float[(x_offset + xr) * 4],
&ibuf->rect_float[(x_offset + xl) * 4],
sizeof(float[4]));
memcpy(&ibuf->rect_float[(x_offset + xl) * 4], &px_f, sizeof(float[4]));
memcpy(&px_f, &rect_float[(x_offset + xr) * 4], sizeof(float[4]));
memcpy(
&rect_float[(x_offset + xr) * 4], &rect_float[(x_offset + xl) * 4], sizeof(float[4]));
memcpy(&rect_float[(x_offset + xl) * 4], &px_f, sizeof(float[4]));
}
}
}
+111 -119
View File
@@ -28,14 +28,14 @@ static void imb_half_x_no_alloc(struct ImBuf *ibuf2, struct ImBuf *ibuf1)
float af, rf, gf, bf, *p1f, *_p1f, *destf;
bool do_rect, do_float;
do_rect = (ibuf1->rect != nullptr);
do_float = (ibuf1->rect_float != nullptr && ibuf2->rect_float != nullptr);
do_rect = (ibuf1->byte_buffer.data != nullptr);
do_float = (ibuf1->float_buffer.data != nullptr && ibuf2->float_buffer.data != nullptr);
_p1 = (uchar *)ibuf1->rect;
dest = (uchar *)ibuf2->rect;
_p1 = ibuf1->byte_buffer.data;
dest = ibuf2->byte_buffer.data;
_p1f = ibuf1->rect_float;
destf = ibuf2->rect_float;
_p1f = ibuf1->float_buffer.data;
destf = ibuf2->float_buffer.data;
for (y = ibuf2->y; y > 0; y--) {
p1 = _p1;
@@ -86,7 +86,7 @@ struct ImBuf *IMB_half_x(struct ImBuf *ibuf1)
if (ibuf1 == nullptr) {
return nullptr;
}
if (ibuf1->rect == nullptr && ibuf1->rect_float == nullptr) {
if (ibuf1->byte_buffer.data == nullptr && ibuf1->float_buffer.data == nullptr) {
return nullptr;
}
@@ -113,22 +113,22 @@ struct ImBuf *IMB_double_fast_x(struct ImBuf *ibuf1)
if (ibuf1 == nullptr) {
return nullptr;
}
if (ibuf1->rect == nullptr && ibuf1->rect_float == nullptr) {
if (ibuf1->byte_buffer.data == nullptr && ibuf1->float_buffer.data == nullptr) {
return nullptr;
}
do_rect = (ibuf1->rect != nullptr);
do_float = (ibuf1->rect_float != nullptr);
do_rect = (ibuf1->byte_buffer.data != nullptr);
do_float = (ibuf1->float_buffer.data != nullptr);
ibuf2 = IMB_allocImBuf(2 * ibuf1->x, ibuf1->y, ibuf1->planes, ibuf1->flags);
if (ibuf2 == nullptr) {
return nullptr;
}
p1 = (int *)ibuf1->rect;
dest = (int *)ibuf2->rect;
p1f = (float *)ibuf1->rect_float;
destf = (float *)ibuf2->rect_float;
p1 = (int *)ibuf1->byte_buffer.data;
dest = (int *)ibuf2->byte_buffer.data;
p1f = (float *)ibuf1->float_buffer.data;
destf = (float *)ibuf2->float_buffer.data;
for (i = ibuf1->y * ibuf1->x; i > 0; i--) {
if (do_rect) {
@@ -156,7 +156,7 @@ struct ImBuf *IMB_double_x(struct ImBuf *ibuf1)
if (ibuf1 == nullptr) {
return nullptr;
}
if (ibuf1->rect == nullptr && ibuf1->rect_float == nullptr) {
if (ibuf1->byte_buffer.data == nullptr && ibuf1->float_buffer.data == nullptr) {
return nullptr;
}
@@ -176,13 +176,14 @@ static void imb_half_y_no_alloc(struct ImBuf *ibuf2, struct ImBuf *ibuf1)
p1 = p2 = nullptr;
p1f = p2f = nullptr;
const bool do_rect = (ibuf1->rect != nullptr);
const bool do_float = (ibuf1->rect_float != nullptr && ibuf2->rect_float != nullptr);
const bool do_rect = (ibuf1->byte_buffer.data != nullptr);
const bool do_float = (ibuf1->float_buffer.data != nullptr &&
ibuf2->float_buffer.data != nullptr);
_p1 = (uchar *)ibuf1->rect;
dest = (uchar *)ibuf2->rect;
_p1f = (float *)ibuf1->rect_float;
destf = (float *)ibuf2->rect_float;
_p1 = ibuf1->byte_buffer.data;
dest = ibuf2->byte_buffer.data;
_p1f = (float *)ibuf1->float_buffer.data;
destf = (float *)ibuf2->float_buffer.data;
for (y = ibuf2->y; y > 0; y--) {
if (do_rect) {
@@ -239,7 +240,7 @@ struct ImBuf *IMB_half_y(struct ImBuf *ibuf1)
if (ibuf1 == nullptr) {
return nullptr;
}
if (ibuf1->rect == nullptr && ibuf1->rect_float == nullptr) {
if (ibuf1->byte_buffer.data == nullptr && ibuf1->float_buffer.data == nullptr) {
return nullptr;
}
@@ -267,22 +268,22 @@ struct ImBuf *IMB_double_fast_y(struct ImBuf *ibuf1)
if (ibuf1 == nullptr) {
return nullptr;
}
if (ibuf1->rect == nullptr && ibuf1->rect_float == nullptr) {
if (ibuf1->byte_buffer.data == nullptr && ibuf1->float_buffer.data == nullptr) {
return nullptr;
}
const bool do_rect = (ibuf1->rect != nullptr);
const bool do_float = (ibuf1->rect_float != nullptr);
const bool do_rect = (ibuf1->byte_buffer.data != nullptr);
const bool do_float = (ibuf1->float_buffer.data != nullptr);
ibuf2 = IMB_allocImBuf(ibuf1->x, 2 * ibuf1->y, ibuf1->planes, ibuf1->flags);
if (ibuf2 == nullptr) {
return nullptr;
}
p1 = (int *)ibuf1->rect;
dest1 = (int *)ibuf2->rect;
p1f = (float *)ibuf1->rect_float;
dest1f = (float *)ibuf2->rect_float;
p1 = (int *)ibuf1->byte_buffer.data;
dest1 = (int *)ibuf2->byte_buffer.data;
p1f = (float *)ibuf1->float_buffer.data;
dest1f = (float *)ibuf2->float_buffer.data;
for (y = ibuf1->y; y > 0; y--) {
if (do_rect) {
@@ -311,7 +312,7 @@ struct ImBuf *IMB_double_y(struct ImBuf *ibuf1)
if (ibuf1 == nullptr) {
return nullptr;
}
if (ibuf1->rect == nullptr) {
if (ibuf1->byte_buffer.data == nullptr) {
return nullptr;
}
@@ -355,10 +356,11 @@ MINLINE void premul_ushort_to_straight_uchar(uchar *result, const ushort color[4
void imb_onehalf_no_alloc(struct ImBuf *ibuf2, struct ImBuf *ibuf1)
{
int x, y;
const bool do_rect = (ibuf1->rect != nullptr);
const bool do_float = (ibuf1->rect_float != nullptr) && (ibuf2->rect_float != nullptr);
const bool do_rect = (ibuf1->byte_buffer.data != nullptr);
const bool do_float = (ibuf1->float_buffer.data != nullptr) &&
(ibuf2->float_buffer.data != nullptr);
if (do_rect && (ibuf2->rect == nullptr)) {
if (do_rect && (ibuf2->byte_buffer.data == nullptr)) {
imb_addrectImBuf(ibuf2);
}
@@ -374,8 +376,8 @@ void imb_onehalf_no_alloc(struct ImBuf *ibuf2, struct ImBuf *ibuf1)
if (do_rect) {
uchar *cp1, *cp2, *dest;
cp1 = (uchar *)ibuf1->rect;
dest = (uchar *)ibuf2->rect;
cp1 = ibuf1->byte_buffer.data;
dest = ibuf2->byte_buffer.data;
for (y = ibuf2->y; y > 0; y--) {
cp2 = cp1 + (ibuf1->x << 2);
@@ -408,8 +410,8 @@ void imb_onehalf_no_alloc(struct ImBuf *ibuf2, struct ImBuf *ibuf1)
if (do_float) {
float *p1f, *p2f, *destf;
p1f = ibuf1->rect_float;
destf = ibuf2->rect_float;
p1f = ibuf1->float_buffer.data;
destf = ibuf2->float_buffer.data;
for (y = ibuf2->y; y > 0; y--) {
p2f = p1f + (ibuf1->x << 2);
for (x = ibuf2->x; x > 0; x--) {
@@ -436,7 +438,7 @@ ImBuf *IMB_onehalf(struct ImBuf *ibuf1)
if (ibuf1 == nullptr) {
return nullptr;
}
if (ibuf1->rect == nullptr && ibuf1->rect_float == nullptr) {
if (ibuf1->byte_buffer.data == nullptr && ibuf1->float_buffer.data == nullptr) {
return nullptr;
}
@@ -854,22 +856,20 @@ static bool q_scale_linear_interpolation(struct ImBuf *ibuf, int newx, int newy)
return false;
}
if (ibuf->rect) {
if (ibuf->byte_buffer.data) {
uchar *newrect = static_cast<uchar *>(MEM_mallocN(sizeof(int) * newx * newy, "q_scale rect"));
q_scale_byte((uchar *)ibuf->rect, newrect, ibuf->x, ibuf->y, newx, newy);
q_scale_byte(ibuf->byte_buffer.data, newrect, ibuf->x, ibuf->y, newx, newy);
imb_freerectImBuf(ibuf);
ibuf->mall |= IB_rect;
ibuf->rect = (uint *)newrect;
IMB_assign_byte_buffer(ibuf, newrect, IB_TAKE_OWNERSHIP);
}
if (ibuf->rect_float) {
if (ibuf->float_buffer.data) {
float *newrect = static_cast<float *>(
MEM_mallocN(sizeof(float[4]) * newx * newy, "q_scale rectfloat"));
q_scale_float(ibuf->rect_float, newrect, ibuf->x, ibuf->y, newx, newy);
imb_freerectfloatImBuf(ibuf);
ibuf->mall |= IB_rectfloat;
ibuf->rect_float = newrect;
q_scale_float(ibuf->float_buffer.data, newrect, ibuf->x, ibuf->y, newx, newy);
IMB_assign_float_buffer(ibuf, newrect, IB_TAKE_OWNERSHIP);
}
ibuf->x = newx;
ibuf->y = newy;
@@ -878,8 +878,8 @@ static bool q_scale_linear_interpolation(struct ImBuf *ibuf, int newx, int newy)
static ImBuf *scaledownx(struct ImBuf *ibuf, int newx)
{
const bool do_rect = (ibuf->rect != nullptr);
const bool do_float = (ibuf->rect_float != nullptr);
const bool do_rect = (ibuf->byte_buffer.data != nullptr);
const bool do_float = (ibuf->float_buffer.data != nullptr);
const size_t rect_size = IMB_get_rect_len(ibuf) * 4;
uchar *rect, *_newrect, *newrect;
@@ -916,11 +916,11 @@ static ImBuf *scaledownx(struct ImBuf *ibuf, int newx)
add = (ibuf->x - 0.01) / newx;
if (do_rect) {
rect = (uchar *)ibuf->rect;
rect = ibuf->byte_buffer.data;
newrect = _newrect;
}
if (do_float) {
rectf = ibuf->rect_float;
rectf = ibuf->float_buffer.data;
newrectf = _newrectf;
}
@@ -999,19 +999,20 @@ static ImBuf *scaledownx(struct ImBuf *ibuf, int newx)
}
if (do_rect) {
// printf("%ld %ld\n", (uchar *)rect - ((uchar *)ibuf->rect), rect_size);
BLI_assert((uchar *)rect - ((uchar *)ibuf->rect) == rect_size); /* see bug #26502. */
// printf("%ld %ld\n", (uchar *)rect - ibuf->byte_buffer.data, rect_size);
BLI_assert((uchar *)rect - ibuf->byte_buffer.data == rect_size); /* see bug #26502. */
imb_freerectImBuf(ibuf);
ibuf->mall |= IB_rect;
ibuf->rect = (uint *)_newrect;
IMB_assign_byte_buffer(ibuf, _newrect, IB_TAKE_OWNERSHIP);
}
if (do_float) {
// printf("%ld %ld\n", rectf - ibuf->rect_float, rect_size);
BLI_assert((rectf - ibuf->rect_float) == rect_size); /* see bug #26502. */
// printf("%ld %ld\n", rectf - ibuf->float_buffer.data, rect_size);
BLI_assert((rectf - ibuf->float_buffer.data) == rect_size); /* see bug #26502. */
imb_freerectfloatImBuf(ibuf);
ibuf->mall |= IB_rectfloat;
ibuf->rect_float = _newrectf;
IMB_assign_float_buffer(ibuf, _newrectf, IB_TAKE_OWNERSHIP);
}
(void)rect_size; /* UNUSED in release builds */
ibuf->x = newx;
@@ -1020,8 +1021,8 @@ static ImBuf *scaledownx(struct ImBuf *ibuf, int newx)
static ImBuf *scaledowny(struct ImBuf *ibuf, int newy)
{
const bool do_rect = (ibuf->rect != nullptr);
const bool do_float = (ibuf->rect_float != nullptr);
const bool do_rect = (ibuf->byte_buffer.data != nullptr);
const bool do_float = (ibuf->float_buffer.data != nullptr);
const size_t rect_size = IMB_get_rect_len(ibuf) * 4;
uchar *rect, *_newrect, *newrect;
@@ -1060,11 +1061,11 @@ static ImBuf *scaledowny(struct ImBuf *ibuf, int newy)
for (x = skipx - 4; x >= 0; x -= 4) {
if (do_rect) {
rect = ((uchar *)ibuf->rect) + x;
rect = ibuf->byte_buffer.data + x;
newrect = _newrect + x;
}
if (do_float) {
rectf = ibuf->rect_float + x;
rectf = ibuf->float_buffer.data + x;
newrectf = _newrectf + x;
}
@@ -1142,19 +1143,20 @@ static ImBuf *scaledowny(struct ImBuf *ibuf, int newy)
}
if (do_rect) {
// printf("%ld %ld\n", (uchar *)rect - ((uchar *)ibuf->rect), rect_size);
BLI_assert((uchar *)rect - ((uchar *)ibuf->rect) == rect_size); /* see bug #26502. */
// printf("%ld %ld\n", (uchar *)rect - byte_buffer.data, rect_size);
BLI_assert((uchar *)rect - ibuf->byte_buffer.data == rect_size); /* see bug #26502. */
imb_freerectImBuf(ibuf);
ibuf->mall |= IB_rect;
ibuf->rect = (uint *)_newrect;
IMB_assign_byte_buffer(ibuf, _newrect, IB_TAKE_OWNERSHIP);
}
if (do_float) {
// printf("%ld %ld\n", rectf - ibuf->rect_float, rect_size);
BLI_assert((rectf - ibuf->rect_float) == rect_size); /* see bug #26502. */
// printf("%ld %ld\n", rectf - ibuf->float_buffer.data, rect_size);
BLI_assert((rectf - ibuf->float_buffer.data) == rect_size); /* see bug #26502. */
imb_freerectfloatImBuf(ibuf);
ibuf->mall |= IB_rectfloat;
ibuf->rect_float = (float *)_newrectf;
IMB_assign_float_buffer(ibuf, _newrectf, IB_TAKE_OWNERSHIP);
}
(void)rect_size; /* UNUSED in release builds */
ibuf->y = newy;
@@ -1171,18 +1173,18 @@ static ImBuf *scaleupx(struct ImBuf *ibuf, int newx)
if (ibuf == nullptr) {
return nullptr;
}
if (ibuf->rect == nullptr && ibuf->rect_float == nullptr) {
if (ibuf->byte_buffer.data == nullptr && ibuf->float_buffer.data == nullptr) {
return ibuf;
}
if (ibuf->rect) {
if (ibuf->byte_buffer.data) {
do_rect = true;
_newrect = static_cast<uchar *>(MEM_mallocN(newx * ibuf->y * sizeof(int), "scaleupx"));
if (_newrect == nullptr) {
return ibuf;
}
}
if (ibuf->rect_float) {
if (ibuf->float_buffer.data) {
do_float = true;
_newrectf = static_cast<float *>(MEM_mallocN(sizeof(float[4]) * newx * ibuf->y, "scaleupxf"));
if (_newrectf == nullptr) {
@@ -1193,8 +1195,8 @@ static ImBuf *scaleupx(struct ImBuf *ibuf, int newx)
}
}
rect = (uchar *)ibuf->rect;
rectf = (float *)ibuf->rect_float;
rect = ibuf->byte_buffer.data;
rectf = ibuf->float_buffer.data;
newrect = _newrect;
newrectf = _newrectf;
@@ -1350,13 +1352,11 @@ static ImBuf *scaleupx(struct ImBuf *ibuf, int newx)
if (do_rect) {
imb_freerectImBuf(ibuf);
ibuf->mall |= IB_rect;
ibuf->rect = (uint *)_newrect;
IMB_assign_byte_buffer(ibuf, _newrect, IB_TAKE_OWNERSHIP);
}
if (do_float) {
imb_freerectfloatImBuf(ibuf);
ibuf->mall |= IB_rectfloat;
ibuf->rect_float = (float *)_newrectf;
IMB_assign_float_buffer(ibuf, _newrectf, IB_TAKE_OWNERSHIP);
}
ibuf->x = newx;
@@ -1373,18 +1373,18 @@ static ImBuf *scaleupy(struct ImBuf *ibuf, int newy)
if (ibuf == nullptr) {
return nullptr;
}
if (ibuf->rect == nullptr && ibuf->rect_float == nullptr) {
if (ibuf->byte_buffer.data == nullptr && ibuf->float_buffer.data == nullptr) {
return ibuf;
}
if (ibuf->rect) {
if (ibuf->byte_buffer.data) {
do_rect = true;
_newrect = static_cast<uchar *>(MEM_mallocN(ibuf->x * newy * sizeof(int), "scaleupy"));
if (_newrect == nullptr) {
return ibuf;
}
}
if (ibuf->rect_float) {
if (ibuf->float_buffer.data) {
do_float = true;
_newrectf = static_cast<float *>(MEM_mallocN(sizeof(float[4]) * ibuf->x * newy, "scaleupyf"));
if (_newrectf == nullptr) {
@@ -1395,8 +1395,8 @@ static ImBuf *scaleupy(struct ImBuf *ibuf, int newy)
}
}
rect = (uchar *)ibuf->rect;
rectf = (float *)ibuf->rect_float;
rect = ibuf->byte_buffer.data;
rectf = ibuf->float_buffer.data;
newrect = _newrect;
newrectf = _newrectf;
@@ -1439,7 +1439,7 @@ static ImBuf *scaleupy(struct ImBuf *ibuf, int newy)
for (x = ibuf->x; x > 0; x--) {
sample = 0;
if (do_rect) {
rect = ((uchar *)ibuf->rect) + 4 * (x - 1);
rect = ibuf->byte_buffer.data + 4 * (x - 1);
newrect = _newrect + 4 * (x - 1);
val_a = rect[0];
@@ -1465,7 +1465,7 @@ static ImBuf *scaleupy(struct ImBuf *ibuf, int newy)
rect += 2 * skipx;
}
if (do_float) {
rectf = ibuf->rect_float + 4 * (x - 1);
rectf = ibuf->float_buffer.data + 4 * (x - 1);
newrectf = _newrectf + 4 * (x - 1);
val_af = rectf[0];
@@ -1553,13 +1553,11 @@ static ImBuf *scaleupy(struct ImBuf *ibuf, int newy)
if (do_rect) {
imb_freerectImBuf(ibuf);
ibuf->mall |= IB_rect;
ibuf->rect = (uint *)_newrect;
IMB_assign_byte_buffer(ibuf, _newrect, IB_TAKE_OWNERSHIP);
}
if (do_float) {
imb_freerectfloatImBuf(ibuf);
ibuf->mall |= IB_rectfloat;
ibuf->rect_float = (float *)_newrectf;
IMB_assign_float_buffer(ibuf, _newrectf, IB_TAKE_OWNERSHIP);
}
ibuf->y = newy;
@@ -1573,14 +1571,14 @@ static void scalefast_Z_ImBuf(ImBuf *ibuf, int newx, int newy)
int x, y;
int ofsx, ofsy, stepx, stepy;
if (ibuf->zbuf) {
if (ibuf->z_buffer.data) {
_newzbuf = static_cast<int *>(MEM_mallocN(newx * newy * sizeof(int), __func__));
if (_newzbuf == nullptr) {
IMB_freezbufImBuf(ibuf);
}
}
if (ibuf->zbuf_float) {
if (ibuf->float_z_buffer.data) {
_newzbuf_float = static_cast<float *>(
MEM_mallocN(size_t(newx) * newy * sizeof(float), __func__));
if (_newzbuf_float == nullptr) {
@@ -1601,7 +1599,7 @@ static void scalefast_Z_ImBuf(ImBuf *ibuf, int newx, int newy)
for (y = newy; y > 0; y--, ofsy += stepy) {
if (newzbuf) {
zbuf = ibuf->zbuf;
zbuf = ibuf->z_buffer.data;
zbuf += (ofsy >> 16) * ibuf->x;
ofsx = 32768;
for (x = newx; x > 0; x--, ofsx += stepx) {
@@ -1610,7 +1608,7 @@ static void scalefast_Z_ImBuf(ImBuf *ibuf, int newx, int newy)
}
if (newzbuf_float) {
zbuf_float = ibuf->zbuf_float;
zbuf_float = ibuf->float_z_buffer.data;
zbuf_float += (ofsy >> 16) * ibuf->x;
ofsx = 32768;
for (x = newx; x > 0; x--, ofsx += stepx) {
@@ -1621,14 +1619,12 @@ static void scalefast_Z_ImBuf(ImBuf *ibuf, int newx, int newy)
if (_newzbuf) {
IMB_freezbufImBuf(ibuf);
ibuf->mall |= IB_zbuf;
ibuf->zbuf = _newzbuf;
IMB_assign_z_buffer(ibuf, _newzbuf, IB_TAKE_OWNERSHIP);
}
if (_newzbuf_float) {
IMB_freezbuffloatImBuf(ibuf);
ibuf->mall |= IB_zbuffloat;
ibuf->zbuf_float = _newzbuf_float;
IMB_assign_float_z_buffer(ibuf, _newzbuf_float, IB_TAKE_OWNERSHIP);
}
}
@@ -1639,7 +1635,7 @@ bool IMB_scaleImBuf(struct ImBuf *ibuf, uint newx, uint newy)
if (ibuf == nullptr) {
return false;
}
if (ibuf->rect == nullptr && ibuf->rect_float == nullptr) {
if (ibuf->byte_buffer.data == nullptr && ibuf->float_buffer.data == nullptr) {
return false;
}
@@ -1697,10 +1693,10 @@ bool IMB_scalefastImBuf(struct ImBuf *ibuf, uint newx, uint newy)
if (ibuf == nullptr) {
return false;
}
if (ibuf->rect) {
if (ibuf->byte_buffer.data) {
do_rect = true;
}
if (ibuf->rect_float) {
if (ibuf->float_buffer.data) {
do_float = true;
}
if (do_rect == false && do_float == false) {
@@ -1737,7 +1733,7 @@ bool IMB_scalefastImBuf(struct ImBuf *ibuf, uint newx, uint newy)
for (y = newy; y > 0; y--, ofsy += stepy) {
if (do_rect) {
rect = ibuf->rect;
rect = (uint *)ibuf->byte_buffer.data;
rect += (ofsy >> 16) * ibuf->x;
ofsx = 32768;
@@ -1747,7 +1743,7 @@ bool IMB_scalefastImBuf(struct ImBuf *ibuf, uint newx, uint newy)
}
if (do_float) {
rectf = (struct imbufRGBA *)ibuf->rect_float;
rectf = (struct imbufRGBA *)ibuf->float_buffer.data;
rectf += (ofsy >> 16) * ibuf->x;
ofsx = 32768;
@@ -1759,14 +1755,12 @@ bool IMB_scalefastImBuf(struct ImBuf *ibuf, uint newx, uint newy)
if (do_rect) {
imb_freerectImBuf(ibuf);
ibuf->mall |= IB_rect;
ibuf->rect = _newrect;
IMB_assign_byte_buffer(ibuf, reinterpret_cast<uint8_t *>(_newrect), IB_TAKE_OWNERSHIP);
}
if (do_float) {
imb_freerectfloatImBuf(ibuf);
ibuf->mall |= IB_rectfloat;
ibuf->rect_float = (float *)_newrectf;
IMB_assign_float_buffer(ibuf, reinterpret_cast<float *>(_newrectf), IB_TAKE_OWNERSHIP);
}
scalefast_Z_ImBuf(ibuf, newx, newy);
@@ -1837,13 +1831,13 @@ static void *do_scale_thread(void *data_v)
if (data->byte_buffer) {
uchar *pixel = data->byte_buffer + 4 * offset;
BLI_bilinear_interpolation_char((uchar *)ibuf->rect, pixel, ibuf->x, ibuf->y, 4, u, v);
BLI_bilinear_interpolation_char(ibuf->byte_buffer.data, pixel, ibuf->x, ibuf->y, 4, u, v);
}
if (data->float_buffer) {
float *pixel = data->float_buffer + ibuf->channels * offset;
BLI_bilinear_interpolation_fl(
ibuf->rect_float, pixel, ibuf->x, ibuf->y, ibuf->channels, u, v);
ibuf->float_buffer.data, pixel, ibuf->x, ibuf->y, ibuf->channels, u, v);
}
}
}
@@ -1863,12 +1857,12 @@ void IMB_scaleImBuf_threaded(ImBuf *ibuf, uint newx, uint newy)
init_data.newx = newx;
init_data.newy = newy;
if (ibuf->rect) {
if (ibuf->byte_buffer.data) {
init_data.byte_buffer = static_cast<uchar *>(
MEM_mallocN(4 * newx * newy * sizeof(char), "threaded scale byte buffer"));
}
if (ibuf->rect_float) {
if (ibuf->float_buffer.data) {
init_data.float_buffer = static_cast<float *>(
MEM_mallocN(ibuf->channels * newx * newy * sizeof(float), "threaded scale float buffer"));
}
@@ -1881,15 +1875,13 @@ void IMB_scaleImBuf_threaded(ImBuf *ibuf, uint newx, uint newy)
ibuf->x = newx;
ibuf->y = newy;
if (ibuf->rect) {
if (ibuf->byte_buffer.data) {
imb_freerectImBuf(ibuf);
ibuf->mall |= IB_rect;
ibuf->rect = (uint *)init_data.byte_buffer;
IMB_assign_byte_buffer(ibuf, init_data.byte_buffer, IB_TAKE_OWNERSHIP);
}
if (ibuf->rect_float) {
if (ibuf->float_buffer.data) {
imb_freerectfloatImBuf(ibuf);
ibuf->mall |= IB_rectfloat;
ibuf->rect_float = init_data.float_buffer;
IMB_assign_float_buffer(ibuf, init_data.float_buffer, IB_TAKE_OWNERSHIP);
}
}
+23 -23
View File
@@ -616,7 +616,7 @@ static void imb_stereo3d_squeeze_rectf(
IMB_stereo3d_write_dimensions(s3d->display_mode, false, x, y, &width, &height);
ibuf = IMB_allocImBuf(width, height, channels, IB_rectfloat);
IMB_buffer_float_from_float(ibuf->rect_float,
IMB_buffer_float_from_float(ibuf->float_buffer.data,
rectf,
channels,
IB_PROFILE_LINEAR_RGB,
@@ -628,7 +628,7 @@ static void imb_stereo3d_squeeze_rectf(
width);
IMB_scaleImBuf_threaded(ibuf, x, y);
memcpy(rectf, ibuf->rect_float, x * y * sizeof(float[4]));
memcpy(rectf, ibuf->float_buffer.data, x * y * sizeof(float[4]));
IMB_freeImBuf(ibuf);
}
@@ -650,7 +650,7 @@ static void imb_stereo3d_squeeze_rect(
IMB_stereo3d_write_dimensions(s3d->display_mode, false, x, y, &width, &height);
ibuf = IMB_allocImBuf(width, height, channels, IB_rect);
IMB_buffer_byte_from_byte((uchar *)ibuf->rect,
IMB_buffer_byte_from_byte(ibuf->byte_buffer.data,
(uchar *)rect,
IB_PROFILE_SRGB,
IB_PROFILE_SRGB,
@@ -661,7 +661,7 @@ static void imb_stereo3d_squeeze_rect(
width);
IMB_scaleImBuf_threaded(ibuf, x, y);
memcpy(rect, ibuf->rect, x * y * sizeof(uint));
memcpy(rect, ibuf->byte_buffer.data, x * y * sizeof(uint));
IMB_freeImBuf(ibuf);
}
@@ -789,12 +789,12 @@ ImBuf *IMB_stereo3d_ImBuf(const ImageFormatData *im_format, ImBuf *ibuf_left, Im
ibuf_left->x,
ibuf_left->y,
ibuf_left->channels,
(int *)ibuf_left->rect,
(int *)ibuf_right->rect,
(int *)ibuf_stereo->rect,
ibuf_left->rect_float,
ibuf_right->rect_float,
ibuf_stereo->rect_float);
(int *)ibuf_left->byte_buffer.data,
(int *)ibuf_right->byte_buffer.data,
(int *)ibuf_stereo->byte_buffer.data,
ibuf_left->float_buffer.data,
ibuf_right->float_buffer.data,
ibuf_stereo->float_buffer.data);
imb_stereo3d_write_doit(&s3d_data, &im_format->stereo3d_format);
imb_stereo3d_squeeze_ImBuf(ibuf_stereo, &im_format->stereo3d_format, ibuf_left->x, ibuf_left->y);
@@ -1293,7 +1293,7 @@ void IMB_ImBufFromStereo3d(const Stereo3dFormat *s3d,
Stereo3DData s3d_data = {{nullptr}};
ImBuf *ibuf_left, *ibuf_right;
size_t width, height;
const bool is_float = (ibuf_stereo3d->rect_float != nullptr);
const bool is_float = (ibuf_stereo3d->float_buffer.data != nullptr);
IMB_stereo3d_read_dimensions(s3d->display_mode,
((s3d->flag & S3D_SQUEEZED_FRAME) == 0),
@@ -1331,12 +1331,12 @@ void IMB_ImBufFromStereo3d(const Stereo3dFormat *s3d,
ibuf_left->x,
ibuf_left->y,
ibuf_left->channels,
(int *)ibuf_left->rect,
(int *)ibuf_right->rect,
(int *)ibuf_stereo3d->rect,
ibuf_left->rect_float,
ibuf_right->rect_float,
ibuf_stereo3d->rect_float);
(int *)ibuf_left->byte_buffer.data,
(int *)ibuf_right->byte_buffer.data,
(int *)ibuf_stereo3d->byte_buffer.data,
ibuf_left->float_buffer.data,
ibuf_right->float_buffer.data,
ibuf_stereo3d->float_buffer.data);
imb_stereo3d_read_doit(&s3d_data, s3d);
@@ -1355,12 +1355,12 @@ void IMB_ImBufFromStereo3d(const Stereo3dFormat *s3d,
ibuf_left->x,
ibuf_left->y,
1,
(int *)ibuf_left->zbuf,
(int *)ibuf_right->zbuf,
(int *)ibuf_stereo3d->zbuf,
ibuf_left->zbuf_float,
ibuf_right->zbuf_float,
ibuf_stereo3d->zbuf_float);
ibuf_left->z_buffer.data,
ibuf_right->z_buffer.data,
ibuf_stereo3d->z_buffer.data,
ibuf_left->float_z_buffer.data,
ibuf_right->float_z_buffer.data,
ibuf_stereo3d->float_z_buffer.data);
imb_stereo3d_read_doit(&s3d_data, s3d);
}
+2 -2
View File
@@ -405,8 +405,8 @@ static ImBuf *thumb_create_ex(const char *file_path,
short ex = MAX2(1, short(img->x * scale));
short ey = MAX2(1, short(img->y * scale));
/* Save some time by only scaling byte buffer. */
if (img->rect_float) {
if (img->rect == nullptr) {
if (img->float_buffer.data) {
if (img->byte_buffer.data == nullptr) {
IMB_rect_from_float(img);
}
imb_freerectfloatImBuf(img);
+1 -1
View File
@@ -27,7 +27,7 @@ struct ImBuf *IMB_thumb_load_font(const char *filename, uint x, uint y)
const float col[4] = {1.0f, 1.0f, 1.0f, 0.0f};
IMB_rectfill(ibuf, col);
if (!BLF_thumb_preview(filename, (uchar *)ibuf->rect, ibuf->x, ibuf->y, ibuf->channels)) {
if (!BLF_thumb_preview(filename, ibuf->byte_buffer.data, ibuf->x, ibuf->y, ibuf->channels)) {
IMB_freeImBuf(ibuf);
ibuf = nullptr;
}
+8 -7
View File
@@ -221,11 +221,12 @@ class PixelPointer {
NumChannels;
if constexpr (std::is_same_v<StorageType, float>) {
pointer = image_buffer->rect_float + offset;
pointer = image_buffer->float_buffer.data + offset;
}
else if constexpr (std::is_same_v<StorageType, uchar>) {
pointer = const_cast<uchar *>(
static_cast<const uchar *>(static_cast<const void *>(image_buffer->rect)) + offset);
static_cast<const uchar *>(static_cast<const void *>(image_buffer->byte_buffer.data)) +
offset);
}
else {
pointer = nullptr;
@@ -401,7 +402,7 @@ class Sampler {
}
else if constexpr (Filter == IMB_FILTER_BILINEAR && std::is_same_v<StorageType, float>) {
if constexpr (std::is_same_v<UVWrapping, WrapRepeatUV>) {
BLI_bilinear_interpolation_wrap_fl(source->rect_float,
BLI_bilinear_interpolation_wrap_fl(source->float_buffer.data,
r_sample.data(),
source->x,
source->y,
@@ -412,7 +413,7 @@ class Sampler {
}
else {
const double2 wrapped_uv = uv_wrapper.modify_uv(source, uv);
BLI_bilinear_interpolation_fl(source->rect_float,
BLI_bilinear_interpolation_fl(source->float_buffer.data,
r_sample.data(),
source->x,
source->y,
@@ -448,7 +449,7 @@ class Sampler {
}
const size_t offset = (size_t(source->x) * y1 + x1) * NumChannels;
const float *dataF = source->rect_float + offset;
const float *dataF = source->float_buffer.data + offset;
for (int i = 0; i < NumChannels; i++) {
r_sample[i] = dataF[i];
}
@@ -701,10 +702,10 @@ static void transform_threaded(TransformUserData *user_data, const eIMBTransform
{
ScanlineThreadFunc scanline_func = nullptr;
if (user_data->dst->rect_float && user_data->src->rect_float) {
if (user_data->dst->float_buffer.data && user_data->src->float_buffer.data) {
scanline_func = get_scanline_function<Filter>(user_data, mode);
}
else if (user_data->dst->rect && user_data->src->rect) {
else if (user_data->dst->byte_buffer.data && user_data->src->byte_buffer.data) {
/* Number of channels is always 4 when using uchar buffers (sRGB + straight alpha). */
scanline_func = get_scanline_function<Filter, uchar, 4, 4>(mode);
}
+13 -9
View File
@@ -45,7 +45,7 @@ static void imb_gpu_get_format(const ImBuf *ibuf,
eGPUDataFormat *r_data_format,
eGPUTextureFormat *r_texture_format)
{
const bool float_rect = (ibuf->rect_float != nullptr);
const bool float_rect = (ibuf->float_buffer.data != nullptr);
const bool is_grayscale = use_grayscale && imb_is_grayscale_texture_format_compatible(ibuf);
if (float_rect) {
@@ -114,9 +114,10 @@ static void *imb_gpu_get_data(const ImBuf *ibuf,
const bool store_premultiplied,
bool *r_freedata)
{
bool is_float_rect = (ibuf->rect_float != nullptr);
bool is_float_rect = (ibuf->float_buffer.data != nullptr);
const bool is_grayscale = imb_is_grayscale_texture_format_compatible(ibuf);
void *data_rect = (is_float_rect) ? (void *)ibuf->rect_float : (void *)ibuf->rect;
void *data_rect = (is_float_rect) ? (void *)ibuf->float_buffer.data :
(void *)ibuf->byte_buffer.data;
bool freedata = false;
if (is_float_rect) {
@@ -192,7 +193,7 @@ static void *imb_gpu_get_data(const ImBuf *ibuf,
}
if (do_rescale) {
uint *rect = (is_float_rect) ? nullptr : (uint *)data_rect;
uint8_t *rect = (is_float_rect) ? nullptr : (uint8_t *)data_rect;
float *rect_float = (is_float_rect) ? (float *)data_rect : nullptr;
ImBuf *scale_ibuf = IMB_allocFromBuffer(rect, rect_float, ibuf->x, ibuf->y, 4);
@@ -202,11 +203,12 @@ static void *imb_gpu_get_data(const ImBuf *ibuf,
MEM_freeN(data_rect);
}
data_rect = (is_float_rect) ? (void *)scale_ibuf->rect_float : (void *)scale_ibuf->rect;
data_rect = (is_float_rect) ? (void *)scale_ibuf->float_buffer.data :
(void *)scale_ibuf->byte_buffer.data;
*r_freedata = freedata = true;
/* Steal the rescaled buffer to avoid double free. */
scale_ibuf->rect_float = nullptr;
scale_ibuf->rect = nullptr;
(void)IMB_steal_byte_buffer(scale_ibuf);
(void)IMB_steal_float_buffer(scale_ibuf);
IMB_freeImBuf(scale_ibuf);
}
@@ -411,14 +413,16 @@ void IMB_gpu_clamp_half_float(ImBuf *image_buffer)
{
const float half_min = -65504;
const float half_max = 65504;
if (!image_buffer->rect_float) {
if (!image_buffer->float_buffer.data) {
return;
}
float *rect_float = image_buffer->float_buffer.data;
int rect_float_len = image_buffer->x * image_buffer->y *
(image_buffer->channels == 0 ? 4 : image_buffer->channels);
for (int i = 0; i < rect_float_len; i++) {
image_buffer->rect_float[i] = clamp_f(image_buffer->rect_float[i], half_min, half_max);
rect_float[i] = clamp_f(rect_float[i], half_min, half_max);
}
}
+4 -4
View File
@@ -63,7 +63,7 @@ ImBuf *imb_loadwebp(const uchar *mem, size_t size, int flags, char colorspace[IM
ibuf->ftype = IMB_FTYPE_WEBP;
imb_addrectImBuf(ibuf);
/* Flip the image during decoding to match Blender. */
uchar *last_row = (uchar *)(ibuf->rect + (ibuf->y - 1) * ibuf->x);
uchar *last_row = ibuf->byte_buffer.data + 4 * (ibuf->y - 1) * ibuf->x;
if (WebPDecodeRGBAInto(mem, size, last_row, size_t(ibuf->x) * ibuf->y * 4, -4 * ibuf->x) ==
nullptr)
{
@@ -136,7 +136,7 @@ struct ImBuf *imb_load_filepath_thumbnail_webp(const char *filepath,
config.options.flip = 1;
config.output.is_external_memory = 1;
config.output.colorspace = MODE_RGBA;
config.output.u.RGBA.rgba = (uint8_t *)ibuf->rect;
config.output.u.RGBA.rgba = ibuf->byte_buffer.data;
config.output.u.RGBA.stride = 4 * ibuf->x;
config.output.u.RGBA.size = size_t(config.output.u.RGBA.stride * ibuf->y);
@@ -167,7 +167,7 @@ bool imb_savewebp(struct ImBuf *ibuf, const char *filepath, int /*flags*/)
if (bytesperpixel == 3) {
/* We must convert the ImBuf RGBA buffer to RGB as WebP expects a RGB buffer. */
const size_t num_pixels = ibuf->x * ibuf->y;
const uint8_t *rgba_rect = (uint8_t *)ibuf->rect;
const uint8_t *rgba_rect = ibuf->byte_buffer.data;
uint8_t *rgb_rect = static_cast<uint8_t *>(
MEM_mallocN(sizeof(uint8_t) * num_pixels * 3, "webp rgb_rect"));
for (int i = 0; i < num_pixels; i++) {
@@ -189,7 +189,7 @@ bool imb_savewebp(struct ImBuf *ibuf, const char *filepath, int /*flags*/)
MEM_freeN(rgb_rect);
}
else if (bytesperpixel == 4) {
last_row = (uchar *)(ibuf->rect + (ibuf->y - 1) * ibuf->x);
last_row = ibuf->byte_buffer.data + 4 * (ibuf->y - 1) * ibuf->x;
if (ibuf->foptions.quality == 100.0f) {
encoded_data_size = WebPEncodeLosslessRGBA(
+1 -1
View File
@@ -42,7 +42,7 @@ bool IMB_saveiff(struct ImBuf *ibuf, const char *filepath, int flags)
* have already created this byte buffer. This is a basic fallback for other
* cases where we do not have a specific desired output colorspace. */
if (!(type->flag & IM_FTYPE_FLOAT)) {
if (ibuf->rect == nullptr && ibuf->rect_float) {
if (ibuf->byte_buffer.data == nullptr && ibuf->float_buffer.data) {
ibuf->rect_colorspace = colormanage_colorspace_get_roled(COLOR_ROLE_DEFAULT_BYTE);
IMB_rect_from_float(ibuf);
}
+1
View File
@@ -5,6 +5,7 @@ set(INC
.
../../blenlib
../../imbuf
../../makesdna
../../../../intern/guardedalloc
)

Some files were not shown because too many files have changed in this diff Show More