Clean-up and refactor of current OCIO integration
- Cleaned up some files -- seems there were some wrongly resolved conflicts which resulted into duplicated code in space_image.py and some build configuration files. - Store all color space related data (such as display device, view transform and so) as strings, so it could easily be ported to new OCIO configuration files and it'll be much more portable between different configurations. This required adding some look-ups to RNA associated with such settings, but it's indeed the only way to do this. If it'll be figured out such look-ups causes performance issues it's possible to optimize this further using hash. So far it's only few elements in list to be looked up. - Added support of display device transformation from OCIO configuration files. Display device is setting per-window and different windows could have different display devices, so it's possible to have one blender window opened on sRGB monitor and another one on xyz projector. Display device is ignored when using ACES ODT Tonecurve view transform due to it's not an OCIO transformation. Probably it'll be possible to get rid of this tone curve soon (if it'll be proved useless or it'll be implemented as a part of OCIO LUT). - Movie Cache now supports deleter functions for user keys, so such keys could have some allocated data which would be removed as soon as element in cache is being removed. - Movie Cache now support callbacks to check whether current cache element could be removed from a cache due to it wouldn't be accessed anymore. - Re-written cache stuff for display buffers of ImBuf. Now it's using Movie Cache which is global for all ImBufs. Probably it's not implemented in fastest way, would be investigated further and probably changed it performance wouldn't be good enough.
This commit is contained in:
@@ -107,15 +107,6 @@ class IMAGE_MT_select(Menu):
|
||||
layout.operator("uv.select_linked")
|
||||
|
||||
|
||||
class IMAGE_PT_view_transform(Panel):
|
||||
bl_label = "View Transform"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
sima = context.space_data
|
||||
|
||||
layout.prop(sima, "view_transform")
|
||||
class IMAGE_MT_image(Menu):
|
||||
bl_label = "Image"
|
||||
|
||||
@@ -436,17 +427,19 @@ class IMAGE_HT_header(Header):
|
||||
layout.prop(sima, "use_realtime_update", text="", icon_only=True, icon='LOCKED')
|
||||
|
||||
|
||||
class IMAGE_PT_view_transform(Panel):
|
||||
class IMAGE_PT_display_properties(Panel):
|
||||
bl_space_type = 'IMAGE_EDITOR'
|
||||
bl_region_type = 'UI'
|
||||
bl_label = "View Transform"
|
||||
bl_label = "Display Properties"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
sima = context.space_data
|
||||
window = context.window
|
||||
|
||||
layout.prop(sima, "view_transform", text="")
|
||||
layout.prop(window, "display_device", text="Display")
|
||||
layout.prop(sima, "view_transform", text="View")
|
||||
|
||||
|
||||
class IMAGE_PT_image_properties(Panel):
|
||||
|
||||
@@ -356,6 +356,8 @@ class INFO_MT_window(Menu):
|
||||
def draw(self, context):
|
||||
import sys
|
||||
|
||||
window = context.window
|
||||
|
||||
layout = self.layout
|
||||
|
||||
layout.operator("wm.window_duplicate")
|
||||
@@ -364,6 +366,9 @@ class INFO_MT_window(Menu):
|
||||
layout.separator()
|
||||
layout.operator("wm.console_toggle", icon='CONSOLE')
|
||||
|
||||
layout.separator()
|
||||
layout.prop_menu_enum(window, "display_device", text="Display")
|
||||
|
||||
|
||||
class INFO_MT_help(Menu):
|
||||
bl_label = "Help"
|
||||
|
||||
@@ -407,8 +407,8 @@ static void put_imbuf_cache(MovieClip *clip, MovieClipUser *user, ImBuf *ibuf, i
|
||||
if (!clip->cache) {
|
||||
clip->cache = MEM_callocN(sizeof(MovieClipCache), "movieClipCache");
|
||||
|
||||
clip->cache->moviecache = IMB_moviecache_create(sizeof(MovieClipImBufCacheKey), moviecache_hashhash,
|
||||
moviecache_hashcmp, moviecache_keydata);
|
||||
clip->cache->moviecache = IMB_moviecache_create(sizeof(MovieClipImBufCacheKey), NULL, moviecache_hashhash,
|
||||
moviecache_hashcmp, moviecache_keydata, NULL);
|
||||
}
|
||||
|
||||
key.framenr = user->framenr;
|
||||
|
||||
@@ -98,8 +98,8 @@ void seq_stripelem_cache_cleanup(void)
|
||||
{
|
||||
if (moviecache) {
|
||||
IMB_moviecache_free(moviecache);
|
||||
moviecache = IMB_moviecache_create(sizeof(SeqCacheKey), seqcache_hashhash,
|
||||
seqcache_hashcmp, NULL);
|
||||
moviecache = IMB_moviecache_create(sizeof(SeqCacheKey), NULL, seqcache_hashhash,
|
||||
seqcache_hashcmp, NULL, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -133,8 +133,8 @@ void seq_stripelem_cache_put(
|
||||
}
|
||||
|
||||
if (!moviecache) {
|
||||
moviecache = IMB_moviecache_create(sizeof(SeqCacheKey), seqcache_hashhash,
|
||||
seqcache_hashcmp, NULL);
|
||||
moviecache = IMB_moviecache_create(sizeof(SeqCacheKey), NULL, seqcache_hashhash,
|
||||
seqcache_hashcmp, NULL, NULL);
|
||||
}
|
||||
|
||||
key.seq = seq;
|
||||
|
||||
@@ -144,6 +144,7 @@
|
||||
#include "BKE_sound.h"
|
||||
|
||||
#include "IMB_imbuf.h" // for proxy / timecode versioning stuff
|
||||
#include "IMB_colormanagement.h"
|
||||
|
||||
#include "NOD_socket.h"
|
||||
|
||||
@@ -8007,7 +8008,10 @@ BlendFileData *blo_read_file_internal(FileData *fd, const char *filepath)
|
||||
fix_relpaths_library(fd->relabase, bfd->main); /* make all relative paths, relative to the open blend file */
|
||||
|
||||
link_global(fd, bfd); /* as last */
|
||||
|
||||
|
||||
/* OCIO_TODO: is there nicer place for this? */
|
||||
IMB_colormanagement_check_file_config(bfd->main);
|
||||
|
||||
return bfd;
|
||||
}
|
||||
|
||||
|
||||
@@ -35,6 +35,7 @@ extern "C" {
|
||||
#include "MEM_guardedalloc.h"
|
||||
#include "IMB_imbuf.h"
|
||||
#include "IMB_imbuf_types.h"
|
||||
#include "IMB_colormanagement.h"
|
||||
}
|
||||
|
||||
|
||||
@@ -72,7 +73,10 @@ void ViewerBaseOperation::initImage()
|
||||
anImage->ok = IMA_OK_LOADED;
|
||||
}
|
||||
|
||||
imb_freerectviewImBuf_all(ibuf);
|
||||
/* viewer might have been change size, invalidate cached
|
||||
* display buffers so they'll be used with a proper size
|
||||
*/
|
||||
IMB_display_buffer_invalidate(ibuf);
|
||||
|
||||
/* now we combine the input with ibuf */
|
||||
this->m_outputBuffer = ibuf->rect_float;
|
||||
@@ -88,7 +92,7 @@ void ViewerBaseOperation:: updateImage(rcti *rect)
|
||||
void ViewerBaseOperation::deinitExecution()
|
||||
{
|
||||
ImBuf *ibuf = BKE_image_acquire_ibuf(this->m_image, this->m_imageUser, &this->m_lock);
|
||||
imb_freerectviewImBuf_all(ibuf);
|
||||
IMB_display_buffer_invalidate(ibuf);
|
||||
BKE_image_release_ibuf(this->m_image, this->m_lock);
|
||||
|
||||
this->m_outputBuffer = NULL;
|
||||
|
||||
@@ -50,6 +50,7 @@
|
||||
|
||||
#include "IMB_imbuf.h"
|
||||
#include "IMB_imbuf_types.h"
|
||||
#include "IMB_colormanagement.h"
|
||||
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_global.h"
|
||||
@@ -69,6 +70,8 @@
|
||||
#include "UI_resources.h"
|
||||
#include "UI_view2d.h"
|
||||
|
||||
#include "WM_api.h"
|
||||
#include "WM_types.h"
|
||||
|
||||
#include "RE_pipeline.h"
|
||||
|
||||
@@ -76,7 +79,7 @@
|
||||
|
||||
#define HEADER_HEIGHT 18
|
||||
|
||||
static void image_verify_buffer_float(Image *ima, ImBuf *ibuf, int color_manage, int view_transform)
|
||||
static void image_verify_buffer_float(Image *ima, ImBuf *ibuf, int color_manage)
|
||||
{
|
||||
/* detect if we need to redo the curve map.
|
||||
* ibuf->rect is zero for compositor and render results after change
|
||||
@@ -85,9 +88,7 @@ static void image_verify_buffer_float(Image *ima, ImBuf *ibuf, int color_manage,
|
||||
* NOTE: if float buffer changes, we have to manually remove the rect
|
||||
*/
|
||||
|
||||
unsigned int *rect = imb_getrectviewImBuf(ibuf, view_transform);
|
||||
|
||||
if (ibuf->rect_float && (rect == NULL || (ibuf->userflags & IB_RECT_INVALID)) ) {
|
||||
if (ibuf->rect_float && (ibuf->rect == NULL || (ibuf->userflags & IB_RECT_INVALID)) ) {
|
||||
if (color_manage) {
|
||||
if (ima && ima->source == IMA_SRC_VIEWER)
|
||||
ibuf->profile = IB_PROFILE_LINEAR_RGB;
|
||||
@@ -95,7 +96,7 @@ static void image_verify_buffer_float(Image *ima, ImBuf *ibuf, int color_manage,
|
||||
else
|
||||
ibuf->profile = IB_PROFILE_NONE;
|
||||
|
||||
IMB_rect_from_float_with_view_transform(ibuf, view_transform);
|
||||
IMB_rect_from_float(ibuf);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -419,7 +420,7 @@ static void sima_draw_zbuffloat_pixels(Scene *scene, float x1, float y1, int rec
|
||||
MEM_freeN(rectf);
|
||||
}
|
||||
|
||||
static void draw_image_buffer(SpaceImage *sima, ARegion *ar, Scene *scene, Image *ima, ImBuf *ibuf, float fx, float fy, float zoomx, float zoomy)
|
||||
static void draw_image_buffer(wmWindow *win, SpaceImage *sima, ARegion *ar, Scene *scene, Image *ima, ImBuf *ibuf, float fx, float fy, float zoomx, float zoomy)
|
||||
{
|
||||
int x, y;
|
||||
int color_manage = scene->r.color_mgt_flag & R_COLOR_MANAGEMENT;
|
||||
@@ -432,10 +433,8 @@ static void draw_image_buffer(SpaceImage *sima, ARegion *ar, Scene *scene, Image
|
||||
|
||||
/* this part is generic image display */
|
||||
if (sima->flag & SI_SHOW_ALPHA) {
|
||||
unsigned int *rect = imb_getrectviewImBuf(ibuf, sima->view_transform);
|
||||
|
||||
if (rect)
|
||||
sima_draw_alpha_pixels(x, y, ibuf->x, ibuf->y, rect);
|
||||
if (ibuf->rect)
|
||||
sima_draw_alpha_pixels(x, y, ibuf->x, ibuf->y, ibuf->rect);
|
||||
else if (ibuf->rect_float && ibuf->channels == 4)
|
||||
sima_draw_alpha_pixelsf(x, y, ibuf->x, ibuf->y, ibuf->rect_float);
|
||||
}
|
||||
@@ -448,7 +447,8 @@ static void draw_image_buffer(SpaceImage *sima, ARegion *ar, Scene *scene, Image
|
||||
sima_draw_zbuffloat_pixels(scene, x, y, ibuf->x, ibuf->y, ibuf->rect_float);
|
||||
}
|
||||
else {
|
||||
unsigned int *rect;
|
||||
unsigned char *display_buffer;
|
||||
void *cache_handle;
|
||||
|
||||
if (sima->flag & SI_USE_ALPHA) {
|
||||
fdrawcheckerboard(x, y, x + ibuf->x * zoomx, y + ibuf->y * zoomy);
|
||||
@@ -459,17 +459,19 @@ static void draw_image_buffer(SpaceImage *sima, ARegion *ar, Scene *scene, Image
|
||||
|
||||
/* we don't draw floats buffers directly but
|
||||
* convert them, and optionally apply curves */
|
||||
image_verify_buffer_float(ima, ibuf, color_manage, sima->view_transform);
|
||||
image_verify_buffer_float(ima, ibuf, color_manage);
|
||||
|
||||
rect = imb_getrectviewImBuf(ibuf, sima->view_transform);
|
||||
display_buffer = IMB_display_buffer_acquire(ibuf, sima->view_transform, win->display_device, &cache_handle);
|
||||
|
||||
if (rect)
|
||||
glaDrawPixelsSafe(x, y, ibuf->x, ibuf->y, ibuf->x, GL_RGBA, GL_UNSIGNED_BYTE, rect);
|
||||
if (display_buffer)
|
||||
glaDrawPixelsSafe(x, y, ibuf->x, ibuf->y, ibuf->x, GL_RGBA, GL_UNSIGNED_BYTE, display_buffer);
|
||||
#if 0
|
||||
else
|
||||
glaDrawPixelsSafe(x, y, ibuf->x, ibuf->y, ibuf->x, GL_RGBA, GL_FLOAT, ibuf->rect_float);
|
||||
#endif
|
||||
|
||||
|
||||
IMB_display_buffer_release(cache_handle);
|
||||
|
||||
if (sima->flag & SI_USE_ALPHA)
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
@@ -478,15 +480,14 @@ static void draw_image_buffer(SpaceImage *sima, ARegion *ar, Scene *scene, Image
|
||||
glPixelZoom(1.0f, 1.0f);
|
||||
}
|
||||
|
||||
static unsigned int *get_part_from_ibuf(ImBuf *ibuf, short startx, short starty, short endx, short endy, int view_transform)
|
||||
static unsigned int *get_part_from_ibuf(ImBuf *ibuf, short startx, short starty, short endx, short endy)
|
||||
{
|
||||
unsigned int *rt, *rp, *rectmain;
|
||||
short y, heigth, len;
|
||||
unsigned int *rect = imb_getrectviewImBuf(ibuf, view_transform);
|
||||
|
||||
/* the right offset in rectot */
|
||||
|
||||
rt = rect + (starty * ibuf->x + startx);
|
||||
rt = ibuf->rect + (starty * ibuf->x + startx);
|
||||
|
||||
len = (endx - startx);
|
||||
heigth = (endy - starty);
|
||||
@@ -517,14 +518,14 @@ static void draw_image_buffer_tiled(SpaceImage *sima, ARegion *ar, Scene *scene,
|
||||
sima->curtile = ima->xrep * ima->yrep - 1;
|
||||
|
||||
/* create char buffer from float if needed */
|
||||
image_verify_buffer_float(ima, ibuf, color_manage, sima->view_transform);
|
||||
image_verify_buffer_float(ima, ibuf, color_manage);
|
||||
|
||||
/* retrieve part of image buffer */
|
||||
dx = ibuf->x / ima->xrep;
|
||||
dy = ibuf->y / ima->yrep;
|
||||
sx = (sima->curtile % ima->xrep) * dx;
|
||||
sy = (sima->curtile / ima->xrep) * dy;
|
||||
rect = get_part_from_ibuf(ibuf, sx, sy, sx + dx, sy + dy, sima->view_transform);
|
||||
rect = get_part_from_ibuf(ibuf, sx, sy, sx + dx, sy + dy);
|
||||
|
||||
/* draw repeated */
|
||||
for (sy = 0; sy + dy <= ibuf->y; sy += dy) {
|
||||
@@ -540,7 +541,7 @@ static void draw_image_buffer_tiled(SpaceImage *sima, ARegion *ar, Scene *scene,
|
||||
MEM_freeN(rect);
|
||||
}
|
||||
|
||||
static void draw_image_buffer_repeated(SpaceImage *sima, ARegion *ar, Scene *scene, Image *ima, ImBuf *ibuf, float zoomx, float zoomy)
|
||||
static void draw_image_buffer_repeated(wmWindow *win, SpaceImage *sima, ARegion *ar, Scene *scene, Image *ima, ImBuf *ibuf, float zoomx, float zoomy)
|
||||
{
|
||||
const double time_current = PIL_check_seconds_timer();
|
||||
|
||||
@@ -557,7 +558,7 @@ static void draw_image_buffer_repeated(SpaceImage *sima, ARegion *ar, Scene *sce
|
||||
if (ima && (ima->tpageflag & IMA_TILES))
|
||||
draw_image_buffer_tiled(sima, ar, scene, ima, ibuf, x, y, zoomx, zoomy);
|
||||
else
|
||||
draw_image_buffer(sima, ar, scene, ima, ibuf, x, y, zoomx, zoomy);
|
||||
draw_image_buffer(win, sima, ar, scene, ima, ibuf, x, y, zoomx, zoomy);
|
||||
|
||||
/* only draw until running out of time */
|
||||
if ((PIL_check_seconds_timer() - time_current) > 0.25)
|
||||
@@ -646,19 +647,16 @@ static unsigned char *get_alpha_clone_image(Scene *scene, int *width, int *heigh
|
||||
ImBuf *ibuf;
|
||||
unsigned int size, alpha;
|
||||
unsigned char *rect, *cp;
|
||||
unsigned int *rect_view;
|
||||
|
||||
if (!brush || !brush->clone.image)
|
||||
return NULL;
|
||||
|
||||
ibuf = BKE_image_get_ibuf(brush->clone.image, NULL);
|
||||
/* XXX: which transform to use here? */
|
||||
rect_view = imb_getrectviewImBuf(ibuf, IMB_VIEW_TRANSFORM_NONE);
|
||||
|
||||
if (!ibuf || !rect_view)
|
||||
if (!ibuf || !ibuf->rect)
|
||||
return NULL;
|
||||
|
||||
rect = MEM_dupallocN(rect_view);
|
||||
rect = MEM_dupallocN(ibuf->rect);
|
||||
if (!rect)
|
||||
return NULL;
|
||||
|
||||
@@ -709,8 +707,11 @@ static void draw_image_paint_helpers(ARegion *ar, Scene *scene, float zoomx, flo
|
||||
|
||||
/* draw main image area */
|
||||
|
||||
void draw_image_main(SpaceImage *sima, ARegion *ar, Scene *scene)
|
||||
void draw_image_main(const bContext *C, ARegion *ar)
|
||||
{
|
||||
SpaceImage *sima = CTX_wm_space_image(C);
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
wmWindow *win = CTX_wm_window(C);
|
||||
Image *ima;
|
||||
ImBuf *ibuf;
|
||||
float zoomx, zoomy;
|
||||
@@ -749,11 +750,11 @@ void draw_image_main(SpaceImage *sima, ARegion *ar, Scene *scene)
|
||||
if (ibuf == NULL)
|
||||
ED_region_grid_draw(ar, zoomx, zoomy);
|
||||
else if (sima->flag & SI_DRAW_TILE)
|
||||
draw_image_buffer_repeated(sima, ar, scene, ima, ibuf, zoomx, zoomy);
|
||||
draw_image_buffer_repeated(win, sima, ar, scene, ima, ibuf, zoomx, zoomy);
|
||||
else if (ima && (ima->tpageflag & IMA_TILES))
|
||||
draw_image_buffer_tiled(sima, ar, scene, ima, ibuf, 0.0f, 0.0, zoomx, zoomy);
|
||||
else
|
||||
draw_image_buffer(sima, ar, scene, ima, ibuf, 0.0f, 0.0f, zoomx, zoomy);
|
||||
draw_image_buffer(win, sima, ar, scene, ima, ibuf, 0.0f, 0.0f, zoomx, zoomy);
|
||||
|
||||
/* paint helpers */
|
||||
if (sima->flag & SI_DRAWTOOL)
|
||||
|
||||
@@ -52,7 +52,7 @@ struct ARegion *image_has_scope_region(struct ScrArea *sa);
|
||||
extern const char *image_context_dir[]; /* doc access */
|
||||
|
||||
/* image_draw.c */
|
||||
void draw_image_main(struct SpaceImage *sima, struct ARegion *ar, struct Scene *scene);
|
||||
void draw_image_main(const struct bContext *C, struct ARegion *ar);
|
||||
void draw_image_grease_pencil(struct bContext *C, short onlyv2d);
|
||||
void draw_image_sample_line(struct SpaceImage *sima);
|
||||
|
||||
|
||||
@@ -387,6 +387,12 @@ static SpaceLink *image_new(const bContext *UNUSED(C))
|
||||
simage->zoom = 1;
|
||||
simage->lock = 1;
|
||||
|
||||
/* OCIO_TODO: use default view transform here when OCIO is completely integrated
|
||||
* and proper versioning stuff is added.
|
||||
* for now use NONE to be compatible with all current files
|
||||
*/
|
||||
BLI_strncpy(simage->view_transform, "NONE", sizeof(simage->view_transform));
|
||||
|
||||
simage->iuser.ok = 1;
|
||||
simage->iuser.fie_ima = 2;
|
||||
simage->iuser.frames = 100;
|
||||
@@ -449,6 +455,7 @@ static void image_init(struct wmWindowManager *UNUSED(wm), ScrArea *sa)
|
||||
|
||||
static SpaceLink *image_duplicate(SpaceLink *sl)
|
||||
{
|
||||
SpaceImage *simage = (SpaceImage *) sl;
|
||||
SpaceImage *simagen = MEM_dupallocN(sl);
|
||||
|
||||
/* clear or remove stuff from old */
|
||||
@@ -457,6 +464,8 @@ static SpaceLink *image_duplicate(SpaceLink *sl)
|
||||
|
||||
scopes_new(&simagen->scopes);
|
||||
|
||||
BLI_strncpy(simagen->view_transform, simage->view_transform, sizeof(simage->view_transform));
|
||||
|
||||
return (SpaceLink *)simagen;
|
||||
}
|
||||
|
||||
@@ -817,7 +826,7 @@ static void image_main_area_draw(const bContext *C, ARegion *ar)
|
||||
image_main_area_set_view2d(sima, ar);
|
||||
|
||||
/* we draw image in pixelspace */
|
||||
draw_image_main(sima, ar, scene);
|
||||
draw_image_main(C, ar);
|
||||
|
||||
/* and uvs in 0.0-1.0 space */
|
||||
UI_view2d_view_ortho(v2d);
|
||||
|
||||
@@ -30,6 +30,7 @@ set(INC
|
||||
../blenlib
|
||||
../blenloader
|
||||
../makesdna
|
||||
../makesrna
|
||||
../../../intern/guardedalloc
|
||||
../../../intern/memutil
|
||||
)
|
||||
@@ -45,6 +46,7 @@ set(SRC
|
||||
intern/anim_movie.c
|
||||
intern/bmp.c
|
||||
intern/cache.c
|
||||
intern/colormanagement.c
|
||||
intern/divers.c
|
||||
intern/filetype.c
|
||||
intern/filter.c
|
||||
@@ -67,6 +69,7 @@ set(SRC
|
||||
intern/util.c
|
||||
intern/writeimage.c
|
||||
|
||||
IMB_colormanagement.h
|
||||
IMB_imbuf.h
|
||||
IMB_imbuf_types.h
|
||||
IMB_moviecache.h
|
||||
@@ -182,17 +185,6 @@ endif()
|
||||
|
||||
if(WITH_OPENCOLORIO)
|
||||
list(APPEND SRC
|
||||
intern/colormanagement.c
|
||||
)
|
||||
list(APPEND INC
|
||||
../../../intern/opencolorio
|
||||
)
|
||||
add_definitions(-DWITH_OCIO)
|
||||
endif()
|
||||
|
||||
if(WITH_OPENCOLORIO)
|
||||
list(APPEND SRC
|
||||
intern/colormanagement.c
|
||||
)
|
||||
list(APPEND INC
|
||||
../../../intern/opencolorio
|
||||
|
||||
@@ -33,7 +33,35 @@
|
||||
|
||||
#define BCM_CONFIG_FILE "config.ocio"
|
||||
|
||||
struct EnumPropertyItem;
|
||||
struct ImBuf;
|
||||
struct Main;
|
||||
|
||||
/* ** Initialization / De-initialization ** */
|
||||
|
||||
void IMB_colormanagement_init(void);
|
||||
void IMB_colormanagement_exit(void);
|
||||
|
||||
/* ** Public display buffers interfaces ** */
|
||||
|
||||
unsigned char *IMB_display_buffer_acquire(struct ImBuf *ibuf, const char *view_transform, const char *display,
|
||||
void **cache_handle);
|
||||
void IMB_display_buffer_release(void *cache_handle);
|
||||
|
||||
void IMB_display_buffer_invalidate(struct ImBuf *ibuf);
|
||||
|
||||
void IMB_colormanagement_check_file_config(struct Main *bmain);
|
||||
|
||||
/* ** Display funcrions ** */
|
||||
int IMB_colormanagement_display_get_named_index(const char *name);
|
||||
const char *IMB_colormanagement_display_get_indexed_name(int index);
|
||||
|
||||
/* ** View funcrions ** */
|
||||
int IMB_colormanagement_view_get_named_index(const char *name);
|
||||
const char *IMB_colormanagement_view_get_indexed_name(int index);
|
||||
|
||||
/* ** RNA helper functions ** */
|
||||
void IMB_colormanagement_display_items_add(struct EnumPropertyItem **items, int *totitem);
|
||||
void IMB_colormanagement_view_items_add(struct EnumPropertyItem **items, int *totitem, const char *display_name);
|
||||
|
||||
#endif // IMB_COLORMANAGEMENT_H
|
||||
|
||||
@@ -364,18 +364,8 @@ int imb_get_anim_type(const char *name);
|
||||
void IMB_de_interlace(struct ImBuf *ibuf);
|
||||
void IMB_interlace(struct ImBuf *ibuf);
|
||||
|
||||
/* currently should match eSpaceImage_ViewTransform */
|
||||
typedef enum IMB_ViewTransform {
|
||||
IMB_VIEW_TRANSFORM_NONE = 0,
|
||||
IMB_VIEW_TRANSFORM_ACES_ODT_TONECURVE = 1,
|
||||
IMB_VIEW_TRANSFORM_OCIO_RAW = 2,
|
||||
IMB_VIEW_TRANSFORM_OCIO_RRT = 3,
|
||||
IMB_VIEW_TRANSFORM_OCIO_LOG = 4,
|
||||
} IMB_ViewTransform;
|
||||
|
||||
/* create char buffer, color corrected if necessary, for ImBufs that lack one */
|
||||
void IMB_rect_from_float(struct ImBuf *ibuf);
|
||||
void IMB_rect_from_float_with_view_transform(struct ImBuf *ibuf, int view_transform);
|
||||
/* Create char buffer for part of the image, color corrected if necessary,
|
||||
* Changed part will be stored in buffer. This is expected to be used for texture painting updates */
|
||||
void IMB_partial_rect_from_float(struct ImBuf *ibuf, float *buffer, int x, int y, int w, int h);
|
||||
@@ -402,6 +392,15 @@ void IMB_buffer_byte_from_byte(unsigned char *rect_to, const unsigned char *rect
|
||||
int width, int height, int stride_to, int stride_from);
|
||||
void IMB_buffer_float_clamp(float *buf, int width, int height);
|
||||
|
||||
/* converting pixel buffers using tobecurve */
|
||||
|
||||
typedef void (*imb_tonecurveCb) (float rgbOut[3], const float rgbIn[3]);
|
||||
|
||||
void IMB_buffer_byte_from_float_tonecurve(unsigned char *rect_to, const float *rect_from,
|
||||
int channels_from, float dither, int profile_to, int profile_from, int predivide,
|
||||
int width, int height, int stride_to, int stride_from,
|
||||
imb_tonecurveCb tonecurve_func);
|
||||
|
||||
/**
|
||||
* Change the ordering of the color bytes pointed to by rect from
|
||||
* rgba to abgr. size * 4 color bytes are reordered.
|
||||
@@ -508,10 +507,4 @@ void imb_freemipmapImBuf(struct ImBuf *ibuf);
|
||||
short imb_addtilesImBuf(struct ImBuf *ibuf);
|
||||
void imb_freetilesImBuf(struct ImBuf *ibuf);
|
||||
|
||||
short imb_addrectviewImBuf(struct ImBuf *ibuf, int view_transform);
|
||||
void imb_freerectviewImBuf(struct ImBuf *ibuf, int view_transform);
|
||||
void imb_freerectviewImBuf_all(struct ImBuf *ibuf);
|
||||
|
||||
unsigned int *imb_getrectviewImBuf(struct ImBuf *ibuf, int view_transform);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -76,8 +76,6 @@ typedef struct ImBuf {
|
||||
|
||||
/* pixels */
|
||||
unsigned int *rect; /* pixel values stored here */
|
||||
unsigned int *rect_view[5]; /* cached view rects which were converted from float buffer */
|
||||
/* using different view transforms */
|
||||
float *rect_float; /* floating point Rect equivalent
|
||||
* Linear RGB color space - may need gamma correction to
|
||||
* sRGB when generating 8bit representations */
|
||||
@@ -121,6 +119,12 @@ typedef struct ImBuf {
|
||||
unsigned char *encodedbuffer; /* Compressed image only used with png currently */
|
||||
unsigned int encodedsize; /* Size of data written to encodedbuffer */
|
||||
unsigned int encodedbuffersize; /* Size of encodedbuffer */
|
||||
|
||||
/* color management */
|
||||
int colormanage_refcounter;
|
||||
unsigned int colormanage_flags;
|
||||
unsigned int display_buffer_flags[16]; /* array of per-display display buffers dirty flags */
|
||||
/* currently supports 16 display spaces and 32 view-transform */
|
||||
} ImBuf;
|
||||
|
||||
/* Moved from BKE_bmfont_types.h because it is a userflag bit mask. */
|
||||
@@ -222,4 +226,7 @@ extern const char *imb_ext_image_qt[];
|
||||
extern const char *imb_ext_movie[];
|
||||
extern const char *imb_ext_audio[];
|
||||
|
||||
/* colormanage flags */
|
||||
#define IMB_COLORMANAGED (1 << 0)
|
||||
|
||||
#endif
|
||||
|
||||
@@ -43,11 +43,16 @@ struct ImBuf;
|
||||
struct MovieCache;
|
||||
|
||||
typedef void (*MovieCacheGetKeyDataFP) (void *userkey, int *framenr, int *proxy, int *render_flags);
|
||||
typedef void (*MoviKeyDeleterFP) (void *userkey);
|
||||
typedef int (*MovieCacheCheckKeyUnusedFP) (void *userkey);
|
||||
|
||||
void IMB_moviecache_init(void);
|
||||
void IMB_moviecache_destruct(void);
|
||||
|
||||
struct MovieCache *IMB_moviecache_create(int keysize, GHashHashFP hashfp, GHashCmpFP cmpfp, MovieCacheGetKeyDataFP getdatafp);
|
||||
struct MovieCache *IMB_moviecache_create(int keysize, MoviKeyDeleterFP keydeleterfp,
|
||||
GHashHashFP hashfp, GHashCmpFP cmpfp,
|
||||
MovieCacheGetKeyDataFP getdatafp,
|
||||
MovieCacheCheckKeyUnusedFP checkkeyunusedfp);
|
||||
void IMB_moviecache_put(struct MovieCache *cache, void *userkey, struct ImBuf *ibuf);
|
||||
struct ImBuf* IMB_moviecache_get(struct MovieCache *cache, void *userkey);
|
||||
void IMB_moviecache_free(struct MovieCache *cache);
|
||||
|
||||
@@ -4,7 +4,7 @@ Import ('env')
|
||||
|
||||
sources = env.Glob('intern/*.c')
|
||||
|
||||
incs = '. ../makesdna #/intern/guardedalloc #/intern/memutil ../blenlib'
|
||||
incs = '. ../makesdna ../makesrna #/intern/guardedalloc #/intern/memutil ../blenlib'
|
||||
incs += ' ../avi ../blenkernel ../blenloader'
|
||||
incs += ' #/intern/ffmpeg'
|
||||
|
||||
@@ -61,7 +61,5 @@ if env['WITH_BF_QUICKTIME']:
|
||||
if env['WITH_BF_OCIO']:
|
||||
defs.append('WITH_OCIO')
|
||||
incs += ' #intern/opencolorio'
|
||||
else:
|
||||
sources.remove(os.path.join('intern', 'colormanagement.c'))
|
||||
|
||||
env.BlenderLib ( libname = 'bf_imbuf', sources = sources, includes = Split(incs), defines = defs, libtype=['core','player'], priority = [185,115] )
|
||||
|
||||
67
source/blender/imbuf/intern/IMB_colormanagement_intern.h
Normal file
67
source/blender/imbuf/intern/IMB_colormanagement_intern.h
Normal file
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2012 by Blender Foundation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): Xavier Thomas,
|
||||
* Lukas Toenne,
|
||||
* Sergey Sharybin
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef IMB_COLORMANAGEMENT_INTERN_H
|
||||
#define IMB_COLORMANAGEMENT_INTERN_H
|
||||
|
||||
#include "DNA_listBase.h"
|
||||
|
||||
#define BCM_CONFIG_FILE "config.ocio"
|
||||
|
||||
typedef struct ColorSpace {
|
||||
struct ColorSpace *next, *prev;
|
||||
int index;
|
||||
char name[64];
|
||||
} ColorSpace;
|
||||
|
||||
typedef struct ColorManagedDisplay {
|
||||
struct ColorManagedDisplay *next, *prev;
|
||||
int index;
|
||||
char name[64];
|
||||
ListBase views;
|
||||
} ColorManagedDisplay;
|
||||
|
||||
typedef struct ColorManagedView {
|
||||
struct ColorManagedView *next, *prev;
|
||||
int index;
|
||||
char name[64];
|
||||
} ColorManagedView;
|
||||
|
||||
struct ColorManagedDisplay *colormanage_display_get_default(void);
|
||||
struct ColorManagedDisplay *colormanage_display_add(const char *name);
|
||||
struct ColorManagedDisplay *colormanage_display_get_named(const char *name);
|
||||
struct ColorManagedDisplay *colormanage_display_get_indexed(int index);
|
||||
|
||||
struct ColorManagedView *colormanage_view_get_default(const ColorManagedDisplay *display);
|
||||
struct ColorManagedView *colormanage_view_add(const char *name);
|
||||
struct ColorManagedView *colormanage_view_get_indexed(int index);
|
||||
struct ColorManagedView *colormanage_view_get_named(const char *name);
|
||||
|
||||
#endif // IMB_COLORMANAGEMENT_INTERN_H
|
||||
@@ -44,8 +44,7 @@ void IMB_premultiply_rect_float(float *rect_float, char planes, int w, int h);
|
||||
void imb_onehalf_no_alloc(struct ImBuf *ibuf2, struct ImBuf *ibuf1);
|
||||
|
||||
/* tonecurves corrections */
|
||||
void IMB_ratio_preserving_odt_tonecurve_v3(const float rgbIn[3], float rgbOut[3]);
|
||||
void IMB_ratio_preserving_odt_tonecurve_v4(const float rgbIn[4], float rgbOut[4]);
|
||||
void IMB_ratio_preserving_odt_tonecurve(float rgbOut[3], const float rgbIn[3]);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
#include "IMB_allocimbuf.h"
|
||||
#include "IMB_filetype.h"
|
||||
#include "IMB_metadata.h"
|
||||
#include "IMB_colormanagement.h"
|
||||
|
||||
#include "imbuf.h"
|
||||
|
||||
@@ -156,7 +157,6 @@ void IMB_freeImBuf(ImBuf *ibuf)
|
||||
}
|
||||
else {
|
||||
imb_freerectImBuf(ibuf);
|
||||
imb_freerectviewImBuf_all(ibuf);
|
||||
imb_freerectfloatImBuf(ibuf);
|
||||
imb_freetilesImBuf(ibuf);
|
||||
IMB_freezbufImBuf(ibuf);
|
||||
@@ -440,10 +440,11 @@ ImBuf *IMB_dupImBuf(ImBuf *ibuf1)
|
||||
// for now don't duplicate metadata
|
||||
tbuf.metadata = NULL;
|
||||
|
||||
memset(tbuf.rect_view, 0, sizeof(tbuf.rect_view));
|
||||
|
||||
*ibuf2 = tbuf;
|
||||
|
||||
|
||||
IMB_display_buffer_invalidate(ibuf2);
|
||||
ibuf2->colormanage_flags &= ~ IMB_COLORMANAGED;
|
||||
|
||||
return(ibuf2);
|
||||
}
|
||||
|
||||
@@ -474,63 +475,3 @@ static MEM_CacheLimiterC **get_imbuf_cache_limiter(void)
|
||||
return &c;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* question; why also add zbuf? */
|
||||
short imb_addrectviewImBuf(ImBuf *ibuf, int view_transform)
|
||||
{
|
||||
int size;
|
||||
|
||||
if (view_transform == IMB_VIEW_TRANSFORM_NONE)
|
||||
return imb_addrectImBuf(ibuf);
|
||||
|
||||
if (ibuf == NULL) return FALSE;
|
||||
|
||||
/* don't call imb_freerectImBuf, it frees mipmaps, this call is used only too give float buffers display */
|
||||
if (ibuf->rect_view[view_transform])
|
||||
MEM_freeN(ibuf->rect_view[view_transform]);
|
||||
ibuf->rect_view[view_transform] = NULL;
|
||||
|
||||
size = ibuf->x * ibuf->y;
|
||||
size = size * sizeof(unsigned int);
|
||||
|
||||
if ((ibuf->rect_view[view_transform] = MEM_mapallocN(size, "imb_addrectImBuf"))) {
|
||||
if (ibuf->planes > 32) return (addzbufImBuf(ibuf));
|
||||
else return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* any free rect frees mipmaps to be sure, creation is in render on first request */
|
||||
void imb_freerectviewImBuf(ImBuf *ibuf, int view_transform)
|
||||
{
|
||||
if (view_transform == IMB_VIEW_TRANSFORM_NONE) {
|
||||
imb_freerectImBuf(ibuf);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (ibuf == NULL) return;
|
||||
|
||||
if (ibuf->rect_view[view_transform])
|
||||
MEM_freeN(ibuf->rect_view[view_transform]);
|
||||
|
||||
ibuf->rect_view[view_transform] = NULL;
|
||||
}
|
||||
|
||||
void imb_freerectviewImBuf_all(ImBuf *ibuf)
|
||||
{
|
||||
imb_freerectviewImBuf(ibuf, IMB_VIEW_TRANSFORM_ACES_ODT_TONECURVE);
|
||||
imb_freerectviewImBuf(ibuf, IMB_VIEW_TRANSFORM_OCIO_RAW);
|
||||
imb_freerectviewImBuf(ibuf, IMB_VIEW_TRANSFORM_OCIO_RRT);
|
||||
imb_freerectviewImBuf(ibuf, IMB_VIEW_TRANSFORM_OCIO_LOG);
|
||||
}
|
||||
|
||||
unsigned int *imb_getrectviewImBuf(ImBuf *ibuf, int view_transform)
|
||||
{
|
||||
if (view_transform == IMB_VIEW_TRANSFORM_NONE) {
|
||||
return ibuf->rect;
|
||||
}
|
||||
|
||||
return ibuf->rect_view[view_transform];
|
||||
}
|
||||
|
||||
@@ -29,30 +29,340 @@
|
||||
*/
|
||||
|
||||
#include "IMB_colormanagement.h"
|
||||
#include "IMB_colormanagement_intern.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "DNA_windowmanager_types.h"
|
||||
#include "DNA_space_types.h"
|
||||
#include "DNA_screen_types.h"
|
||||
|
||||
#include "IMB_filter.h"
|
||||
#include "IMB_imbuf.h"
|
||||
#include "IMB_imbuf_types.h"
|
||||
#include "IMB_moviecache.h"
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "BLI_blenlib.h"
|
||||
#include "BLI_path_util.h"
|
||||
#include "BLI_string.h"
|
||||
|
||||
#include "BKE_utildefines.h"
|
||||
#include "BKE_main.h"
|
||||
|
||||
#include <ocio_capi.h>
|
||||
#include "RNA_define.h"
|
||||
|
||||
static void colormgmt_load_config(ConstConfigRcPtr* config)
|
||||
#ifdef WITH_OCIO
|
||||
# include <ocio_capi.h>
|
||||
#endif
|
||||
|
||||
/*********************** Global declarations *************************/
|
||||
|
||||
/* ** list of all supported color spaces, displays and views */
|
||||
#ifdef WITH_OCIO
|
||||
static ListBase global_colorspaces = {NULL};
|
||||
#endif
|
||||
|
||||
static ListBase global_displays = {NULL};
|
||||
static ListBase global_views = {NULL};
|
||||
|
||||
/*********************** Color managed cache *************************/
|
||||
|
||||
/* Currently it's original ImBuf pointer is used to distinguish which
|
||||
* datablock, frame number, possible postprocessing display buffer was
|
||||
* created for.
|
||||
*
|
||||
* This makes it's possible to easy define key for color managed cache
|
||||
* which would work for Images, Movie Clips, Sequencer Strips and so.
|
||||
*
|
||||
* This also allows to easily control memory usage -- all color managed
|
||||
* buffers are concentrated in single cache and it's really easy to
|
||||
* control maximal memory usage for all color management related stuff
|
||||
* (currently supports only maximal memory usage, but it could be
|
||||
* improved further to support removing buffers when they are not needed
|
||||
* anymore but memory usage didn't exceed it's limit).
|
||||
*
|
||||
* This ImBuf is being referenced by cache key, so it could accessed
|
||||
* anytime on runtime while cache element is valid. This is needed to
|
||||
* support removing display buffers from cache when ImBuf they were
|
||||
* created for is being freed.
|
||||
*
|
||||
* Technically it works in the following way:
|
||||
* - ImBuf is being referenced first time when display buffer is
|
||||
* creating for it and being put into the cache
|
||||
* - On any further display buffer created for this ImBuf user
|
||||
* reference counter is not being incremented
|
||||
* - There's count of color management users in ImBuf which is
|
||||
* being incremented every time display buffer is creating for
|
||||
* giver ImBuf.
|
||||
* - Hence, we always know how many display buffers is created
|
||||
* for the ImBuf and if there's any display buffers created
|
||||
* this ImBuf would be referenced by color management stuff and
|
||||
* actual data for it wouldn't be freed even when this ImBuf is
|
||||
* being freed by user, who created it.
|
||||
* - When all external users finished working with this ImBuf it's
|
||||
* reference counter would be 0.
|
||||
* - On every new display buffer adding to the cache review of
|
||||
* the cache happens and all cached display buffers who's ImBuf's
|
||||
* user counter is zero are being removed from the cache.
|
||||
* - On every display buffer removed from the cache ImBuf's color
|
||||
* management user counter is being decremented. As soon as it's
|
||||
* becoming zero, original ImBuf is being freed completely.
|
||||
*/
|
||||
|
||||
typedef struct ColormanageCacheKey {
|
||||
ImBuf *ibuf; /* image buffer for which display buffer was created */
|
||||
int view_transform; /* view transformation used for display buffer */
|
||||
int display; /* display device name */
|
||||
} ColormanageCacheKey;
|
||||
|
||||
static struct MovieCache *colormanage_cache = NULL;
|
||||
|
||||
static unsigned int colormanage_hashhash(const void *key_v)
|
||||
{
|
||||
OCIO_setCurrentConfig(config);
|
||||
ColormanageCacheKey *key = (ColormanageCacheKey *)key_v;
|
||||
|
||||
unsigned int rval = *(unsigned int *) key->ibuf;
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
void colormgmt_free_config(void)
|
||||
static int colormanage_hashcmp(const void *av, const void *bv)
|
||||
{
|
||||
const ColormanageCacheKey *a = (ColormanageCacheKey *) av;
|
||||
const ColormanageCacheKey *b = (ColormanageCacheKey *) bv;
|
||||
|
||||
if (a->ibuf < b->ibuf)
|
||||
return -1;
|
||||
else if (a->ibuf > b->ibuf)
|
||||
return 1;
|
||||
|
||||
if (a->view_transform < b->view_transform)
|
||||
return -1;
|
||||
else if (a->view_transform > b->view_transform)
|
||||
return 1;
|
||||
|
||||
if (a->display < b->display)
|
||||
return -1;
|
||||
else if (a->display > b->display)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int colormanage_checkkeyunused(void *key_v)
|
||||
{
|
||||
ColormanageCacheKey *key = (ColormanageCacheKey *)key_v;
|
||||
|
||||
return key->ibuf->refcounter == 0;
|
||||
}
|
||||
|
||||
static void colormanage_keydeleter(void *key_v)
|
||||
{
|
||||
ColormanageCacheKey *key = (ColormanageCacheKey *)key_v;
|
||||
ImBuf *cache_ibuf = key->ibuf;
|
||||
|
||||
cache_ibuf->colormanage_refcounter--;
|
||||
|
||||
if (cache_ibuf->colormanage_refcounter == 0) {
|
||||
IMB_freeImBuf(key->ibuf);
|
||||
}
|
||||
}
|
||||
|
||||
static void colormanage_cache_init(void)
|
||||
{
|
||||
colormanage_cache = IMB_moviecache_create(sizeof(ColormanageCacheKey), colormanage_keydeleter,
|
||||
colormanage_hashhash, colormanage_hashcmp,
|
||||
NULL, colormanage_checkkeyunused);
|
||||
}
|
||||
|
||||
static void colormanage_cache_exit(void)
|
||||
{
|
||||
IMB_moviecache_free(colormanage_cache);
|
||||
}
|
||||
|
||||
#ifdef WITH_OCIO
|
||||
static unsigned char *colormanage_cache_get(ImBuf *ibuf, int view_transform, int display, void **cache_handle)
|
||||
{
|
||||
ImBuf *cache_ibuf;
|
||||
ColormanageCacheKey key;
|
||||
|
||||
*cache_handle = NULL;
|
||||
|
||||
key.ibuf = ibuf;
|
||||
key.view_transform = view_transform;
|
||||
key.display = display;
|
||||
|
||||
cache_ibuf = IMB_moviecache_get(colormanage_cache, &key);
|
||||
|
||||
if (cache_ibuf) {
|
||||
*cache_handle = cache_ibuf;
|
||||
|
||||
return (unsigned char *) cache_ibuf->rect;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void colormanage_cache_put(ImBuf *ibuf, int view_transform, int display,
|
||||
unsigned char *display_buffer, void **cache_handle)
|
||||
{
|
||||
ColormanageCacheKey key;
|
||||
ImBuf *cache_ibuf;
|
||||
|
||||
key.ibuf = ibuf;
|
||||
key.view_transform = view_transform;
|
||||
key.display = display;
|
||||
|
||||
cache_ibuf = IMB_allocImBuf(ibuf->x, ibuf->y, ibuf->planes, 0);
|
||||
cache_ibuf->rect = (unsigned int *) display_buffer;
|
||||
|
||||
cache_ibuf->mall |= IB_rect;
|
||||
cache_ibuf->flags |= IB_rect;
|
||||
|
||||
*cache_handle = cache_ibuf;
|
||||
|
||||
if ((ibuf->colormanage_flags & IMB_COLORMANAGED) == 0) {
|
||||
ibuf->colormanage_flags |= IMB_COLORMANAGED;
|
||||
|
||||
IMB_refImBuf(ibuf);
|
||||
}
|
||||
|
||||
ibuf->colormanage_refcounter++;
|
||||
|
||||
IMB_moviecache_put(colormanage_cache, &key, cache_ibuf);
|
||||
}
|
||||
|
||||
static void colormanage_cache_update(ImBuf *ibuf, unsigned char *display_buffer, void *cache_handle)
|
||||
{
|
||||
ImBuf *cache_ibuf = cache_handle;
|
||||
|
||||
/* remove old display buffer */
|
||||
MEM_freeN(cache_ibuf->rect);
|
||||
|
||||
/* resolution could have been changed for generated images */
|
||||
cache_ibuf->x = ibuf->x;
|
||||
cache_ibuf->y = ibuf->y;
|
||||
|
||||
/* use new display buffer */
|
||||
cache_ibuf->rect = (unsigned int *) display_buffer;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void colormanage_cache_handle_release(void *cache_handle)
|
||||
{
|
||||
ImBuf *cache_ibuf = cache_handle;
|
||||
|
||||
IMB_freeImBuf(cache_ibuf);
|
||||
}
|
||||
|
||||
/*********************** Initialization / De-initialization *************************/
|
||||
|
||||
#ifdef WITH_OCIO
|
||||
static void colormanage_load_config(ConstConfigRcPtr* config)
|
||||
{
|
||||
ConstColorSpaceRcPtr *ociocs;
|
||||
int tot_colorspace, tot_display, tot_display_view, index, viewindex, viewindex2;
|
||||
const char *name;
|
||||
|
||||
/* load colorspaces */
|
||||
tot_colorspace = OCIO_configGetNumColorSpaces(config);
|
||||
for (index = 0 ; index < tot_colorspace; index++) {
|
||||
ColorSpace *colorspace;
|
||||
|
||||
name = OCIO_configGetColorSpaceNameByIndex(config, index);
|
||||
ociocs = OCIO_configGetColorSpace(config, name);
|
||||
|
||||
colorspace = MEM_callocN(sizeof(ColorSpace), "ColorSpace");
|
||||
colorspace->index = index + 1;
|
||||
|
||||
BLI_strncpy(colorspace->name, name, sizeof(colorspace->name));
|
||||
|
||||
BLI_addtail(&global_colorspaces, colorspace);
|
||||
|
||||
OCIO_colorSpaceRelease(ociocs);
|
||||
}
|
||||
|
||||
/* load displays */
|
||||
viewindex2 = 0;
|
||||
tot_display = OCIO_configGetNumDisplays(config);
|
||||
|
||||
for (index = 0 ; index < tot_display; index++) {
|
||||
const char *displayname;
|
||||
ColorManagedDisplay *display;
|
||||
|
||||
displayname = OCIO_configGetDisplay(config, index);
|
||||
|
||||
display = colormanage_display_add(displayname);
|
||||
|
||||
/* load views */
|
||||
tot_display_view = OCIO_configGetNumViews(config, displayname);
|
||||
for (viewindex = 0 ; viewindex < tot_display_view; viewindex++, viewindex2++) {
|
||||
const char *viewname;
|
||||
ColorManagedView *view;
|
||||
LinkData *display_view;
|
||||
|
||||
viewname = OCIO_configGetView(config, displayname, viewindex);
|
||||
|
||||
/* first check if view transform with given name was already loaded */
|
||||
view = colormanage_view_get_named(viewname);
|
||||
|
||||
if (!view) {
|
||||
view = colormanage_view_add(viewname);
|
||||
}
|
||||
|
||||
display_view = BLI_genericNodeN(view);
|
||||
|
||||
BLI_addtail(&display->views, display_view);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void colormanage_free_config(void)
|
||||
{
|
||||
ColorSpace *colorspace;
|
||||
ColorManagedDisplay *display;
|
||||
ColorManagedView *view;
|
||||
|
||||
colorspace = global_colorspaces.first;
|
||||
while (colorspace) {
|
||||
ColorSpace *colorspace_next = colorspace->next;
|
||||
|
||||
MEM_freeN(colorspace);
|
||||
colorspace = colorspace_next;
|
||||
}
|
||||
|
||||
display = global_displays.first;
|
||||
while (display) {
|
||||
ColorManagedDisplay *display_next = display->next;
|
||||
LinkData *display_view = display->views.first;
|
||||
|
||||
while (display_view) {
|
||||
LinkData *display_view_next = display_view->next;
|
||||
|
||||
MEM_freeN(display_view);
|
||||
display_view = display_view_next;
|
||||
}
|
||||
|
||||
MEM_freeN(display);
|
||||
display = display_next;
|
||||
}
|
||||
|
||||
view = global_views.first;
|
||||
while (view) {
|
||||
ColorManagedView *view_next = view->next;
|
||||
|
||||
MEM_freeN(view);
|
||||
view = view_next;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void IMB_colormanagement_init(void)
|
||||
{
|
||||
#ifdef WITH_OCIO
|
||||
const char *ocio_env;
|
||||
const char *configdir;
|
||||
char configfile[FILE_MAXDIR+FILE_MAXFILE];
|
||||
@@ -74,13 +384,444 @@ void IMB_colormanagement_init(void)
|
||||
}
|
||||
|
||||
if (config) {
|
||||
colormgmt_load_config(config);
|
||||
OCIO_setCurrentConfig(config);
|
||||
|
||||
colormanage_load_config(config);
|
||||
}
|
||||
|
||||
OCIO_configRelease(config);
|
||||
|
||||
/* special views, which does not depend on OCIO */
|
||||
colormanage_view_add("ACES ODT Tonecurve");
|
||||
#endif
|
||||
|
||||
colormanage_cache_init();
|
||||
}
|
||||
|
||||
void IMB_colormanagement_exit(void)
|
||||
{
|
||||
colormgmt_free_config();
|
||||
#ifdef WITH_OCIO
|
||||
colormanage_free_config();
|
||||
#endif
|
||||
|
||||
colormanage_cache_exit();
|
||||
}
|
||||
|
||||
/*********************** Public display buffers interfaces *************************/
|
||||
|
||||
#ifdef WITH_OCIO
|
||||
static void display_buffer_apply_tonemap(ImBuf *ibuf, unsigned char *display_buffer,
|
||||
imb_tonecurveCb tonecurve_func)
|
||||
{
|
||||
int predivide = ibuf->flags & IB_cm_predivide;
|
||||
|
||||
IMB_buffer_byte_from_float_tonecurve(display_buffer, ibuf->rect_float,
|
||||
ibuf->channels, ibuf->dither, IB_PROFILE_SRGB, IB_PROFILE_LINEAR_RGB,
|
||||
predivide, ibuf->x, ibuf->y, ibuf->x, ibuf->x, tonecurve_func);
|
||||
}
|
||||
|
||||
static void display_buffer_apply_ocio(ImBuf *ibuf, unsigned char *display_buffer,
|
||||
const char *view_transform, const char *display)
|
||||
{
|
||||
ConstConfigRcPtr *config = OCIO_getCurrentConfig();
|
||||
DisplayTransformRcPtr *dt = OCIO_createDisplayTransform();
|
||||
ConstProcessorRcPtr *processor;
|
||||
float *rect_float;
|
||||
int predivide = ibuf->flags & IB_cm_predivide;
|
||||
PackedImageDesc *img;
|
||||
|
||||
rect_float = MEM_dupallocN(ibuf->rect_float);
|
||||
img = OCIO_createPackedImageDesc(rect_float, ibuf->x, ibuf->y, ibuf->channels, sizeof(float),
|
||||
ibuf->channels * sizeof(float), ibuf->channels * sizeof(float)*ibuf->x);
|
||||
|
||||
/* OCIO_TODO: get rid of hardcoded input and display spaces */
|
||||
OCIO_displayTransformSetInputColorSpaceName(dt, "aces");
|
||||
|
||||
OCIO_displayTransformSetView(dt, view_transform);
|
||||
OCIO_displayTransformSetDisplay(dt, display);
|
||||
|
||||
processor = OCIO_configGetProcessor(config, (ConstTransformRcPtr*)dt);
|
||||
|
||||
if (processor) {
|
||||
OCIO_processorApply(processor, img);
|
||||
|
||||
/* do conversion */
|
||||
IMB_buffer_byte_from_float(display_buffer, rect_float,
|
||||
ibuf->channels, ibuf->dither, IB_PROFILE_SRGB, IB_PROFILE_SRGB,
|
||||
predivide, ibuf->x, ibuf->y, ibuf->x, ibuf->x);
|
||||
}
|
||||
|
||||
OCIO_packedImageDescRelease(img);
|
||||
OCIO_displayTransformRelease(dt);
|
||||
OCIO_processorRelease(processor);
|
||||
OCIO_configRelease(config);
|
||||
|
||||
MEM_freeN(rect_float);
|
||||
}
|
||||
#endif
|
||||
|
||||
unsigned char *IMB_display_buffer_acquire(ImBuf *ibuf, const char *view_transform, const char *display, void **cache_handle)
|
||||
{
|
||||
*cache_handle = NULL;
|
||||
|
||||
#ifdef WITH_OCIO
|
||||
if (!ibuf->x || !ibuf->y)
|
||||
return NULL;
|
||||
|
||||
/* OCIO_TODO: support colormanaged byte buffers */
|
||||
if (!strcmp(view_transform, "NONE") || !ibuf->rect_float) {
|
||||
/* currently only view-transformation is allowed, input and display
|
||||
* spaces are hard-coded, so if there's no view transform applying
|
||||
* it's safe to suppose standard byte buffer is used for display
|
||||
*/
|
||||
|
||||
if (!ibuf->rect)
|
||||
IMB_rect_from_float(ibuf);
|
||||
|
||||
return (unsigned char *) ibuf->rect;
|
||||
}
|
||||
else {
|
||||
unsigned char *display_buffer;
|
||||
int buffer_size;
|
||||
int view_transform_index = IMB_colormanagement_view_get_named_index(view_transform);
|
||||
int display_index = IMB_colormanagement_display_get_named_index(display);
|
||||
int view_transform_flag = 1 << (view_transform_index - 1);
|
||||
|
||||
display_buffer = colormanage_cache_get(ibuf, view_transform_index, display_index, cache_handle);
|
||||
|
||||
if (display_buffer) {
|
||||
/* check whether display buffer isn't marked as dirty */
|
||||
if (ibuf->display_buffer_flags[display_index - 1] & view_transform_flag)
|
||||
return display_buffer;
|
||||
}
|
||||
|
||||
/* OCIO_TODO: in case when image is being resized it is possible
|
||||
* to save buffer allocation here
|
||||
*/
|
||||
|
||||
buffer_size = ibuf->channels * ibuf->x * ibuf->y * sizeof(float);
|
||||
display_buffer = MEM_callocN(buffer_size, "imbuf display buffer");
|
||||
|
||||
if (!strcmp(view_transform, "ACES ODT Tonecurve")) {
|
||||
/* special case for Mango team, this does not actually apply
|
||||
* any input space -> display space conversion and just applies
|
||||
* a tonecurve for better linear float -> sRGB byte conversion
|
||||
*/
|
||||
display_buffer_apply_tonemap(ibuf, display_buffer, IMB_ratio_preserving_odt_tonecurve);
|
||||
}
|
||||
else {
|
||||
display_buffer_apply_ocio(ibuf, display_buffer, view_transform, display);
|
||||
}
|
||||
|
||||
if (*cache_handle) {
|
||||
colormanage_cache_update(ibuf, display_buffer, *cache_handle);
|
||||
}
|
||||
else {
|
||||
colormanage_cache_put(ibuf, view_transform_index, display_index, display_buffer, cache_handle);
|
||||
}
|
||||
|
||||
ibuf->display_buffer_flags[display_index - 1] |= view_transform_flag;
|
||||
|
||||
return display_buffer;
|
||||
}
|
||||
#else
|
||||
/* no OCIO support, simply return byte buffer which was
|
||||
* generated from float buffer (if any) using standard
|
||||
* profiles without applying any view / display transformation */
|
||||
|
||||
(void) view_transform;
|
||||
(void) display;
|
||||
|
||||
if (!ibuf->rect) {
|
||||
IMB_rect_from_float(ibuf);
|
||||
}
|
||||
|
||||
return (unsigned char*) ibuf->rect;
|
||||
#endif
|
||||
}
|
||||
|
||||
void IMB_display_buffer_release(void *cache_handle)
|
||||
{
|
||||
if (cache_handle) {
|
||||
colormanage_cache_handle_release(cache_handle);
|
||||
}
|
||||
}
|
||||
|
||||
void IMB_display_buffer_invalidate(ImBuf *ibuf)
|
||||
{
|
||||
memset(ibuf->display_buffer_flags, 0, sizeof(ibuf->display_buffer_flags));
|
||||
}
|
||||
|
||||
void IMB_colormanagement_check_file_config(Main *bmain)
|
||||
{
|
||||
#ifdef WITH_OCIO
|
||||
wmWindowManager *wm = bmain->wm.first;
|
||||
wmWindow *win;
|
||||
bScreen *sc;
|
||||
|
||||
ColorManagedDisplay *default_display = colormanage_display_get_default();
|
||||
ColorManagedView *default_view = colormanage_view_get_default(default_display);
|
||||
|
||||
for (win = wm->windows.first; win; win = win->next) {
|
||||
if (win->display_device[0] == '\0') {
|
||||
BLI_strncpy(win->display_device, default_display->name, sizeof(win->display_device));
|
||||
}
|
||||
else {
|
||||
ColorManagedDisplay *display = colormanage_display_get_named(win->display_device);
|
||||
|
||||
if (!display) {
|
||||
printf("Blender color management: Window display \"%s\" not found, setting to default (\"%s\").\n",
|
||||
win->display_device, default_display->name);
|
||||
|
||||
BLI_strncpy(win->display_device, default_display->name, sizeof(win->display_device));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(sc = bmain->screen.first; sc; sc= sc->id.next) {
|
||||
ScrArea *sa;
|
||||
|
||||
for (sa = sc->areabase.first; sa; sa = sa->next) {
|
||||
SpaceLink *sl;
|
||||
for (sl = sa->spacedata.first; sl; sl = sl->next) {
|
||||
|
||||
if (sl->spacetype == SPACE_IMAGE) {
|
||||
SpaceImage *sima = (SpaceImage *) sl;
|
||||
|
||||
if (sima->view_transform[0] == '\0') {
|
||||
BLI_strncpy(sima->view_transform, "NONE", sizeof(sima->view_transform));
|
||||
}
|
||||
else if (!strcmp(sima->view_transform, "NONE")) {
|
||||
/* pass */
|
||||
}
|
||||
else {
|
||||
ColorManagedView *view = colormanage_view_get_named(sima->view_transform);
|
||||
|
||||
if (!view) {
|
||||
printf("Blender color management: image editor view \"%s\" not found, setting default \"%s\".\n",
|
||||
sima->view_transform, default_view->name);
|
||||
|
||||
BLI_strncpy(sima->view_transform, default_view->name, sizeof(sima->view_transform));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
(void) bmain;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*********************** Display functions *************************/
|
||||
|
||||
#ifdef WITH_OCIO
|
||||
ColorManagedDisplay *colormanage_display_get_default(void)
|
||||
{
|
||||
ConstConfigRcPtr *config = OCIO_getCurrentConfig();
|
||||
const char *display = OCIO_configGetDefaultDisplay(config);
|
||||
|
||||
OCIO_configRelease(config);
|
||||
|
||||
if (display[0] == '\0')
|
||||
return NULL;
|
||||
|
||||
return colormanage_display_get_named(display);
|
||||
}
|
||||
#endif
|
||||
|
||||
ColorManagedDisplay *colormanage_display_add(const char *name)
|
||||
{
|
||||
ColorManagedDisplay *display;
|
||||
int index = 0;
|
||||
|
||||
if (global_displays.last) {
|
||||
ColorManagedDisplay *last_display = global_displays.last;
|
||||
|
||||
index = last_display->index;
|
||||
}
|
||||
|
||||
display = MEM_callocN(sizeof(ColorManagedDisplay), "ColorManagedDisplay");
|
||||
|
||||
display->index = index + 1;
|
||||
|
||||
BLI_strncpy(display->name, name, sizeof(display->name));
|
||||
|
||||
BLI_addtail(&global_displays, display);
|
||||
|
||||
return display;
|
||||
}
|
||||
|
||||
ColorManagedDisplay *colormanage_display_get_named(const char *name)
|
||||
{
|
||||
ColorManagedDisplay *display;
|
||||
|
||||
for (display = global_displays.first; display; display = display->next) {
|
||||
if (!strcmp(display->name, name))
|
||||
return display;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ColorManagedDisplay *colormanage_display_get_indexed(int index)
|
||||
{
|
||||
/* display indices are 1-based */
|
||||
return BLI_findlink(&global_displays, index - 1);
|
||||
}
|
||||
|
||||
int IMB_colormanagement_display_get_named_index(const char *name)
|
||||
{
|
||||
ColorManagedDisplay *display;
|
||||
|
||||
display = colormanage_display_get_named(name);
|
||||
|
||||
if (display) {
|
||||
return display->index;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char *IMB_colormanagement_display_get_indexed_name(int index)
|
||||
{
|
||||
ColorManagedDisplay *display;
|
||||
|
||||
display = colormanage_display_get_indexed(index);
|
||||
|
||||
if (display) {
|
||||
return display->name;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*********************** View functions *************************/
|
||||
|
||||
#ifdef WITH_OCIO
|
||||
ColorManagedView *colormanage_view_get_default(const ColorManagedDisplay *display)
|
||||
{
|
||||
ConstConfigRcPtr *config = OCIO_getCurrentConfig();
|
||||
const char *name = OCIO_configGetDefaultView(config, display->name);
|
||||
OCIO_configRelease(config);
|
||||
|
||||
if (name[0] == '\0')
|
||||
return NULL;
|
||||
|
||||
return colormanage_view_get_named(name);
|
||||
}
|
||||
#endif
|
||||
|
||||
ColorManagedView *colormanage_view_add(const char *name)
|
||||
{
|
||||
ColorManagedView *view;
|
||||
int index = 0;
|
||||
|
||||
if (global_views.last) {
|
||||
ColorManagedView *last_view = global_views.last;
|
||||
|
||||
index = last_view->index;
|
||||
}
|
||||
|
||||
view = MEM_callocN(sizeof(ColorManagedView), "ColorManagedView");
|
||||
view->index = index + 1;
|
||||
BLI_strncpy(view->name, name, sizeof(view->name));
|
||||
|
||||
BLI_addtail(&global_views, view);
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
ColorManagedView *colormanage_view_get_named(const char *name)
|
||||
{
|
||||
ColorManagedView *view;
|
||||
|
||||
for (view = global_views.first; view; view = view->next) {
|
||||
if (!strcmp(view->name, name))
|
||||
return view;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ColorManagedView *colormanage_view_get_indexed(int index)
|
||||
{
|
||||
/* view transform indices are 1-based */
|
||||
return BLI_findlink(&global_views, index - 1);
|
||||
}
|
||||
|
||||
int IMB_colormanagement_view_get_named_index(const char *name)
|
||||
{
|
||||
ColorManagedView *view = colormanage_view_get_named(name);
|
||||
|
||||
if (view) {
|
||||
return view->index;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char *IMB_colormanagement_view_get_indexed_name(int index)
|
||||
{
|
||||
ColorManagedView *view = colormanage_view_get_indexed(index);
|
||||
|
||||
if (view) {
|
||||
return view->name;
|
||||
}
|
||||
|
||||
return "NONE";
|
||||
}
|
||||
|
||||
/*********************** RNA helper functions *************************/
|
||||
|
||||
void IMB_colormanagement_display_items_add(EnumPropertyItem **items, int *totitem)
|
||||
{
|
||||
ColorManagedDisplay *display;
|
||||
|
||||
for (display = global_displays.first; display; display = display->next) {
|
||||
EnumPropertyItem item;
|
||||
|
||||
item.value = display->index;
|
||||
item.name = display->name;
|
||||
item.identifier = display->name;
|
||||
item.icon = 0;
|
||||
item.description = "";
|
||||
|
||||
RNA_enum_item_add(items, totitem, &item);
|
||||
}
|
||||
}
|
||||
|
||||
static void colormanagement_view_item_add(EnumPropertyItem **items, int *totitem, ColorManagedView *view)
|
||||
{
|
||||
EnumPropertyItem item;
|
||||
|
||||
item.value = view->index;
|
||||
item.name = view->name;
|
||||
item.identifier = view->name;
|
||||
item.icon = 0;
|
||||
item.description = "";
|
||||
|
||||
RNA_enum_item_add(items, totitem, &item);
|
||||
}
|
||||
|
||||
void IMB_colormanagement_view_items_add(EnumPropertyItem **items, int *totitem, const char *display_name)
|
||||
{
|
||||
ColorManagedDisplay *display = colormanage_display_get_named(display_name);
|
||||
ColorManagedView *view;
|
||||
|
||||
/* OCIO_TODO: try to get rid of such a hackish stuff */
|
||||
view = colormanage_view_get_named("ACES ODT Tonecurve");
|
||||
if (view) {
|
||||
colormanagement_view_item_add(items, totitem, view);
|
||||
}
|
||||
|
||||
if (display) {
|
||||
LinkData *display_view;
|
||||
|
||||
for (display_view = display->views.first; display_view; display_view = display_view->next) {
|
||||
view = display_view->data;
|
||||
|
||||
colormanagement_view_item_add(items, totitem, view);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -192,11 +192,13 @@ MINLINE void float_to_byte_dither_v4(uchar b[4], const float f[4], DitherContext
|
||||
}
|
||||
|
||||
/* float to byte pixels, output 4-channel RGBA */
|
||||
void IMB_buffer_byte_from_float(uchar *rect_to, const float *rect_from,
|
||||
int channels_from, float dither, int profile_to, int profile_from, int predivide,
|
||||
int width, int height, int stride_to, int stride_from)
|
||||
void IMB_buffer_byte_from_float_tonecurve(uchar *rect_to, const float *rect_from,
|
||||
int channels_from, float dither, int profile_to, int profile_from, int predivide,
|
||||
int width, int height, int stride_to, int stride_from,
|
||||
imb_tonecurveCb tonecurve_func)
|
||||
{
|
||||
float tmp[4];
|
||||
float corrected[4];
|
||||
int x, y;
|
||||
DitherContext *di;
|
||||
|
||||
@@ -208,6 +210,9 @@ void IMB_buffer_byte_from_float(uchar *rect_to, const float *rect_from,
|
||||
if (dither)
|
||||
di = create_dither_context(width, dither);
|
||||
|
||||
if (!tonecurve_func)
|
||||
tonecurve_func = copy_v3_v3;
|
||||
|
||||
for (y = 0; y < height; y++) {
|
||||
if (channels_from == 1) {
|
||||
/* single channel input */
|
||||
@@ -232,7 +237,8 @@ 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 */
|
||||
for (x = 0; x < width; x++, from += 3, to += 4) {
|
||||
linearrgb_to_srgb_v3_v3(tmp, from);
|
||||
tonecurve_func(corrected, from);
|
||||
linearrgb_to_srgb_v3_v3(tmp, corrected);
|
||||
rgb_float_to_uchar(to, tmp);
|
||||
to[3] = 255;
|
||||
}
|
||||
@@ -268,25 +274,37 @@ void IMB_buffer_byte_from_float(uchar *rect_to, const float *rect_from,
|
||||
|
||||
if (dither && predivide) {
|
||||
for (x = 0; x < width; x++, from += 4, to += 4) {
|
||||
linearrgb_to_srgb_ushort4_predivide(us, from);
|
||||
tonecurve_func(corrected, from);
|
||||
corrected[3] = from[3];
|
||||
|
||||
linearrgb_to_srgb_ushort4_predivide(us, corrected);
|
||||
ushort_to_byte_dither_v4(to, us, di);
|
||||
}
|
||||
}
|
||||
else if (dither) {
|
||||
for (x = 0; x < width; x++, from += 4, to += 4) {
|
||||
linearrgb_to_srgb_ushort4(us, from);
|
||||
tonecurve_func(corrected, from);
|
||||
corrected[3] = from[3];
|
||||
|
||||
linearrgb_to_srgb_ushort4(us, corrected);
|
||||
ushort_to_byte_dither_v4(to, us, di);
|
||||
}
|
||||
}
|
||||
else if (predivide) {
|
||||
for (x = 0; x < width; x++, from += 4, to += 4) {
|
||||
linearrgb_to_srgb_ushort4_predivide(us, from);
|
||||
tonecurve_func(corrected, from);
|
||||
corrected[3] = from[3];
|
||||
|
||||
linearrgb_to_srgb_ushort4_predivide(us, corrected);
|
||||
ushort_to_byte_v4(to, us);
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (x = 0; x < width; x++, from += 4, to += 4) {
|
||||
linearrgb_to_srgb_ushort4(us, from);
|
||||
tonecurve_func(corrected, from);
|
||||
corrected[3] = from[3];
|
||||
|
||||
linearrgb_to_srgb_ushort4(us, corrected);
|
||||
ushort_to_byte_v4(to, us);
|
||||
}
|
||||
}
|
||||
@@ -328,6 +346,15 @@ void IMB_buffer_byte_from_float(uchar *rect_to, const float *rect_from,
|
||||
clear_dither_context(di);
|
||||
}
|
||||
|
||||
void IMB_buffer_byte_from_float(uchar *rect_to, const float *rect_from,
|
||||
int channels_from, float dither, int profile_to, int profile_from, int predivide,
|
||||
int width, int height, int stride_to, int stride_from)
|
||||
{
|
||||
IMB_buffer_byte_from_float_tonecurve(rect_to, rect_from, channels_from, dither, profile_to, profile_from, predivide,
|
||||
width, height, stride_to, stride_from, NULL);
|
||||
}
|
||||
|
||||
|
||||
/* byte to float pixels, input and output 4-channel RGBA */
|
||||
void IMB_buffer_float_from_byte(float *rect_to, const uchar *rect_from,
|
||||
int profile_to, int profile_from, int predivide,
|
||||
@@ -527,89 +554,6 @@ void IMB_buffer_byte_from_byte(uchar *rect_to, const uchar *rect_from,
|
||||
}
|
||||
}
|
||||
|
||||
/* float to byte pixels, output 4-channel RGBA */
|
||||
void IMB_buffer_srgb_byte_from_linear_float(uchar *rect_to, const float *rect_from,
|
||||
int channels_from, float dither, int predivide,
|
||||
int width, int height, int stride_to, int stride_from)
|
||||
{
|
||||
float tmp[4];
|
||||
int x, y;
|
||||
DitherContext *di;
|
||||
float corrected[4];
|
||||
|
||||
BLI_init_srgb_conversion();
|
||||
|
||||
if (dither)
|
||||
di = create_dither_context(width, dither);
|
||||
|
||||
for (y = 0; y < height; y++) {
|
||||
if (channels_from == 1) {
|
||||
/* single channel input */
|
||||
const float *from = rect_from + stride_from * y;
|
||||
uchar *to = rect_to + stride_to * y * 4;
|
||||
|
||||
for (x = 0; x < width; x++, from++, to += 4)
|
||||
to[0] = to[1] = to[2] = to[3] = FTOCHAR(from[0]);
|
||||
}
|
||||
else if (channels_from == 3) {
|
||||
/* RGB input */
|
||||
const float *from = rect_from + stride_from * y * 3;
|
||||
uchar *to = rect_to + stride_to * y * 4;
|
||||
|
||||
/* convert from linear to sRGB */
|
||||
for (x = 0; x < width; x++, from += 3, to += 4) {
|
||||
IMB_ratio_preserving_odt_tonecurve_v3(from, corrected);
|
||||
linearrgb_to_srgb_v3_v3(tmp, corrected);
|
||||
rgb_float_to_uchar(to, tmp);
|
||||
to[3] = 255;
|
||||
}
|
||||
}
|
||||
else if (channels_from == 4) {
|
||||
/* RGBA input */
|
||||
const float *from = rect_from + stride_from * y * 4;
|
||||
uchar *to = rect_to + stride_to * y * 4;
|
||||
|
||||
/* convert from linear to sRGB */
|
||||
unsigned short us[4];
|
||||
|
||||
if (dither && predivide) {
|
||||
for (x = 0; x < width; x++, from += 4, to += 4) {
|
||||
IMB_ratio_preserving_odt_tonecurve_v4(from, corrected);
|
||||
linearrgb_to_srgb_ushort4_predivide(us, corrected);
|
||||
ushort_to_byte_dither_v4(to, us, di);
|
||||
}
|
||||
}
|
||||
else if (dither) {
|
||||
for (x = 0; x < width; x++, from += 4, to += 4) {
|
||||
IMB_ratio_preserving_odt_tonecurve_v4(from, corrected);
|
||||
linearrgb_to_srgb_ushort4(us, corrected);
|
||||
ushort_to_byte_dither_v4(to, us, di);
|
||||
}
|
||||
}
|
||||
else if (predivide) {
|
||||
for (x = 0; x < width; x++, from += 4, to += 4) {
|
||||
IMB_ratio_preserving_odt_tonecurve_v4(from, corrected);
|
||||
linearrgb_to_srgb_ushort4_predivide(us, corrected);
|
||||
ushort_to_byte_v4(to, us);
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (x = 0; x < width; x++, from += 4, to += 4) {
|
||||
IMB_ratio_preserving_odt_tonecurve_v4(from, corrected);
|
||||
linearrgb_to_srgb_ushort4(us, corrected);
|
||||
ushort_to_byte_v4(to, us);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (dither)
|
||||
dither_finish_row(di);
|
||||
}
|
||||
|
||||
if (dither)
|
||||
clear_dither_context(di);
|
||||
}
|
||||
|
||||
/****************************** ImBuf Conversion *****************************/
|
||||
|
||||
void IMB_rect_from_float(ImBuf *ibuf)
|
||||
@@ -621,10 +565,6 @@ void IMB_rect_from_float(ImBuf *ibuf)
|
||||
if (ibuf->rect_float == NULL)
|
||||
return;
|
||||
|
||||
if (ibuf->userflags & IB_RECT_INVALID) {
|
||||
imb_freerectviewImBuf_all(ibuf);
|
||||
}
|
||||
|
||||
/* create byte rect if it didn't exist yet */
|
||||
if (ibuf->rect == NULL)
|
||||
imb_addrectImBuf(ibuf);
|
||||
@@ -650,113 +590,6 @@ void IMB_rect_from_float(ImBuf *ibuf)
|
||||
ibuf->userflags &= ~IB_RECT_INVALID;
|
||||
}
|
||||
|
||||
void IMB_rect_from_float_with_view_transform(ImBuf *ibuf, int view_transform)
|
||||
{
|
||||
int predivide = (ibuf->flags & IB_cm_predivide);
|
||||
|
||||
/* verify we have a float buffer */
|
||||
if (ibuf->rect_float == NULL)
|
||||
return;
|
||||
|
||||
if (ibuf->userflags & IB_RECT_INVALID) {
|
||||
imb_freerectviewImBuf_all(ibuf);
|
||||
}
|
||||
|
||||
#ifdef WITH_OCIO
|
||||
if (view_transform == IMB_VIEW_TRANSFORM_NONE)
|
||||
#else
|
||||
(void)view_transform;
|
||||
#endif /* WITH_OCIO */
|
||||
{
|
||||
int profile_from;
|
||||
|
||||
/* create byte rect if it didn't exist yet */
|
||||
if (ibuf->rect == NULL)
|
||||
imb_addrectImBuf(ibuf);
|
||||
|
||||
/* determine profiles */
|
||||
if (ibuf->profile == IB_PROFILE_LINEAR_RGB) {
|
||||
profile_from = IB_PROFILE_LINEAR_RGB;
|
||||
}
|
||||
else if (ELEM(ibuf->profile, IB_PROFILE_SRGB, IB_PROFILE_NONE)) {
|
||||
profile_from = IB_PROFILE_SRGB;
|
||||
}
|
||||
else {
|
||||
profile_from = IB_PROFILE_SRGB; /* should never happen */
|
||||
BLI_assert(0);
|
||||
}
|
||||
|
||||
/* do conversion */
|
||||
IMB_buffer_byte_from_float((uchar *)ibuf->rect, ibuf->rect_float,
|
||||
ibuf->channels, ibuf->dither, IB_PROFILE_SRGB, profile_from, predivide,
|
||||
ibuf->x, ibuf->y, ibuf->x, ibuf->x);
|
||||
}
|
||||
#ifdef WITH_OCIO
|
||||
else if (view_transform == IMB_VIEW_TRANSFORM_ACES_ODT_TONECURVE) {
|
||||
unsigned int *rect_view;
|
||||
|
||||
/* create byte rect if it didn't exist yet */
|
||||
if (ibuf->rect_view[view_transform] == NULL)
|
||||
imb_addrectviewImBuf(ibuf, view_transform);
|
||||
|
||||
rect_view = imb_getrectviewImBuf(ibuf, view_transform);
|
||||
|
||||
IMB_buffer_srgb_byte_from_linear_float((uchar *)rect_view, ibuf->rect_float,
|
||||
ibuf->channels, ibuf->dither, predivide,
|
||||
ibuf->x, ibuf->y, ibuf->x, ibuf->x);
|
||||
}
|
||||
else if (ibuf->x && ibuf->y) {
|
||||
ConstConfigRcPtr *config = OCIO_getCurrentConfig();
|
||||
ConstProcessorRcPtr *processor;
|
||||
DisplayTransformRcPtr *dt = OCIO_createDisplayTransform();
|
||||
PackedImageDesc *img;
|
||||
float *rect_float;
|
||||
|
||||
OCIO_displayTransformSetInputColorSpaceName(dt, "aces");
|
||||
OCIO_displayTransformSetDisplay(dt, "sRGB");
|
||||
|
||||
if (view_transform == IMB_VIEW_TRANSFORM_OCIO_RAW)
|
||||
OCIO_displayTransformSetView(dt, "Raw");
|
||||
else if (view_transform == IMB_VIEW_TRANSFORM_OCIO_RRT)
|
||||
OCIO_displayTransformSetView(dt, "RRT");
|
||||
else if (view_transform == IMB_VIEW_TRANSFORM_OCIO_LOG)
|
||||
OCIO_displayTransformSetView(dt, "Log");
|
||||
|
||||
rect_float = MEM_dupallocN(ibuf->rect_float);
|
||||
img = OCIO_createPackedImageDesc(rect_float, ibuf->x, ibuf->y, ibuf->channels, sizeof(float),
|
||||
ibuf->channels * sizeof(float), ibuf->channels * sizeof(float)*ibuf->x);
|
||||
|
||||
processor = OCIO_configGetProcessor(config, (ConstTransformRcPtr*)dt);
|
||||
if (processor) {
|
||||
unsigned int *rect_view;
|
||||
|
||||
OCIO_processorApply(processor, img);
|
||||
|
||||
/* create byte rect if it didn't exist yet */
|
||||
if (ibuf->rect_view[view_transform] == NULL)
|
||||
imb_addrectviewImBuf(ibuf, view_transform);
|
||||
|
||||
rect_view = imb_getrectviewImBuf(ibuf, view_transform);
|
||||
|
||||
/* do conversion */
|
||||
IMB_buffer_byte_from_float((uchar *)rect_view, rect_float,
|
||||
ibuf->channels, ibuf->dither, IB_PROFILE_SRGB, IB_PROFILE_SRGB, predivide,
|
||||
ibuf->x, ibuf->y, ibuf->x, ibuf->x);
|
||||
|
||||
}
|
||||
|
||||
OCIO_packedImageDescRelease(img);
|
||||
OCIO_displayTransformRelease(dt);
|
||||
OCIO_processorRelease(processor);
|
||||
OCIO_configRelease(config);
|
||||
|
||||
MEM_freeN(rect_float);
|
||||
}
|
||||
#endif /* WITH_OCIO */
|
||||
|
||||
ibuf->userflags &= ~IB_RECT_INVALID;
|
||||
}
|
||||
|
||||
/* converts from linear float to sRGB byte for part of the texture, buffer will hold the changed part */
|
||||
void IMB_partial_rect_from_float(ImBuf *ibuf, float *buffer, int x, int y, int w, int h)
|
||||
{
|
||||
|
||||
@@ -755,7 +755,7 @@ static float rdt_shaper_fwd( float x)
|
||||
return y;
|
||||
}
|
||||
|
||||
void IMB_ratio_preserving_odt_tonecurve_v3(const float rgbIn[3], float rgbOut[3])
|
||||
void IMB_ratio_preserving_odt_tonecurve(float rgbOut[3], const float rgbIn[3])
|
||||
{
|
||||
//
|
||||
// The "ratio preserving tonecurve" is used to avoid hue/chroma shifts.
|
||||
@@ -783,10 +783,3 @@ void IMB_ratio_preserving_odt_tonecurve_v3(const float rgbIn[3], float rgbOut[3]
|
||||
rgbOut[2] = rgbIn[2] * normRGBo / normRGB;
|
||||
}
|
||||
}
|
||||
|
||||
void IMB_ratio_preserving_odt_tonecurve_v4(const float rgbIn[4], float rgbOut[4])
|
||||
{
|
||||
IMB_ratio_preserving_odt_tonecurve_v3(rgbIn, rgbOut);
|
||||
|
||||
rgbOut[3] = rgbIn[3];
|
||||
}
|
||||
|
||||
@@ -48,9 +48,11 @@ static MEM_CacheLimiterC *limitor = NULL;
|
||||
|
||||
typedef struct MovieCache {
|
||||
GHash *hash;
|
||||
MoviKeyDeleterFP keydeleterfp;
|
||||
GHashHashFP hashfp;
|
||||
GHashCmpFP cmpfp;
|
||||
MovieCacheGetKeyDataFP getdatafp;
|
||||
MovieCacheCheckKeyUnusedFP checkkeyunusedfp;
|
||||
|
||||
struct BLI_mempool *keys_pool;
|
||||
struct BLI_mempool *items_pool;
|
||||
@@ -94,6 +96,12 @@ static void moviecache_keyfree(void *val)
|
||||
{
|
||||
MovieCacheKey *key = (MovieCacheKey *)val;
|
||||
|
||||
if (key->cache_owner->keydeleterfp) {
|
||||
key->cache_owner->keydeleterfp(key->userkey);
|
||||
}
|
||||
|
||||
BLI_mempool_free(key->cache_owner->userkeys_pool, key->userkey);
|
||||
|
||||
BLI_mempool_free(key->cache_owner->keys_pool, key);
|
||||
}
|
||||
|
||||
@@ -117,10 +125,16 @@ static void check_unused_keys(MovieCache *cache)
|
||||
while (!BLI_ghashIterator_isDone(iter)) {
|
||||
MovieCacheKey *key = BLI_ghashIterator_getKey(iter);
|
||||
MovieCacheItem *item = BLI_ghashIterator_getValue(iter);
|
||||
int remove = 0;
|
||||
|
||||
BLI_ghashIterator_step(iter);
|
||||
|
||||
if (!item->ibuf)
|
||||
remove = !item->ibuf;
|
||||
|
||||
if (!remove && cache->checkkeyunusedfp)
|
||||
remove = cache->checkkeyunusedfp(key->userkey);
|
||||
|
||||
if (remove)
|
||||
BLI_ghash_remove(cache->hash, key, moviecache_keyfree, moviecache_valfree);
|
||||
}
|
||||
|
||||
@@ -198,8 +212,10 @@ void IMB_moviecache_destruct(void)
|
||||
delete_MEM_CacheLimiter(limitor);
|
||||
}
|
||||
|
||||
MovieCache *IMB_moviecache_create(int keysize, GHashHashFP hashfp, GHashCmpFP cmpfp,
|
||||
MovieCacheGetKeyDataFP getdatafp)
|
||||
MovieCache *IMB_moviecache_create(int keysize, MoviKeyDeleterFP keydeleterfp,
|
||||
GHashHashFP hashfp, GHashCmpFP cmpfp,
|
||||
MovieCacheGetKeyDataFP getdatafp,
|
||||
MovieCacheCheckKeyUnusedFP checkkeyunusedfp)
|
||||
{
|
||||
MovieCache *cache;
|
||||
|
||||
@@ -209,10 +225,12 @@ MovieCache *IMB_moviecache_create(int keysize, GHashHashFP hashfp, GHashCmpFP cm
|
||||
cache->userkeys_pool = BLI_mempool_create(keysize, 64, 64, 0);
|
||||
cache->hash = BLI_ghash_new(moviecache_hashhash, moviecache_hashcmp, "MovieClip ImBuf cache hash");
|
||||
|
||||
cache->keydeleterfp = keydeleterfp;
|
||||
cache->keysize = keysize;
|
||||
cache->hashfp = hashfp;
|
||||
cache->cmpfp = cmpfp;
|
||||
cache->getdatafp = getdatafp;
|
||||
cache->checkkeyunusedfp = checkkeyunusedfp;
|
||||
cache->proxy = -1;
|
||||
|
||||
return cache;
|
||||
|
||||
@@ -691,7 +691,7 @@ typedef struct SpaceImage {
|
||||
char around;
|
||||
|
||||
/* color transformation */
|
||||
int view_transform, pad2;
|
||||
char view_transform[64];
|
||||
} SpaceImage;
|
||||
|
||||
|
||||
@@ -755,15 +755,6 @@ typedef enum eSpaceImage_Flag {
|
||||
SI_COLOR_CORRECTION = (1 << 24),
|
||||
} eSpaceImage_Flag;
|
||||
|
||||
/* SpaceImage->flag */
|
||||
typedef enum eSpaceImage_ViewTransform {
|
||||
SI_VIEW_TRANSFORM_NONE = 0,
|
||||
SI_VIEW_TRANSFORM_ACES_ODT_TONECURVE = 1,
|
||||
SI_VIEW_TRANSFORM_OCIO_RAW = 2,
|
||||
SI_VIEW_TRANSFORM_OCIO_RRT = 3,
|
||||
SI_VIEW_TRANSFORM_OCIO_LOG = 4,
|
||||
} eSpaceImage_ViewTransform;
|
||||
|
||||
/* Text Editor ============================================ */
|
||||
|
||||
/* Text Editor */
|
||||
|
||||
@@ -195,6 +195,8 @@ typedef struct wmWindow {
|
||||
|
||||
ListBase subwindows; /* opengl stuff for sub windows, see notes in wm_subwindow.c */
|
||||
ListBase gesture; /* gesture stuff */
|
||||
|
||||
char display_device[64]; /* color managed display device name */
|
||||
} wmWindow;
|
||||
|
||||
/* should be something like DNA_EXCLUDE
|
||||
|
||||
@@ -118,6 +118,11 @@ EnumPropertyItem viewport_shade_items[] = {
|
||||
{0, NULL, 0, NULL, NULL}
|
||||
};
|
||||
|
||||
static EnumPropertyItem view_transform_items[] = {
|
||||
{0, "NONE", 0, "None", ""},
|
||||
{0, NULL, 0, NULL, NULL}
|
||||
};
|
||||
|
||||
#ifdef RNA_RUNTIME
|
||||
|
||||
#include "DNA_anim_types.h"
|
||||
@@ -143,6 +148,7 @@ EnumPropertyItem viewport_shade_items[] = {
|
||||
#include "ED_sequencer.h"
|
||||
#include "ED_clip.h"
|
||||
|
||||
#include "IMB_colormanagement.h"
|
||||
#include "IMB_imbuf_types.h"
|
||||
|
||||
static StructRNA *rna_Space_refine(struct PointerRNA *ptr)
|
||||
@@ -665,6 +671,38 @@ static void rna_SpaceImageEditor_scopes_update(Main *UNUSED(bmain), Scene *scene
|
||||
ED_space_image_release_buffer(sima, lock);
|
||||
}
|
||||
|
||||
static int rna_SpaceImageEditor_view_transform_get(PointerRNA *ptr)
|
||||
{
|
||||
SpaceImage *sima = (SpaceImage *) ptr->data;
|
||||
|
||||
return IMB_colormanagement_view_get_named_index(sima->view_transform);
|
||||
}
|
||||
|
||||
static void rna_SpaceImageEditor_view_transform_set(PointerRNA *ptr, int value)
|
||||
{
|
||||
SpaceImage *sima = (SpaceImage*) ptr->data;
|
||||
|
||||
const char *name = IMB_colormanagement_view_get_indexed_name(value);
|
||||
|
||||
if (name) {
|
||||
BLI_strncpy(sima->view_transform, name, sizeof(sima->view_transform));
|
||||
}
|
||||
}
|
||||
|
||||
static EnumPropertyItem* rna_SpaceImageEditor_view_transform_itemf(bContext *C, PointerRNA *ptr, PropertyRNA *UNUSED(prop), int *free)
|
||||
{
|
||||
wmWindow *win = CTX_wm_window(C);
|
||||
EnumPropertyItem *items = NULL;
|
||||
int totitem = 0;
|
||||
|
||||
RNA_enum_item_add(&items, &totitem, &view_transform_items[0]);
|
||||
IMB_colormanagement_view_items_add(&items, &totitem, win->display_device);
|
||||
RNA_enum_item_end(&items, &totitem);
|
||||
|
||||
*free = 1;
|
||||
return items;
|
||||
}
|
||||
|
||||
/* Space Text Editor */
|
||||
|
||||
static void rna_SpaceTextEditor_word_wrap_set(PointerRNA *ptr, int value)
|
||||
@@ -1922,15 +1960,6 @@ static void rna_def_space_image(BlenderRNA *brna)
|
||||
StructRNA *srna;
|
||||
PropertyRNA *prop;
|
||||
|
||||
static EnumPropertyItem view_transform_items[] = {
|
||||
{SI_VIEW_TRANSFORM_NONE, "NONE", ICON_NONE, "None", ""},
|
||||
{SI_VIEW_TRANSFORM_ACES_ODT_TONECURVE, "ACES_TOMEMAP", ICON_NONE, "ACES ODT Tonecurve", ""},
|
||||
{SI_VIEW_TRANSFORM_OCIO_RAW, "OCIO_RAW", ICON_NONE, "OCIO RAW", ""},
|
||||
{SI_VIEW_TRANSFORM_OCIO_RRT, "OCIO_RRT", ICON_NONE, "OCIO RRT", ""},
|
||||
{SI_VIEW_TRANSFORM_OCIO_LOG, "OCIO_LOG", ICON_NONE, "OCIO LOG", ""},
|
||||
{0, NULL, 0, NULL, NULL}
|
||||
};
|
||||
|
||||
srna = RNA_def_struct(brna, "SpaceImageEditor", "Space");
|
||||
RNA_def_struct_sdna(srna, "SpaceImage");
|
||||
RNA_def_struct_ui_text(srna, "Space Image Editor", "Image and UV editor space data");
|
||||
@@ -2035,10 +2064,11 @@ static void rna_def_space_image(BlenderRNA *brna)
|
||||
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
|
||||
RNA_def_property_ui_text(prop, "Show UV Editor", "Show UV editing related properties");
|
||||
|
||||
prop = RNA_def_property(srna, "view_transform", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_sdna(prop, NULL, "view_transform");
|
||||
prop= RNA_def_property(srna, "view_transform", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_items(prop, view_transform_items);
|
||||
RNA_def_property_ui_text(prop, "View Transform", "Transformation used on linear to sRGB conversion");
|
||||
RNA_def_property_enum_funcs(prop, "rna_SpaceImageEditor_view_transform_get", "rna_SpaceImageEditor_view_transform_set",
|
||||
"rna_SpaceImageEditor_view_transform_itemf");
|
||||
RNA_def_property_ui_text(prop, "View Transform", "View transform used for this image editor");
|
||||
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_IMAGE, NULL);
|
||||
|
||||
rna_def_space_image_uv(brna);
|
||||
|
||||
@@ -440,6 +440,8 @@ EnumPropertyItem wm_report_items[] = {
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "IMB_colormanagement.h"
|
||||
|
||||
static wmOperator *rna_OperatorProperties_find_operator(PointerRNA *ptr)
|
||||
{
|
||||
wmWindowManager *wm = ptr->id.data;
|
||||
@@ -570,6 +572,36 @@ static void rna_Window_screen_update(bContext *C, PointerRNA *ptr)
|
||||
}
|
||||
}
|
||||
|
||||
static int rna_Window_display_device_get(struct PointerRNA *ptr)
|
||||
{
|
||||
wmWindow *win = (wmWindow *) ptr->data;
|
||||
|
||||
return IMB_colormanagement_display_get_named_index(win->display_device);
|
||||
}
|
||||
|
||||
static void rna_Window_display_device_set(struct PointerRNA *ptr, int value)
|
||||
{
|
||||
wmWindow *win = (wmWindow *) ptr->data;
|
||||
const char *name = IMB_colormanagement_display_get_indexed_name(value);
|
||||
|
||||
if (name) {
|
||||
BLI_strncpy(win->display_device, name, sizeof(win->display_device));
|
||||
}
|
||||
}
|
||||
|
||||
static EnumPropertyItem *rna_Window_display_device_itemf(bContext *C, PointerRNA *ptr, PropertyRNA *UNUSED(prop), int *free)
|
||||
{
|
||||
EnumPropertyItem *items = NULL;
|
||||
int totitem = 0;
|
||||
|
||||
IMB_colormanagement_display_items_add(&items, &totitem);
|
||||
RNA_enum_item_end(&items, &totitem);
|
||||
|
||||
*free = TRUE;
|
||||
|
||||
return items;
|
||||
}
|
||||
|
||||
static PointerRNA rna_KeyMapItem_properties_get(PointerRNA *ptr)
|
||||
{
|
||||
wmKeyMapItem *kmi = ptr->data;
|
||||
@@ -1577,6 +1609,11 @@ static void rna_def_window(BlenderRNA *brna)
|
||||
StructRNA *srna;
|
||||
PropertyRNA *prop;
|
||||
|
||||
static EnumPropertyItem display_device_items[] = {
|
||||
{0, "DEFAULT", 0, "Default", ""},
|
||||
{0, NULL, 0, NULL, NULL}
|
||||
};
|
||||
|
||||
srna = RNA_def_struct(brna, "Window", NULL);
|
||||
RNA_def_struct_ui_text(srna, "Window", "Open window");
|
||||
RNA_def_struct_sdna(srna, "wmWindow");
|
||||
@@ -1589,6 +1626,14 @@ static void rna_def_window(BlenderRNA *brna)
|
||||
RNA_def_property_pointer_funcs(prop, NULL, "rna_Window_screen_set", NULL, NULL);
|
||||
RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
|
||||
RNA_def_property_update(prop, 0, "rna_Window_screen_update");
|
||||
|
||||
/* Color Management Display */
|
||||
prop= RNA_def_property(srna, "display_device", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_items(prop, display_device_items);
|
||||
RNA_def_property_enum_funcs(prop, "rna_Window_display_device_get", "rna_Window_display_device_set",
|
||||
"rna_Window_display_device_itemf");
|
||||
RNA_def_property_ui_text(prop, "Display Device", "Display device name used for this window");
|
||||
RNA_def_property_update(prop, NC_WINDOW, NULL);
|
||||
}
|
||||
|
||||
/* curve.splines */
|
||||
|
||||
@@ -143,12 +143,4 @@ if(WIN322)
|
||||
)
|
||||
endif()
|
||||
|
||||
if(WITH_OPENCOLORIO)
|
||||
add_definitions(-DWITH_OCIO)
|
||||
endif()
|
||||
|
||||
if(WITH_OPENCOLORIO)
|
||||
add_definitions(-DWITH_OCIO)
|
||||
endif()
|
||||
|
||||
blender_add_lib_nolist(bf_windowmanager "${SRC}" "${INC}" "${INC_SYS}")
|
||||
|
||||
@@ -43,10 +43,4 @@ if env['BF_BUILDINFO']:
|
||||
if env['WITH_BF_INTERNATIONAL']:
|
||||
defs.append('WITH_INTERNATIONAL')
|
||||
|
||||
if env['WITH_BF_OCIO']:
|
||||
defs.append('WITH_OCIO')
|
||||
|
||||
if env['WITH_BF_OCIO']:
|
||||
defs.append('WITH_OCIO')
|
||||
|
||||
env.BlenderLib ( 'bf_windowmanager', sources, Split(incs), defines=defs, libtype=['core'], priority=[5] )
|
||||
|
||||
@@ -110,9 +110,7 @@
|
||||
#include "BKE_depsgraph.h"
|
||||
#include "BKE_sound.h"
|
||||
|
||||
#ifdef WITH_OCIO
|
||||
#include "IMB_colormanagement.h"
|
||||
#endif
|
||||
|
||||
static void wm_init_reports(bContext *C)
|
||||
{
|
||||
@@ -147,6 +145,10 @@ void WM_init(bContext *C, int argc, const char **argv)
|
||||
|
||||
BLF_init(11, U.dpi); /* Please update source/gamengine/GamePlayer/GPG_ghost.cpp if you change this */
|
||||
BLF_lang_init();
|
||||
|
||||
/* initialize color management stuff */
|
||||
IMB_colormanagement_init();
|
||||
|
||||
/* get the default database, plus a wm */
|
||||
WM_read_homefile(C, NULL, G.factory_startup);
|
||||
|
||||
@@ -203,10 +205,6 @@ void WM_init(bContext *C, int argc, const char **argv)
|
||||
#endif
|
||||
|
||||
BLI_strncpy(G.lib, G.main->name, FILE_MAX);
|
||||
|
||||
#ifdef WITH_OCIO
|
||||
IMB_colormanagement_init();
|
||||
#endif
|
||||
}
|
||||
|
||||
void WM_init_splash(bContext *C)
|
||||
@@ -340,6 +338,7 @@ void WM_exit_ext(bContext *C, const short do_python)
|
||||
|
||||
sound_exit();
|
||||
|
||||
IMB_colormanagement_exit();
|
||||
|
||||
/* first wrap up running stuff, we assume only the active WM is running */
|
||||
/* modal handlers are on window level freed, others too? */
|
||||
@@ -460,10 +459,6 @@ void WM_exit_ext(bContext *C, const short do_python)
|
||||
getchar();
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef WITH_OCIO
|
||||
IMB_colormanagement_exit();
|
||||
#endif
|
||||
}
|
||||
|
||||
void WM_exit(bContext *C)
|
||||
|
||||
@@ -243,7 +243,9 @@ wmWindow *wm_window_copy(bContext *C, wmWindow *winorig)
|
||||
|
||||
win->drawmethod = -1;
|
||||
win->drawdata = NULL;
|
||||
|
||||
|
||||
BLI_strncpy(win->display_device, winorig->display_device, sizeof(win->display_device));
|
||||
|
||||
return win;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user