Color management support for sequencer
This adds color management controls to the sequencer space, which are applying on the displaying image. Currently used the same UI approach as was used for other areas, but this would probably be cleaned up in the nearest future. This required a bit of hackish stuff to be done, Namely color management for the sequencer requires one extra step in the conversion chain to convert sRGB float buffer to linear space. This was made by setting special flag in ImBuf. Later this could be done using input color space for the ImBuf probably.
This commit is contained in:
@@ -19,6 +19,7 @@
|
||||
# <pep8 compliant>
|
||||
import bpy
|
||||
from bpy.types import Header, Menu, Panel
|
||||
from bl_ui.properties_color_management import ColorManagedViewSettingsPanel
|
||||
|
||||
|
||||
def act_strip(context):
|
||||
@@ -860,5 +861,8 @@ class SEQUENCER_PT_view(SequencerButtonsPanel_Output, Panel):
|
||||
col.prop(st, "show_separate_color")
|
||||
col.prop(st, "proxy_render_size")
|
||||
|
||||
class SEQUENCER_PT_display_properties(SequencerButtonsPanel_Output, Panel, ColorManagedViewSettingsPanel):
|
||||
bl_label = "Display Properties"
|
||||
|
||||
if __name__ == "__main__": # only for live edit.
|
||||
bpy.utils.register_module(__name__)
|
||||
|
||||
@@ -52,6 +52,7 @@
|
||||
|
||||
#include "BKE_sound.h"
|
||||
|
||||
#include "IMB_colormanagement.h"
|
||||
#include "IMB_imbuf.h"
|
||||
|
||||
#include "BIF_gl.h"
|
||||
@@ -68,6 +69,9 @@
|
||||
#include "UI_resources.h"
|
||||
#include "UI_view2d.h"
|
||||
|
||||
#include "WM_api.h"
|
||||
#include "WM_types.h"
|
||||
|
||||
/* own include */
|
||||
#include "sequencer_intern.h"
|
||||
|
||||
@@ -812,6 +816,8 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq
|
||||
GLuint texid;
|
||||
GLuint last_texid;
|
||||
SeqRenderData context;
|
||||
unsigned char *display_buffer;
|
||||
void *cache_handle = NULL;
|
||||
|
||||
render_size = sseq->render_size;
|
||||
if (render_size == 0) {
|
||||
@@ -892,12 +898,23 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq
|
||||
if (scope) {
|
||||
IMB_freeImBuf(ibuf);
|
||||
ibuf = scope;
|
||||
|
||||
if (ibuf->rect_float && ibuf->rect == NULL) {
|
||||
IMB_rect_from_float(ibuf);
|
||||
}
|
||||
|
||||
display_buffer = (unsigned char *)ibuf->rect;
|
||||
}
|
||||
else {
|
||||
const ColorManagedViewSettings *view_settings;
|
||||
wmWindow *win = CTX_wm_window(C);
|
||||
|
||||
ibuf->colormanagement_flags |= IMB_COLORMANAGEMENT_SRGB_SOURCE;
|
||||
|
||||
view_settings = IMB_view_settings_get_effective(win, &sseq->view_settings);
|
||||
display_buffer = IMB_display_buffer_acquire(ibuf, view_settings, &win->display_settings, &cache_handle);
|
||||
}
|
||||
|
||||
if (ibuf->rect_float && ibuf->rect == NULL) {
|
||||
IMB_rect_from_float(ibuf);
|
||||
}
|
||||
|
||||
/* setting up the view - actual drawing starts here */
|
||||
UI_view2d_view_ortho(v2d);
|
||||
|
||||
@@ -910,7 +927,7 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, ibuf->x, ibuf->y, 0, GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, ibuf->x, ibuf->y, 0, GL_RGBA, GL_UNSIGNED_BYTE, display_buffer);
|
||||
glBegin(GL_QUADS);
|
||||
|
||||
if (frame_ofs) {
|
||||
@@ -1042,6 +1059,8 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq
|
||||
}
|
||||
}
|
||||
|
||||
if (cache_handle)
|
||||
IMB_display_buffer_release(cache_handle);
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
@@ -128,6 +128,7 @@ typedef struct ImBuf {
|
||||
unsigned int encodedbuffersize; /* Size of encodedbuffer */
|
||||
|
||||
/* color management */
|
||||
unsigned int colormanagement_flags; /* flags filed used by color management rutines */
|
||||
unsigned int *display_buffer_flags; /* array of per-display display buffers dirty flags */
|
||||
struct ColormanageCache *colormanage_cache; /* cache used by color management */
|
||||
|
||||
@@ -256,4 +257,12 @@ extern const char *imb_ext_image_qt[];
|
||||
extern const char *imb_ext_movie[];
|
||||
extern const char *imb_ext_audio[];
|
||||
|
||||
/* imbuf->colormanagement_flags */
|
||||
|
||||
/* special flag used for color management of compositor results,
|
||||
* which are in sRGB space and requires extra step in color conversions
|
||||
* could be replaced with something more general in the future
|
||||
*/
|
||||
#define IMB_COLORMANAGEMENT_SRGB_SOURCE (1 << 0)
|
||||
|
||||
#endif
|
||||
|
||||
@@ -625,6 +625,8 @@ typedef struct DisplayBufferThread {
|
||||
int channels;
|
||||
int dither;
|
||||
int predivide;
|
||||
|
||||
int buffer_in_srgb;
|
||||
} DisplayBufferThread;
|
||||
|
||||
static void display_buffer_apply_threaded(ImBuf *ibuf, float *buffer, unsigned char *display_buffer,
|
||||
@@ -637,8 +639,16 @@ static void display_buffer_apply_threaded(ImBuf *ibuf, float *buffer, unsigned c
|
||||
int i, tot_thread = BLI_system_thread_count();
|
||||
int start_line, tot_line;
|
||||
|
||||
if (tot_thread > 1)
|
||||
if (tot_thread > 1) {
|
||||
/* XXX: IMB_buffer_byte_from_float_tonecurve isn't thread-safe because of
|
||||
* possible non-initialized sRGB conversion stuff. Make sure it's properly
|
||||
* initialized before starting threads, but likely this stuff should be
|
||||
* initialized somewhere before to avoid possible issues in other issues.
|
||||
*/
|
||||
BLI_init_srgb_conversion();
|
||||
|
||||
BLI_init_threads(&threads, do_thread, tot_thread);
|
||||
}
|
||||
|
||||
start_line = 0;
|
||||
tot_line = ((float)(ibuf->y / tot_thread)) + 0.5f;
|
||||
@@ -664,6 +674,7 @@ static void display_buffer_apply_threaded(ImBuf *ibuf, float *buffer, unsigned c
|
||||
handles[i].channels = ibuf->channels;
|
||||
handles[i].dither = ibuf->dither;
|
||||
handles[i].predivide = predivide;
|
||||
handles[i].buffer_in_srgb = ibuf->colormanagement_flags & IMB_COLORMANAGEMENT_SRGB_SOURCE;
|
||||
|
||||
if (tot_thread > 1)
|
||||
BLI_insert_thread(&threads, &handles[i]);
|
||||
@@ -677,6 +688,30 @@ static void display_buffer_apply_threaded(ImBuf *ibuf, float *buffer, unsigned c
|
||||
do_thread(&handles[0]);
|
||||
}
|
||||
|
||||
static void *display_buffer_apply_get_linear_buffer(DisplayBufferThread *handle)
|
||||
{
|
||||
float *linear_buffer = handle->buffer;
|
||||
|
||||
if (handle->buffer_in_srgb) {
|
||||
float *buffer = handle->buffer;
|
||||
|
||||
int channels = handle->channels;
|
||||
int width = handle->width;
|
||||
int height = handle->tot_line;
|
||||
int predivide = handle->predivide;
|
||||
|
||||
int buffer_size = 4 * channels * width * height;
|
||||
|
||||
linear_buffer = MEM_callocN(buffer_size * sizeof(float), "color conversion linear buffer");
|
||||
|
||||
IMB_buffer_float_from_float(linear_buffer, buffer, channels,
|
||||
IB_PROFILE_LINEAR_RGB, IB_PROFILE_SRGB,
|
||||
predivide, width, height, width, width);
|
||||
}
|
||||
|
||||
return linear_buffer;
|
||||
}
|
||||
|
||||
static void *do_display_buffer_apply_tonemap_thread(void *handle_v)
|
||||
{
|
||||
DisplayBufferThread *handle = (DisplayBufferThread *) handle_v;
|
||||
@@ -691,24 +726,22 @@ static void *do_display_buffer_apply_tonemap_thread(void *handle_v)
|
||||
int dither = handle->dither;
|
||||
int predivide = handle->predivide;
|
||||
|
||||
IMB_buffer_byte_from_float_tonecurve(display_buffer, buffer, channels, dither,
|
||||
float *linear_buffer = display_buffer_apply_get_linear_buffer(handle);
|
||||
|
||||
IMB_buffer_byte_from_float_tonecurve(display_buffer, linear_buffer, channels, dither,
|
||||
IB_PROFILE_SRGB, IB_PROFILE_LINEAR_RGB,
|
||||
predivide, width, height, width, width,
|
||||
tonecurve_func);
|
||||
|
||||
if (linear_buffer != buffer)
|
||||
MEM_freeN(linear_buffer);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void display_buffer_apply_tonemap(ImBuf *ibuf, unsigned char *display_buffer,
|
||||
imb_tonecurveCb tonecurve_func)
|
||||
{
|
||||
/* XXX: IMB_buffer_byte_from_float_tonecurve isn't thread-safe because of
|
||||
* possible non-initialized sRGB conversion stuff. Make sure it's properly
|
||||
* initialized before starting threads, but likely this stuff should be
|
||||
* initialized somewhere before to avoid possible issues in other issues.
|
||||
*/
|
||||
BLI_init_srgb_conversion();
|
||||
|
||||
display_buffer_apply_threaded(ibuf, ibuf->rect_float, display_buffer, tonecurve_func,
|
||||
do_display_buffer_apply_tonemap_thread);
|
||||
}
|
||||
@@ -726,7 +759,9 @@ static void *do_display_buffer_apply_ocio_thread(void *handle_v)
|
||||
int dither = handle->dither;
|
||||
int predivide = handle->predivide;
|
||||
|
||||
img = OCIO_createPackedImageDesc(buffer, width, height, channels, sizeof(float),
|
||||
float *linear_buffer = display_buffer_apply_get_linear_buffer(handle);
|
||||
|
||||
img = OCIO_createPackedImageDesc(linear_buffer, width, height, channels, sizeof(float),
|
||||
channels * sizeof(float), channels * sizeof(float) * width);
|
||||
|
||||
OCIO_processorApply(processor, img);
|
||||
@@ -734,10 +769,13 @@ static void *do_display_buffer_apply_ocio_thread(void *handle_v)
|
||||
OCIO_packedImageDescRelease(img);
|
||||
|
||||
/* do conversion */
|
||||
IMB_buffer_byte_from_float(display_buffer, buffer,
|
||||
IMB_buffer_byte_from_float(display_buffer, linear_buffer,
|
||||
channels, dither, IB_PROFILE_SRGB, IB_PROFILE_SRGB,
|
||||
predivide, width, height, width, width);
|
||||
|
||||
if (linear_buffer != buffer)
|
||||
MEM_freeN(linear_buffer);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -1103,6 +1141,11 @@ void IMB_colormanagement_check_file_config(Main *bmain)
|
||||
|
||||
colormanage_check_view_settings(&sclip->view_settings, "clip editor", default_view);
|
||||
}
|
||||
else if (sl->spacetype == SPACE_SEQ) {
|
||||
SpaceSeq *sseq = (SpaceSeq *) sl;
|
||||
|
||||
colormanage_check_view_settings(&sseq->view_settings, "sequencer editor", default_view);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -473,6 +473,9 @@ typedef struct SpaceSeq {
|
||||
int pad;
|
||||
|
||||
struct bGPdata *gpd; /* grease-pencil data */
|
||||
|
||||
/* **** color management **** */
|
||||
ColorManagedViewSettings view_settings;
|
||||
} SpaceSeq;
|
||||
|
||||
|
||||
@@ -690,6 +693,7 @@ typedef struct SpaceImage {
|
||||
char dt_uvstretch;
|
||||
char around;
|
||||
|
||||
/* **** color management **** */
|
||||
ColorManagedViewSettings view_settings;
|
||||
} SpaceImage;
|
||||
|
||||
@@ -874,6 +878,7 @@ typedef struct SpaceNode {
|
||||
|
||||
struct bGPdata *gpd; /* grease-pencil data */
|
||||
|
||||
/* **** color management **** */
|
||||
ColorManagedViewSettings view_settings;
|
||||
} SpaceNode;
|
||||
|
||||
|
||||
@@ -2143,6 +2143,11 @@ static void rna_def_space_sequencer(BlenderRNA *brna)
|
||||
RNA_def_property_struct_type(prop, "GreasePencil");
|
||||
RNA_def_property_ui_text(prop, "Grease Pencil", "Grease pencil data for this space");
|
||||
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_SEQUENCER, NULL);
|
||||
|
||||
prop = RNA_def_property(srna, "view_settings", PROP_POINTER, PROP_NONE);
|
||||
RNA_def_property_pointer_sdna(prop, NULL, "view_settings");
|
||||
RNA_def_property_struct_type(prop, "ColorManagedViewSettings");
|
||||
RNA_def_property_ui_text(prop, "View Settings", "Sampled colors alongColor management settings used for displaying images on the display");
|
||||
}
|
||||
|
||||
static void rna_def_space_text(BlenderRNA *brna)
|
||||
|
||||
Reference in New Issue
Block a user