Color proofing support with lcms (http://www.littlecms.com/).
authorMartin Poirier <theeth@yahoo.com>
Sun, 17 May 2009 16:19:13 +0000 (16:19 +0000)
committerMartin Poirier <theeth@yahoo.com>
Sun, 17 May 2009 16:19:13 +0000 (16:19 +0000)
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.

12 files changed:
source/blender/blenkernel/BKE_colortools.h
source/blender/blenkernel/SConscript
source/blender/blenkernel/intern/colortools.c
source/blender/editors/space_image/SConscript
source/blender/editors/space_image/image_draw.c
source/blender/editors/space_image/image_header.c
source/blender/imbuf/IMB_imbuf_types.h
source/blender/imbuf/intern/allocimbuf.c
source/blender/makesdna/DNA_space_types.h
source/blender/makesrna/intern/rna_space.c
tools/Blender.py
tools/btools.py

index 555b467b1d6ae44a91be12fd381803f117185461..6f6c4a834dfcdde78761485ce4731d816a7bd805 100644 (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
 
index 19d150b34a84315289c7957c73c5ecb7af5c5655..dbc990d06137ff52d3613dfd678b076876898f2d 100644 (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']
 
index 1bc34aea9a135896dab31ad276db682ba8a10372..e8716aba296fb3b47f51cfeacb68d57f27678336 100644 (file)
 #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)
 {
index 3ae638d344dd2ce0226028852ce91e0328909bfd..e7041ef045861b4d9562d9be00457b350a1b86f2 100644 (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] )
index b9407d263529df7e1cfba1b5e10f57df8923ea21..122e298baaa91f52d09a562e379212aab2b3d056 100644 (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);
index a584993005a10530a733a6cde9743ecec427eefb..7a28499009b00bdfd9347b05b197c77e90dda4c8 100644 (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 */
index 3cc155af1adec2b276d29098b6822e101e8398fb..79da0cb1c41106a6d01f2f1274c1a19495574186 100644 (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 */
index ad7b1dce2e09f3640d742050d921f5246032c50c..b561f0a583dda1703160f5c080b8e0bc75f4e1ec 100644 (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;
 }
 
index 0e19a6845dad7d7f83c426ba90302646f9087c0d..0d88e3eb6e8fd9f43b1951540236e51e389d7eb0 100644 (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)
index 229a260efce95479f7fac882235c7844d46bd95c..2b5c3a621b4c9936e4c4ea2ca97ff06adc9c95e0 100644 (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");
index 6ffc0b8d76d556df7f75b0c076fb1c9bff619b7e..ce5570ebd459bae2eeb537280274d566f6c7eb81 100644 (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']
 
index 2c9b564b8a1a453b8983fcb492f7b95e9617cd2f..bd646a2f3eb606776b1e9ec825547e5b89cf5856 100755 (executable)
@@ -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', ''),