Color proofing support with lcms (http://www.littlecms.com/).

Enable with WITH_LCMS (options have been added for scons).
lcms is very common on linux package managers, so no need to add in extern (IMHO). Libs for windows can be added to /lib

Code is mostly a proof of concept with hardcoded path for icc profile (taken from the lcms test suite).

Adding this now to svn so it doesn't rot on my hard drive. People interested in pushing it forward should feel free to dig in the code or poke me about it.
This commit is contained in:
Martin Poirier 2009-05-17 16:19:13 +00:00
parent 351086dbb8
commit 7eeb8ac01c
12 changed files with 87 additions and 4 deletions

View File

@ -58,6 +58,7 @@ void curvemapping_premultiply(struct CurveMapping *cumap, int restore);
int curvemapping_RGBA_does_something(struct CurveMapping *cumap);
void curvemapping_initialize(struct CurveMapping *cumap);
void curvemapping_table_RGBA(struct CurveMapping *cumap, float **array, int *size);
void colorcorrection_do_ibuf(struct ImBuf *ibuf, const char *profile);
#endif

View File

@ -55,6 +55,9 @@ if env['WITH_BF_BULLET']:
if env['BF_NO_ELBEEM']:
defs.append('DISABLE_ELBEEM')
if env['WITH_BF_LCMS']:
defs.append('WITH_LCMS')
if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc'):
incs += ' ' + env['BF_PTHREADS_INC']

View File

@ -32,6 +32,10 @@
#include <stdlib.h>
#include <float.h>
#ifdef WITH_LCMS
#include <lcms.h>
#endif
#include "MEM_guardedalloc.h"
#include "DNA_color_types.h"
@ -650,6 +654,38 @@ void curvemapping_evaluate_premulRGBF(CurveMapping *cumap, float *vecout, const
vecout[2]= curvemap_evaluateF(cumap->cm+2, fac);
}
void colorcorrection_do_ibuf(ImBuf *ibuf, const char *profile)
{
if (ibuf->crect == NULL)
{
#ifdef WITH_LCMS
cmsHPROFILE imageProfile, proofingProfile;
cmsHTRANSFORM hTransform;
ibuf->crect = MEM_mallocN(ibuf->x*ibuf->y*sizeof(int), "imbuf crect");
imageProfile = cmsCreate_sRGBProfile();
proofingProfile = cmsOpenProfileFromFile(profile, "r");
cmsErrorAction(LCMS_ERROR_SHOW);
hTransform = cmsCreateProofingTransform(imageProfile, TYPE_RGBA_8, imageProfile, TYPE_RGBA_8,
proofingProfile,
INTENT_ABSOLUTE_COLORIMETRIC,
INTENT_ABSOLUTE_COLORIMETRIC,
cmsFLAGS_SOFTPROOFING);
cmsDoTransform(hTransform, ibuf->rect, ibuf->crect, ibuf->x * ibuf->y);
cmsDeleteTransform(hTransform);
cmsCloseProfile(imageProfile);
cmsCloseProfile(proofingProfile);
#else
ibuf->crect = ibuf->rect;
#endif
}
}
void curvemapping_do_ibuf(CurveMapping *cumap, ImBuf *ibuf)
{

View File

@ -7,4 +7,9 @@ incs = '../include ../../blenlib ../../blenkernel ../../makesdna ../../imbuf'
incs += ' ../../windowmanager #/intern/guardedalloc #/extern/glew/include'
incs += ' ../../render/extern/include ../../makesrna'
env.BlenderLib ( 'bf_editors_space_image', sources, Split(incs), [], libtype=['core'], priority=[40] )
defs = []
if env['WITH_BF_LCMS']:
defs.append('WITH_LCMS')
env.BlenderLib ( 'bf_editors_space_image', sources, Split(incs), defs, libtype=['core'], priority=[40] )

View File

@ -117,10 +117,12 @@ static void image_verify_buffer_float(SpaceImage *sima, ImBuf *ibuf)
if(ibuf->rect_float) {
if(ibuf->rect==NULL) {
if(image_curves_active(sima))
if(image_curves_active(sima)) {
curvemapping_do_ibuf(sima->cumap, ibuf);
else
}
else {
IMB_rect_from_float(ibuf);
}
}
}
}
@ -309,6 +311,13 @@ static void sima_draw_alpha_pixelsf(float x1, float y1, int rectx, int recty, fl
// glColorMask(1, 1, 1, 1);
}
static void sima_draw_colorcorrected_pixels(float x1, float y1, ImBuf *ibuf)
{
colorcorrection_do_ibuf(ibuf, "MONOSCNR.ICM"); /* path is hardcoded here, find some place better */
glaDrawPixelsSafe(x1, y1, ibuf->x, ibuf->y, ibuf->x, GL_RGBA, GL_UNSIGNED_BYTE, ibuf->crect);
}
static void sima_draw_zbuf_pixels(float x1, float y1, int rectx, int recty, int *recti)
{
/* zbuffer values are signed, so we need to shift color range */
@ -386,6 +395,14 @@ static void draw_image_buffer(SpaceImage *sima, ARegion *ar, Scene *scene, ImBuf
else if(ibuf->channels==1)
sima_draw_zbuffloat_pixels(scene, x, y, ibuf->x, ibuf->y, ibuf->rect_float);
}
#ifdef WITH_LCMS
else if(sima->flag & SI_COLOR_CORRECTION) {
image_verify_buffer_float(sima, ibuf);
sima_draw_colorcorrected_pixels(x, y, ibuf);
}
#endif
else {
if(sima->flag & SI_USE_ALPHA) {
sima_draw_alpha_backdrop(x, y, ibuf->x, ibuf->y, zoomx, zoomy);

View File

@ -907,8 +907,12 @@ void image_header_buttons(const bContext *C, ARegion *ar)
xco+= XIC;
}
}
#ifdef WITH_LCMS
uiDefIconButR(block, ROW, B_REDR, ICON_IMAGE_ALPHA, xco,yco,XIC,YIC, &spaceptr, "draw_channels", 0, 0, SI_COLOR_CORRECTION, 0, 0, NULL);
xco+= XIC;
#endif
xco+= 8;
/* record & play */
uiBlockBeginAlign(block);
if(ima->type==IMA_TYPE_COMPOSITE) {
@ -921,6 +925,7 @@ void image_header_buttons(const bContext *C, ARegion *ar)
}
uiBlockEndAlign(block);
xco+= 8;
}
/* draw lock */

View File

@ -83,6 +83,7 @@ typedef struct ImBuf {
int ftype; /**< File type we are going to save as */
unsigned int *cmap; /**< Color map data. */
unsigned int *rect; /**< pixel values stored here */
unsigned int *crect; /**< color corrected pixel values stored here */
unsigned int **planes; /**< bitplanes */
int flags; /**< Controls which components should exist. */
int mall; /**< what is malloced internal, and can be freed */

View File

@ -93,6 +93,10 @@ void imb_freerectImBuf(struct ImBuf * ibuf)
{
if (ibuf==NULL) return;
if (ibuf->crect && ibuf->crect != ibuf->rect) {
MEM_freeN(ibuf->crect);
}
if (ibuf->rect) {
if (ibuf->mall & IB_rect) {
MEM_freeN(ibuf->rect);
@ -102,6 +106,7 @@ void imb_freerectImBuf(struct ImBuf * ibuf)
imb_freemipmapImBuf(ibuf);
ibuf->rect= NULL;
ibuf->crect= NULL;
ibuf->mall &= ~IB_rect;
}

View File

@ -577,6 +577,8 @@ typedef struct SpaceImaSel {
#define SI_DISPGP 1<<22
#define SI_DRAW_OTHER 1<<23
#define SI_COLOR_CORRECTION 1<<24
/* SpaceIpo->flag (Graph Editor Settings) */
#define SIPO_LOCK_VIEW (1<<0)
#define SIPO_NOTRANSKEYCULL (1<<1)

View File

@ -260,6 +260,7 @@ static void rna_def_space_image(BlenderRNA *brna)
{SI_USE_ALPHA, "COLOR_ALPHA", "Color and Alpha", "Draw image with RGB colors and alpha transparency."},
{SI_SHOW_ALPHA, "ALPHA", "Alpha", "Draw alpha transparency channel."},
{SI_SHOW_ZBUF, "Z_BUFFER", "Z-Buffer", "Draw Z-buffer associated with image (mapped from camera clip start to end)."},
{SI_COLOR_CORRECTION, "COLOR_CORRECTED", "Color Corrected", "Display color corrected image."},
{0, NULL, NULL, NULL}};
srna= RNA_def_struct(brna, "SpaceImageEditor", "Space");

View File

@ -188,6 +188,9 @@ def setup_syslibs(lenv):
syslibs += Split(lenv['BF_OPENGL_LIB'])
if lenv['OURPLATFORM'] in ('win32-vc', 'win32-mingw','linuxcross', 'win64-vc'):
syslibs += Split(lenv['BF_PTHREADS_LIB'])
if lenv['WITH_BF_LCMS']:
syslibs.append(lenv['BF_LCMS_LIB'])
syslibs += lenv['LLIBS']

View File

@ -61,6 +61,7 @@ def validate_arguments(args, bc):
'BF_FANCY', 'BF_QUIET',
'BF_X264_CONFIG',
'BF_XVIDCORE_CONFIG',
'WITH_BF_LCMS', 'BF_LCMS_LIB',
'WITH_BF_DOCS',
'BF_NUMJOBS',
]
@ -353,6 +354,9 @@ def read_opts(cfg, args):
(BoolVariable('BF_FANCY', 'Enable fancy output if true', True)),
(BoolVariable('BF_QUIET', 'Enable silent output if true', True)),
(BoolVariable('WITH_BF_BINRELOC', 'Enable relocatable binary (linux only)', False)),
(BoolVariable('WITH_BF_LCMS', 'Enable color correction with lcms', False)),
('BF_LCMS_LIB', 'LCMSlibrary', 'lcms'),
('BF_X264_CONFIG', 'configuration flags for x264', ''),
('BF_XVIDCORE_CONFIG', 'configuration flags for xvidcore', ''),