Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/imbuf/intern/divers.c')
-rw-r--r--source/blender/imbuf/intern/divers.c81
1 files changed, 54 insertions, 27 deletions
diff --git a/source/blender/imbuf/intern/divers.c b/source/blender/imbuf/intern/divers.c
index f049c404e2d..f0d8b7cac72 100644
--- a/source/blender/imbuf/intern/divers.c
+++ b/source/blender/imbuf/intern/divers.c
@@ -39,6 +39,7 @@
#include "IMB_imbuf_types.h"
#include "IMB_imbuf.h"
#include "IMB_allocimbuf.h"
+#include "IMB_filter.h"
#include "IMB_colormanagement.h"
#include "IMB_colormanagement_intern.h"
@@ -249,11 +250,25 @@ void IMB_buffer_byte_from_float(uchar *rect_to, const float *rect_from,
uchar *to = rect_to + stride_to * y * 4;
if (profile_to == profile_from) {
+ float straight[4];
+
/* no color space conversion */
- if (dither) {
+ if (dither && predivide) {
+ for (x = 0; x < width; x++, from += 4, to += 4) {
+ premul_to_straight_v4(straight, from);
+ float_to_byte_dither_v4(to, straight, di);
+ }
+ }
+ else if (dither) {
for (x = 0; x < width; x++, from += 4, to += 4)
float_to_byte_dither_v4(to, from, di);
}
+ else if (predivide) {
+ for (x = 0; x < width; x++, from += 4, to += 4) {
+ premul_to_straight_v4(straight, from);
+ rgba_float_to_uchar(to, straight);
+ }
+ }
else {
for (x = 0; x < width; x++, from += 4, to += 4)
rgba_float_to_uchar(to, from);
@@ -262,10 +277,12 @@ void IMB_buffer_byte_from_float(uchar *rect_to, const float *rect_from,
else if (profile_to == IB_PROFILE_SRGB) {
/* convert from linear to sRGB */
unsigned short us[4];
+ float straight[4];
if (dither && predivide) {
for (x = 0; x < width; x++, from += 4, to += 4) {
- linearrgb_to_srgb_ushort4_predivide(us, from);
+ premul_to_straight_v4(straight, from);
+ linearrgb_to_srgb_ushort4(us, from);
ushort_to_byte_dither_v4(to, us, di);
}
}
@@ -277,7 +294,8 @@ void IMB_buffer_byte_from_float(uchar *rect_to, const float *rect_from,
}
else if (predivide) {
for (x = 0; x < width; x++, from += 4, to += 4) {
- linearrgb_to_srgb_ushort4_predivide(us, from);
+ premul_to_straight_v4(straight, from);
+ linearrgb_to_srgb_ushort4(us, from);
ushort_to_byte_v4(to, us);
}
}
@@ -526,7 +544,6 @@ void IMB_buffer_byte_from_byte(uchar *rect_to, const uchar *rect_from,
void IMB_rect_from_float(ImBuf *ibuf)
{
- int predivide = (ibuf->flags & IB_cm_predivide);
float *buffer;
const char *from_colorspace;
@@ -548,7 +565,10 @@ void IMB_rect_from_float(ImBuf *ibuf)
buffer = MEM_dupallocN(ibuf->rect_float);
/* first make float buffer in byte space */
- IMB_colormanagement_transform(buffer, ibuf->x, ibuf->y, ibuf->channels, from_colorspace, ibuf->rect_colorspace->name, predivide);
+ IMB_colormanagement_transform(buffer, ibuf->x, ibuf->y, ibuf->channels, from_colorspace, ibuf->rect_colorspace->name, TRUE);
+
+ /* convert from float's premul alpha to byte's straight alpha */
+ IMB_unpremultiply_rect_float(buffer, ibuf->planes, ibuf->x, ibuf->y);
/* convert float to byte */
IMB_buffer_byte_from_float((unsigned char *) ibuf->rect, buffer, ibuf->channels, ibuf->dither, IB_PROFILE_SRGB, IB_PROFILE_SRGB,
@@ -565,7 +585,6 @@ void IMB_partial_rect_from_float(ImBuf *ibuf, float *buffer, int x, int y, int w
{
float *rect_float;
uchar *rect_byte;
- int predivide = (ibuf->flags & IB_cm_predivide);
int profile_from = IB_PROFILE_LINEAR_RGB;
/* verify we have a float buffer */
@@ -588,12 +607,12 @@ void IMB_partial_rect_from_float(ImBuf *ibuf, float *buffer, int x, int y, int w
/* and do color space conversion to byte */
IMB_buffer_byte_from_float(rect_byte, rect_float,
- 4, ibuf->dither, IB_PROFILE_SRGB, profile_from, predivide,
+ 4, ibuf->dither, IB_PROFILE_SRGB, profile_from, TRUE,
w, h, ibuf->x, w);
}
else {
IMB_buffer_float_from_float(buffer, rect_float,
- ibuf->channels, IB_PROFILE_SRGB, profile_from, predivide,
+ ibuf->channels, IB_PROFILE_SRGB, profile_from, TRUE,
w, h, w, ibuf->x);
/* XXX: need to convert to image buffer's rect space */
@@ -608,8 +627,6 @@ void IMB_partial_rect_from_float(ImBuf *ibuf, float *buffer, int x, int y, int w
void IMB_float_from_rect(ImBuf *ibuf)
{
- int predivide = (ibuf->flags & IB_cm_predivide);
-
/* verify if we byte and float buffers */
if (ibuf->rect == NULL)
return;
@@ -634,22 +651,12 @@ void IMB_float_from_rect(ImBuf *ibuf)
/* then make float be in linear space */
IMB_colormanagement_colorspace_to_scene_linear(ibuf->rect_float, ibuf->x, ibuf->y, ibuf->channels,
- ibuf->rect_colorspace, predivide);
-
- BLI_unlock_thread(LOCK_COLORMANAGE);
-}
-
-/* no profile conversion */
-void IMB_float_from_rect_simple(ImBuf *ibuf)
-{
- int predivide = (ibuf->flags & IB_cm_predivide);
+ ibuf->rect_colorspace, FALSE);
- if (ibuf->rect_float == NULL)
- imb_addrectfloatImBuf(ibuf);
+ /* byte buffer is straight alpha, float should always be premul */
+ IMB_premultiply_rect_float(ibuf->rect_float, ibuf->planes, ibuf->x, ibuf->y);
- IMB_buffer_float_from_byte(ibuf->rect_float, (uchar *)ibuf->rect,
- IB_PROFILE_SRGB, IB_PROFILE_SRGB, predivide,
- ibuf->x, ibuf->y, ibuf->x, ibuf->x);
+ BLI_unlock_thread(LOCK_COLORMANAGE);
}
/* use when you need to get a buffer with a certain profile
@@ -660,7 +667,6 @@ void IMB_float_from_rect_simple(ImBuf *ibuf)
*/
float *IMB_float_profile_ensure(ImBuf *ibuf, int profile, int *alloc)
{
- int predivide = (ibuf->flags & IB_cm_predivide);
int profile_from = IB_PROFILE_LINEAR_RGB;
int profile_to;
@@ -686,12 +692,13 @@ float *IMB_float_profile_ensure(ImBuf *ibuf, int profile, int *alloc)
if (ibuf->rect_float == NULL) {
IMB_buffer_float_from_byte(fbuf, (uchar *)ibuf->rect,
- profile_to, profile_from, predivide,
+ profile_to, profile_from, FALSE,
ibuf->x, ibuf->y, ibuf->x, ibuf->x);
+ IMB_premultiply_rect_float(ibuf->rect_float, ibuf->planes, ibuf->x, ibuf->y);
}
else {
IMB_buffer_float_from_float(fbuf, ibuf->rect_float,
- 4, profile_to, profile_from, predivide,
+ 4, profile_to, profile_from, TRUE,
ibuf->x, ibuf->y, ibuf->x, ibuf->x);
}
@@ -727,6 +734,26 @@ void IMB_buffer_float_clamp(float *buf, int width, int height)
}
}
+void IMB_buffer_float_unpremultiply(float *buf, int width, int height)
+{
+ int total = width * height;
+ float *cp = buf;
+ while (total--) {
+ premul_to_straight_v4(cp, cp);
+ cp += 4;
+ }
+}
+
+void IMB_buffer_float_premultiply(float *buf, int width, int height)
+{
+ int total = width * height;
+ float *cp = buf;
+ while (total--) {
+ straight_to_premul_v4(cp, cp);
+ cp += 4;
+ }
+}
+
/**************************** alter saturation *****************************/
void IMB_saturation(ImBuf *ibuf, float sat)