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:
Sergey Sharybin
2012-06-27 18:10:53 +00:00
parent bb1432f2de
commit 8f8d7f586a
30 changed files with 1101 additions and 419 deletions

View File

@@ -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):

View File

@@ -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"

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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)

View File

@@ -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);

View File

@@ -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);

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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);

View File

@@ -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] )

View 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

View File

@@ -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

View File

@@ -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];
}

View File

@@ -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);
}
}
}

View File

@@ -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)
{

View File

@@ -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];
}

View File

@@ -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;

View File

@@ -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 */

View File

@@ -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

View File

@@ -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);

View File

@@ -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 */

View File

@@ -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}")

View File

@@ -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] )

View File

@@ -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)

View File

@@ -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;
}