Color management: make it behave closer to trunk

Avoid using tricks with ibuf->profile to check whether image buffer is
in sequencer or linear space. Assume the whole sequencer works in non
linear float space and do transformation to linear where it;s needed
only.

This removes confusion from the code, fixes wrong behavior of some
effects.
This commit is contained in:
Sergey Sharybin
2012-08-30 13:40:31 +00:00
parent 63197444b4
commit 70301f431c
6 changed files with 41 additions and 35 deletions

View File

@@ -140,8 +140,6 @@ static ImBuf *prepare_effect_imbufs(SeqRenderData context, ImBuf *ibuf1, ImBuf *
IMB_rect_from_float(ibuf3);
}
out->profile = IB_PROFILE_SRGB;
return out;
}

View File

@@ -2461,7 +2461,8 @@ static ImBuf *do_render_strip_uncached(SeqRenderData context, Sequence *seq, flo
imb_freerectImBuf(ibuf);
/* all sequencer color is done in SRGB space, linear gives odd crossfades */
IMB_colormanagement_imbuf_to_sequencer_space(ibuf, FALSE);
if (ibuf->profile == IB_PROFILE_LINEAR_RGB)
IMB_colormanagement_imbuf_to_sequencer_space(ibuf, FALSE);
copy_to_ibuf_still(context, seq, nr, ibuf);
@@ -2653,18 +2654,13 @@ static ImBuf *seq_render_strip_stack(SeqRenderData context, ListBase *seqbasep,
if (count == 1) {
out = seq_render_strip(context, seq_arr[0], cfra);
if (out) {
/* put buffer back to linear space */
IMB_colormanagement_imbuf_from_sequencer_space(out);
}
out->colormanage_flags |= IMB_COLORMANAGE_NOLINEAR_FLOAT;
BKE_sequencer_cache_put(context, seq_arr[0], cfra, SEQ_STRIPELEM_IBUF_COMP, out);
return out;
}
for (i = count - 1; i >= 0; i--) {
int early_out;
Sequence *seq = seq_arr[i];
@@ -2738,10 +2734,7 @@ static ImBuf *seq_render_strip_stack(SeqRenderData context, ListBase *seqbasep,
BKE_sequencer_cache_put(context, seq_arr[i], cfra, SEQ_STRIPELEM_IBUF_COMP, out);
}
if (out) {
/* put buffer back to linear space */
IMB_colormanagement_imbuf_from_sequencer_space(out);
}
out->colormanage_flags |= IMB_COLORMANAGE_NOLINEAR_FLOAT;
return out;
}

View File

@@ -128,6 +128,7 @@ typedef struct ImBuf {
unsigned int encodedbuffersize; /* Size of encodedbuffer */
/* color management */
int colormanage_flags;
unsigned int *display_buffer_flags; /* array of per-display display buffers dirty flags */
struct ColormanageCache *colormanage_cache; /* cache used by color management */
@@ -258,4 +259,9 @@ extern const char *imb_ext_image_qt[];
extern const char *imb_ext_movie[];
extern const char *imb_ext_audio[];
/* ImBuf->colormanage_flags */
enum {
IMB_COLORMANAGE_NOLINEAR_FLOAT = (1 << 0)
};
#endif

View File

@@ -616,6 +616,8 @@ typedef struct DisplayBufferThread {
int channels;
int dither;
int predivide;
int nolinear_float;
} DisplayBufferThread;
typedef struct DisplayBufferInitData {
@@ -659,6 +661,8 @@ static void display_buffer_init_handle(void *handle_v, int start_line, int tot_l
handle->channels = channels;
handle->dither = dither;
handle->predivide = predivide;
handle->nolinear_float = ibuf->colormanage_flags & IMB_COLORMANAGE_NOLINEAR_FLOAT;
}
static void display_buffer_apply_threaded(ImBuf *ibuf, float *buffer, unsigned char *byte_buffer,
@@ -703,6 +707,20 @@ static void *display_buffer_apply_get_linear_buffer(DisplayBufferThread *handle)
IB_PROFILE_LINEAR_RGB, IB_PROFILE_SRGB,
predivide, width, height, width, width);
}
else if (handle->nolinear_float) {
/* currently float is non-linear only in sequencer, which is working
* in it's own color space even to handle float buffers, so we need to ensure
* float buffer is in linear space before applying all the view transformations
*/
const char *from_colorspace = global_role_sequencer;
const char *to_colorspace = global_role_scene_linear;
memcpy(linear_buffer, handle->buffer, buffer_size * sizeof(float));
IMB_colormanagement_colorspace_transform(linear_buffer, width, height, channels,
from_colorspace, to_colorspace);
}
else {
/* some processors would want to modify float original buffer
* before converting it into display byte buffer, so we need to
@@ -1060,9 +1078,6 @@ void IMB_colormanagement_imbuf_from_role(ImBuf *ibuf, int role)
IMB_colormanagement_colorspace_transform(ibuf->rect_float, ibuf->x, ibuf->y, ibuf->channels,
from_colorspace, to_colorspace);
/* buffer in now in scene linear space */
ibuf->profile = IB_PROFILE_LINEAR_RGB;
}
#else
(void) ibuf;
@@ -1118,13 +1133,13 @@ void IMB_colormanagement_imbuf_to_sequencer_space(ImBuf *ibuf, int make_float)
if (global_role_sequencer[0]) {
IMB_colormanagement_imbuf_to_role(ibuf, COLOR_ROLE_SEQUENCER);
ibuf->profile = IB_PROFILE_SRGB;
ibuf->profile = IB_PROFILE_NONE;
}
else
#endif
{
/* if no sequencer's working space defined fallback to legacy sRGB space */
IMB_convert_profile(ibuf, IB_PROFILE_SRGB);
IMB_convert_profile(ibuf, IB_PROFILE_NONE);
}
}
@@ -1135,10 +1150,8 @@ void IMB_colormanagement_imbuf_from_sequencer_space(ImBuf *ibuf)
#ifdef WITH_OCIO
if (global_role_sequencer[0]) {
if (ibuf->profile == IB_PROFILE_SRGB) {
IMB_colormanagement_imbuf_from_role(ibuf, COLOR_ROLE_SEQUENCER);
ibuf->profile = IB_PROFILE_LINEAR_RGB;
}
IMB_colormanagement_imbuf_from_role(ibuf, COLOR_ROLE_SEQUENCER);
ibuf->profile = IB_PROFILE_LINEAR_RGB;
}
else
#endif

View File

@@ -1648,7 +1648,7 @@ int RE_seq_render_active(Scene *scene, RenderData *rd)
static void do_render_seq(Render *re)
{
static int recurs_depth = 0;
struct ImBuf *ibuf;
struct ImBuf *ibuf, *out;
RenderResult *rr; /* don't assign re->result here as it might change during give_ibuf_seq */
int cfra = re->r.cfra;
SeqRenderData context;
@@ -1675,7 +1675,11 @@ static void do_render_seq(Render *re)
100);
}
ibuf = BKE_sequencer_give_ibuf(context, cfra, 0);
out = BKE_sequencer_give_ibuf(context, cfra, 0);
ibuf = IMB_dupImBuf(out);
IMB_freeImBuf(out);
IMB_colormanagement_imbuf_from_sequencer_space(ibuf);
recurs_depth--;

View File

@@ -1089,22 +1089,14 @@ ImBuf *render_result_rect_to_ibuf(RenderResult *rr, RenderData *rd)
return ibuf;
}
void render_result_rect_from_ibuf(RenderResult *rr, RenderData *rd, ImBuf *ibuf)
void render_result_rect_from_ibuf(RenderResult *rr, RenderData *UNUSED(rd), ImBuf *ibuf)
{
if (ibuf->rect_float) {
/* color management: when off ensure rectf is non-lin, since thats what the internal
* render engine delivers */
int profile_to = (rd->color_mgt_flag & R_COLOR_MANAGEMENT) ? IB_PROFILE_LINEAR_RGB : IB_PROFILE_SRGB;
int profile_from = (ibuf->profile == IB_PROFILE_LINEAR_RGB) ? IB_PROFILE_LINEAR_RGB : IB_PROFILE_SRGB;
int predivide = (rd->color_mgt_flag & R_COLOR_MANAGEMENT_PREDIVIDE);
if (!rr->rectf)
rr->rectf = MEM_mallocN(4 * sizeof(float) * rr->rectx * rr->recty, "render_seq rectf");
IMB_buffer_float_from_float(rr->rectf, ibuf->rect_float,
4, profile_to, profile_from, predivide,
rr->rectx, rr->recty, rr->rectx, rr->rectx);
memcpy(rr->rectf, ibuf->rect_float, 4 * sizeof(float) * rr->rectx * rr->recty);
/* TSK! Since sequence render doesn't free the *rr render result, the old rect32
* can hang around when sequence render has rendered a 32 bits one before */
if (rr->rect32) {