Color Management: image buffer loading reworked
authorSergey Sharybin <sergey.vfx@gmail.com>
Fri, 14 Sep 2012 14:36:47 +0000 (14:36 +0000)
committerSergey Sharybin <sergey.vfx@gmail.com>
Fri, 14 Sep 2012 14:36:47 +0000 (14:36 +0000)
Before this color space settings in image/movie clip data blocks
defined space in which loaded image buffer is, based on whether
this buffer contains float or byte buffer. This didn't work well
for formats like 16bit PNG, which are in fact non-linear formats
but were represented in Blender as float buffers.

Now image buffer loader is responsible to set up input default
color space for image/movie clip data blocks, which could be
based on format itself only or on particular file properties.

This means image/movie clip data blocks' input colorspace will
be initialized at time first image buffer is loaded.

This also resolves old confusing thing with image buffer's profile
flag, which in could have been non-linear for image buffer which
contained float buffer only -- this happened in mentioned case of
16 bit PNG format, i.e. Now float buffer would always be linear
which should make it easier to get rid of image buffer's profile.

40 files changed:
source/blender/blenkernel/BKE_image.h
source/blender/blenkernel/intern/image.c
source/blender/blenkernel/intern/movieclip.c
source/blender/blenkernel/intern/ocean.c
source/blender/blenkernel/intern/sequencer.c
source/blender/collada/ImageExporter.cpp
source/blender/editors/interface/interface_icons.c
source/blender/editors/render/render_preview.c
source/blender/editors/space_file/filelist.c
source/blender/editors/space_image/image_ops.c
source/blender/imbuf/IMB_colormanagement.h
source/blender/imbuf/IMB_imbuf.h
source/blender/imbuf/intern/IMB_anim.h
source/blender/imbuf/intern/IMB_colormanagement_intern.h
source/blender/imbuf/intern/IMB_filetype.h
source/blender/imbuf/intern/anim_movie.c
source/blender/imbuf/intern/bmp.c
source/blender/imbuf/intern/cineon/cineon_dpx.c
source/blender/imbuf/intern/colormanagement.c
source/blender/imbuf/intern/dds/dds_api.cpp
source/blender/imbuf/intern/dds/dds_api.h
source/blender/imbuf/intern/filetype.c
source/blender/imbuf/intern/indexer.c
source/blender/imbuf/intern/iris.c
source/blender/imbuf/intern/jp2.c
source/blender/imbuf/intern/jpeg.c
source/blender/imbuf/intern/openexr/openexr_api.cpp
source/blender/imbuf/intern/openexr/openexr_api.h
source/blender/imbuf/intern/png.c
source/blender/imbuf/intern/radiance_hdr.c
source/blender/imbuf/intern/readimage.c
source/blender/imbuf/intern/targa.c
source/blender/imbuf/intern/thumbs.c
source/blender/imbuf/intern/tiff.c
source/blender/imbuf/intern/writeimage.c
source/blender/makesrna/intern/rna_image_api.c
source/blender/makesrna/intern/rna_sequencer_api.c
source/blender/render/intern/source/pipeline.c
source/blender/windowmanager/intern/wm_operators.c
source/blender/windowmanager/intern/wm_playanim.c

index 4f1e48e..ac324b2 100644 (file)
@@ -46,6 +46,8 @@ struct Object;
 struct ImageFormatData;
 struct Main;
 
+#define IMA_MAX_SPACE       64
+
 /* call from library */
 void    BKE_image_free(struct Image *me);
 
@@ -73,7 +75,7 @@ char    BKE_imtype_from_arg(const char *arg);
 void    BKE_imformat_defaults(struct ImageFormatData *im_format);
 void    BKE_imbuf_to_image_format(struct ImageFormatData *im_format, const struct ImBuf *imbuf);
 
-struct anim *openanim(const char *name, int flags, int streamindex);
+struct anim *openanim(const char *name, int flags, int streamindex, char colorspace[IMA_MAX_SPACE]);
 
 void    BKE_image_de_interlace(struct Image *ima, int odd);
 
index 0949f54..ce3e99a 100644 (file)
@@ -304,12 +304,6 @@ static void image_assign_ibuf(Image *ima, ImBuf *ibuf, int index, int frame)
                else
                        ibuf->flags &= ~IB_cm_predivide;
 
-               if (ima->source == IMA_SRC_GENERATED) {
-                       /* for other image types spaces are set by image_initialize_after_load */
-
-                       IMB_colormanagement_imbuf_assign_spaces(ibuf, &ima->colorspace_settings);
-               }
-
                /* this function accepts (link == NULL) */
                BLI_insertlinkbefore(&ima->ibufs, link, ibuf);
 
@@ -1910,12 +1904,12 @@ void BKE_makepicstring(char *string, const char *base, const char *relbase, int
 }
 
 /* used by sequencer too */
-struct anim *openanim(const char *name, int flags, int streamindex)
+struct anim *openanim(const char *name, int flags, int streamindex, char colorspace[IMA_MAX_SPACE])
 {
        struct anim *anim;
        struct ImBuf *ibuf;
 
-       anim = IMB_open_anim(name, flags, streamindex);
+       anim = IMB_open_anim(name, flags, streamindex, colorspace);
        if (anim == NULL) return NULL;
 
        ibuf = IMB_anim_absolute(anim, 0, IMB_TC_NONE, IMB_PROXY_NONE);
@@ -2224,9 +2218,6 @@ static void image_create_multilayer(Image *ima, ImBuf *ibuf, int framenr)
 /* common stuff to do with images after loading */
 static void image_initialize_after_load(Image *ima, ImBuf *ibuf)
 {
-       /* make float buffer stored in ImBuf scene linear space */
-       IMB_colormanagement_imbuf_make_scene_linear(ibuf, &ima->colorspace_settings);
-
        /* preview is NULL when it has never been used as an icon before */
        if (G.background == 0 && ima->preview == NULL)
                BKE_icon_changed(BKE_icon_getid(&ima->id));
@@ -2261,7 +2252,7 @@ static ImBuf *image_load_sequence_file(Image *ima, ImageUser *iuser, int frame)
                flag |= IB_premul;
 
        /* read ibuf */
-       ibuf = IMB_loadiffname(name, flag);
+       ibuf = IMB_loadiffname(name, flag, ima->colorspace_settings.name);
 
 #if 0
        if (ibuf) {
@@ -2369,7 +2360,7 @@ static ImBuf *image_load_movie_file(Image *ima, ImageUser *iuser, int frame)
                BKE_image_user_file_path(iuser, ima, str);
 
                /* FIXME: make several stream accessible in image editor, too*/
-               ima->anim = openanim(str, IB_rect, 0);
+               ima->anim = openanim(str, IB_rect, 0, ima->colorspace_settings.name);
 
                /* let's initialize this user */
                if (ima->anim && iuser && iuser->frames == 0)
@@ -2420,8 +2411,8 @@ static ImBuf *image_load_image_file(Image *ima, ImageUser *iuser, int cfra)
                flag = IB_rect | IB_multilayer;
                if (ima->flag & IMA_DO_PREMUL) flag |= IB_premul;
 
-               ibuf = IMB_ibImageFromMemory((unsigned char *)ima->packedfile->data,
-                                            ima->packedfile->size, flag, "<packed data>");
+               ibuf = IMB_ibImageFromMemory((unsigned char *)ima->packedfile->data, ima->packedfile->size, flag,
+                                            ima->colorspace_settings.name, "<packed data>");
        }
        else {
                flag = IB_rect | IB_multilayer | IB_metadata;
@@ -2433,7 +2424,7 @@ static ImBuf *image_load_image_file(Image *ima, ImageUser *iuser, int cfra)
                BKE_image_user_file_path(iuser, ima, str);
 
                /* read ibuf */
-               ibuf = IMB_loadiffname(str, flag);
+               ibuf = IMB_loadiffname(str, flag, ima->colorspace_settings.name);
        }
 
        if (ibuf) {
index e83e697..cd8b0e4 100644 (file)
@@ -199,19 +199,25 @@ static ImBuf *movieclip_load_sequence_file(MovieClip *clip, MovieClipUser *user,
        struct ImBuf *ibuf;
        char name[FILE_MAX];
        int loadflag, use_proxy = FALSE;
+       char *colorspace;
 
        use_proxy = (flag & MCLIP_USE_PROXY) && user->render_size != MCLIP_PROXY_RENDER_SIZE_FULL;
        if (use_proxy) {
                int undistort = user->render_flag & MCLIP_PROXY_RENDER_UNDISTORT;
                get_proxy_fname(clip, user->render_size, undistort, framenr, name);
+
+               /* proxies were built using default color space settings */
+               colorspace = NULL;
        }
-       else
+       else {
                get_sequence_fname(clip, framenr, name);
+               colorspace = clip->colorspace_settings.name;
+       }
 
        loadflag = IB_rect | IB_multilayer;
 
        /* read ibuf */
-       ibuf = IMB_loadiffname(name, loadflag);
+       ibuf = IMB_loadiffname(name, loadflag, colorspace);
 
        return ibuf;
 }
@@ -225,7 +231,7 @@ static void movieclip_open_anim_file(MovieClip *clip)
                BLI_path_abs(str, ID_BLEND_PATH(G.main, &clip->id));
 
                /* FIXME: make several stream accessible in image editor, too */
-               clip->anim = openanim(str, IB_rect, 0);
+               clip->anim = openanim(str, IB_rect, 0, clip->colorspace_settings.name);
 
                if (clip->anim) {
                        if (clip->flag & MCLIP_USE_PROXY_CUSTOM_DIR) {
@@ -781,11 +787,6 @@ static ImBuf *movieclip_get_postprocessed_ibuf(MovieClip *clip, MovieClipUser *u
                        ibuf = movieclip_load_movie_file(clip, user, framenr, flag);
                }
 
-               if (ibuf) {
-                       /* make float buffer stored in ImBuf scene linear space */
-                       IMB_colormanagement_imbuf_make_scene_linear(ibuf, &clip->colorspace_settings);
-               }
-
                if (ibuf && (cache_flag & MOVIECLIP_CACHE_SKIP) == 0)
                        put_imbuf_cache(clip, user, ibuf, flag);
        }
index b862a82..46b89f7 100644 (file)
@@ -1117,19 +1117,20 @@ void BKE_simulate_ocean_cache(struct OceanCache *och, int frame)
        /* if image is already loaded in mem, return */
        if (och->ibufs_disp[f] != NULL) return;
 
+       /* use default color spaces since we know for sure cache files were saved with default settings too */
 
        cache_filename(string, och->bakepath, och->relbase, frame, CACHE_TYPE_DISPLACE);
-       och->ibufs_disp[f] = IMB_loadiffname(string, 0);
+       och->ibufs_disp[f] = IMB_loadiffname(string, 0, NULL);
        //if (och->ibufs_disp[f] == NULL) printf("error loading %s\n", string);
        //else printf("loaded cache %s\n", string);
 
        cache_filename(string, och->bakepath, och->relbase, frame, CACHE_TYPE_FOAM);
-       och->ibufs_foam[f] = IMB_loadiffname(string, 0);
+       och->ibufs_foam[f] = IMB_loadiffname(string, 0, NULL);
        //if (och->ibufs_foam[f] == NULL) printf("error loading %s\n", string);
        //else printf("loaded cache %s\n", string);
 
        cache_filename(string, och->bakepath, och->relbase, frame, CACHE_TYPE_NORMAL);
-       och->ibufs_norm[f] = IMB_loadiffname(string, 0);
+       och->ibufs_norm[f] = IMB_loadiffname(string, 0, NULL);
        //if (och->ibufs_norm[f] == NULL) printf("error loading %s\n", string);
        //else printf("loaded cache %s\n", string);
 }
index 0d8b220..1d4efb0 100644 (file)
@@ -686,7 +686,9 @@ void BKE_sequence_reload_new_file(Scene *scene, Sequence *seq, int lock_range)
                        BLI_path_abs(str, G.main->name);
 
                        if (seq->anim) IMB_free_anim(seq->anim);
-                       seq->anim = openanim(str, IB_rect | ((seq->flag & SEQ_FILTERY) ? IB_animdeinterlace : 0), seq->streamindex);
+
+                       /* OCIO_TODO: support configurable input space for strips */
+                       seq->anim = openanim(str, IB_rect | ((seq->flag & SEQ_FILTERY) ? IB_animdeinterlace : 0), seq->streamindex, NULL);
 
                        if (!seq->anim) {
                                return;
@@ -1183,7 +1185,8 @@ static void seq_open_anim_file(Sequence *seq)
                         seq->strip->dir, seq->strip->stripdata->name);
        BLI_path_abs(name, G.main->name);
        
-       seq->anim = openanim(name, IB_rect | ((seq->flag & SEQ_FILTERY) ? IB_animdeinterlace : 0), seq->streamindex);
+       /* OCIO_TODO: support configurable input space for strips */
+       seq->anim = openanim(name, IB_rect | ((seq->flag & SEQ_FILTERY) ? IB_animdeinterlace : 0), seq->streamindex, NULL);
 
        if (seq->anim == NULL) {
                return;
@@ -1289,8 +1292,9 @@ static ImBuf *seq_proxy_fetch(SeqRenderData context, Sequence *seq, int cfra)
                        if (seq_proxy_get_fname(seq, cfra, render_size, name) == 0) {
                                return NULL;
                        }
-                       seq->strip->proxy->anim = openanim(name, IB_rect, 0);
+
+                       /* proxies are generated in default color space */
+                       seq->strip->proxy->anim = openanim(name, IB_rect, 0, NULL);
                }
                if (seq->strip->proxy->anim == NULL) {
                        return NULL;
@@ -1308,7 +1312,8 @@ static ImBuf *seq_proxy_fetch(SeqRenderData context, Sequence *seq, int cfra)
        }
 
        if (BLI_exists(name)) {
-               ImBuf *ibuf = IMB_loadiffname(name, IB_rect);
+               /* OCIO_TODO: support configurable spaces for strips */
+               ImBuf *ibuf = IMB_loadiffname(name, IB_rect, NULL);
 
                if (ibuf)
                        BKE_sequencer_imbuf_assign_spaces(context.scene, ibuf);
@@ -1351,7 +1356,8 @@ static void seq_proxy_build_frame(SeqRenderData context, Sequence *seq, int cfra
                ibuf->planes = 24;
 
        BLI_make_existing_file(name);
-       
+
+       /* OCIO_TODO: support per-strip color space settings */
        ok = IMB_saveiff(ibuf, name, IB_rect | IB_zbuf | IB_zbuffloat);
        if (ok == 0) {
                perror(name);
@@ -2536,7 +2542,8 @@ static ImBuf *do_render_strip_uncached(SeqRenderData context, Sequence *seq, flo
                                BLI_path_abs(name, G.main->name);
                        }
 
-                       if (s_elem && (ibuf = IMB_loadiffname(name, IB_rect))) {
+                       /* OCIO_TODO: support configurable space for image strips */
+                       if (s_elem && (ibuf = IMB_loadiffname(name, IB_rect, NULL))) {
                                /* we don't need both (speed reasons)! */
                                if (ibuf->rect_float && ibuf->rect)
                                        imb_freerectImBuf(ibuf);
@@ -4046,7 +4053,8 @@ Sequence *BKE_sequencer_add_movie_strip(bContext *C, ListBase *seqbasep, SeqLoad
        BLI_strncpy(path, seq_load->path, sizeof(path));
        BLI_path_abs(path, G.main->name);
 
-       an = openanim(path, IB_rect, 0);
+       /* OCIO_TODO: support configurable input space for strips */
+       an = openanim(path, IB_rect, 0, NULL);
 
        if (an == NULL)
                return NULL;
index 1af34bf..41d3c79 100644 (file)
@@ -102,7 +102,7 @@ void ImagesExporter::export_UV_Image(Image *image, bool use_copies)
                        // So we have to export it. The export will keep the image state intact,
                        // so the exported file will not be associated with the image.
 
-                       if (BKE_imbuf_write_as(imbuf, export_path, &imageFormat, true) == 0) {
+                       if (BKE_imbuf_write_as(imbuf, export_path, &imageFormat, image->colorspace_settings.name, true) == 0) {
                                fprintf(stderr, "Collada export: Cannot export image to:\n%s\n", export_path);
                                return;
                        }
index f6f12f9..0921107 100644 (file)
@@ -466,7 +466,7 @@ static void init_brush_icons(void)
        {                                                                         \
                bbuf = IMB_ibImageFromMemory((unsigned char *)datatoc_ ##name## _png, \
                                             datatoc_ ##name## _png_size,             \
-                                            IB_rect, "<brush icon>");                \
+                                            IB_rect, NULL, "<brush icon>");          \
                def_internal_icon(bbuf, icon_id, 0, 0, w, ICON_TYPE_BUFFER);          \
                IMB_freeImBuf(bbuf);                                                  \
        } (void)0
@@ -520,7 +520,7 @@ static void init_internal_icons(void)
                char *icondir = BLI_get_folder(BLENDER_DATAFILES, "icons");
                if (icondir) {
                        BLI_join_dirfile(iconfilestr, sizeof(iconfilestr), icondir, btheme->tui.iconfile);
-                       bbuf = IMB_loadiffname(iconfilestr, IB_rect); /* if the image is missing bbuf will just be NULL */
+                       bbuf = IMB_loadiffname(iconfilestr, IB_rect, NULL); /* if the image is missing bbuf will just be NULL */
                        if (bbuf && (bbuf->x < ICON_IMAGE_W || bbuf->y < ICON_IMAGE_H)) {
                                printf("\n***WARNING***\nIcons file %s too small.\nUsing built-in Icons instead\n", iconfilestr);
                                IMB_freeImBuf(bbuf);
@@ -533,7 +533,7 @@ static void init_internal_icons(void)
        }
        if (bbuf == NULL)
                bbuf = IMB_ibImageFromMemory((unsigned char *)datatoc_blender_icons_png,
-                                            datatoc_blender_icons_png_size, IB_rect, "<blender icons>");
+                                            datatoc_blender_icons_png_size, IB_rect, NULL, "<blender icons>");
 
        if (bbuf) {
                /* free existing texture if any */
index 38117aa..4b8411e 100644 (file)
@@ -118,7 +118,8 @@ ImBuf *get_brush_icon(Brush *brush)
                                BLI_strncpy(path, brush->icon_filepath, sizeof(brush->icon_filepath));
                                BLI_path_abs(path, G.main->name);
 
-                               brush->icon_imbuf = IMB_loadiffname(path, flags);
+                               /* use default colorspaces for brushes */
+                               brush->icon_imbuf = IMB_loadiffname(path, flags, NULL);
 
                                // otherwise lets try to find it in other directories
                                if (!(brush->icon_imbuf)) {
@@ -126,8 +127,10 @@ ImBuf *get_brush_icon(Brush *brush)
 
                                        BLI_make_file_string(G.main->name, path, folder, brush->icon_filepath);
 
-                                       if (path[0])
-                                               brush->icon_imbuf = IMB_loadiffname(path, flags);
+                                       if (path[0]) {
+                                               /* use fefault color spaces */
+                                               brush->icon_imbuf = IMB_loadiffname(path, flags, NULL);
+                                       }
                                }
 
                                if (brush->icon_imbuf)
index 337e13f..d3b4df0 100644 (file)
@@ -389,7 +389,7 @@ void filelist_init_icons(void)
 #ifdef WITH_HEADLESS
        bbuf = NULL;
 #else
-       bbuf = IMB_ibImageFromMemory((unsigned char *)datatoc_prvicons_png, datatoc_prvicons_png_size, IB_rect, "<splash>");
+       bbuf = IMB_ibImageFromMemory((unsigned char *)datatoc_prvicons_png, datatoc_prvicons_png_size, IB_rect, NULL, "<splash>");
 #endif
        if (bbuf) {
                for (y = 0; y < SPECIAL_IMG_ROWS; y++) {
index 857d017..563680f 100644 (file)
@@ -1212,15 +1212,12 @@ static ImBuf *save_image_colormanaged_imbuf_acquire(ImBuf *ibuf, SaveImageOption
        int do_colormanagement;
 
        *cache_handle = NULL;
-       do_colormanagement = !BKE_imtype_supports_float(imf->imtype);
+       do_colormanagement = save_as_render && !BKE_imtype_supports_float(imf->imtype);
 
        if (do_colormanagement) {
                unsigned char *display_buffer;
 
-               if (save_as_render)
-                       display_buffer = IMB_display_buffer_acquire(ibuf, &imf->view_settings, &imf->display_settings, cache_handle);
-               else
-                       display_buffer = IMB_display_buffer_acquire(ibuf, NULL, &imf->display_settings, cache_handle);
+               display_buffer = IMB_display_buffer_acquire(ibuf, &imf->view_settings, &imf->display_settings, cache_handle);
 
                if (*cache_handle) {
                        colormanaged_ibuf = IMB_allocImBuf(ibuf->x, ibuf->y, ibuf->planes, 0);
@@ -1295,7 +1292,8 @@ static void save_image_doit(bContext *C, SpaceImage *sima, wmOperator *op, SaveI
                        BKE_image_release_renderresult(scene, ima);
                }
                else {
-                       if (BKE_imbuf_write_as(colormanaged_ibuf, simopts->filepath, &simopts->im_format, save_copy)) {
+                       if (BKE_imbuf_write_as(colormanaged_ibuf, simopts->filepath, &simopts->im_format, save_copy))
+                       {
                                ok = TRUE;
                        }
                }
@@ -1334,6 +1332,8 @@ static void save_image_doit(bContext *C, SpaceImage *sima, wmOperator *op, SaveI
                                if (relative) {
                                        BLI_path_rel(ima->name, relbase); /* only after saving */
                                }
+
+                               IMB_colormanagment_colorspace_from_ibuf_ftype(&ima->colorspace_settings, ibuf);
                        }
                }
                else {
index 0dc8264..cd88371 100644 (file)
@@ -88,17 +88,15 @@ void IMB_colormanagement_pixel_to_display_space_v3(float result[3], const float
 void IMB_colormanagement_pixel_to_role_v4(float pixel[4], int role);
 void IMB_colormanagement_pixel_from_role_v4(float pixel[4], int role);
 
-void IMB_colormanagement_imbuf_to_role(struct ImBuf *ibuf, int role);
-void IMB_colormanagement_imbuf_from_role(struct ImBuf *ibuf, int role);
-
 void IMB_colormanagement_imbuf_assign_spaces(struct ImBuf *ibuf, struct ColorManagedColorspaceSettings *colorspace_settings);
+void IMB_colormanagement_imbuf_assign_default_spaces(struct ImBuf *ibuf);
 void IMB_colormanagement_imbuf_assign_float_space(struct ImBuf *ibuf, struct ColorManagedColorspaceSettings *colorspace_settings);
 
-void IMB_colormanagement_imbuf_make_scene_linear(struct ImBuf *ibuf, struct ColorManagedColorspaceSettings *colorspace_settings);
-
 void IMB_colormanagement_imbuf_make_display_space(struct ImBuf *ibuf, const struct ColorManagedViewSettings *view_settings,
                                                   const struct ColorManagedDisplaySettings *display_settings);
 
+void IMB_colormanagement_imbuf_make_colorspace(struct ImBuf *ibuf, const char *to_colorspace, int flag);
+
 /* ** Public display buffers interfaces ** */
 
 unsigned char *IMB_display_buffer_acquire(struct ImBuf *ibuf, const struct ColorManagedViewSettings *view_settings,
@@ -129,6 +127,8 @@ int IMB_colormanagement_colorspace_get_named_index(const char *name);
 const char *IMB_colormanagement_colorspace_get_indexed_name(int index);
 const char *IMB_colormanagement_view_get_default_name(const char *display_name);
 
+void IMB_colormanagment_colorspace_from_ibuf_ftype(struct ColorManagedColorspaceSettings *colorspace_settings, struct ImBuf *ibuf);
+
 /* ** 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);
index 71c8f19..a8780d3 100644 (file)
@@ -70,6 +70,8 @@
 #ifndef __IMB_IMBUF_H__
 #define __IMB_IMBUF_H__
 
+#define IM_MAX_SPACE 64
+
 /**
  *
  * \attention defined in ???
@@ -95,20 +97,19 @@ void IMB_exit(void);
  *
  * \attention Defined in readimage.c
  */
-struct ImBuf *IMB_ibImageFromMemory(unsigned char *mem, size_t size,
-                                    int flags, const char *descr);
+struct ImBuf *IMB_ibImageFromMemory(unsigned char *mem, size_t size, int flags, char colorspace[IM_MAX_SPACE], const char *descr);
 
 /**
  *
  * \attention Defined in readimage.c
  */
-struct ImBuf *IMB_testiffname(const char *filepath, int flags);
+struct ImBuf *IMB_testiffname(const char *filepath, int flags, char colorspace[IM_MAX_SPACE]);
 
 /**
  *
  * \attention Defined in readimage.c
  */
-struct ImBuf *IMB_loadiffname(const char *filepath, int flags);
+struct ImBuf *IMB_loadiffname(const char *filepath, int flags, char colorspace[IM_MAX_SPACE]);
 
 /**
  *
@@ -247,7 +248,7 @@ int IMB_anim_get_fps(struct anim * anim,
  *
  * \attention Defined in anim_movie.c
  */
-struct anim *IMB_open_anim(const char *name, int ib_flags, int streamindex);
+struct anim *IMB_open_anim(const char *name, int ib_flags, int streamindex, char colorspace[IM_MAX_SPACE]);
 void IMB_close_anim(struct anim *anim);
 void IMB_close_anim_proxies(struct anim *anim);
 
@@ -419,7 +420,7 @@ void bilinear_interpolation_color_wrap(struct ImBuf *in, unsigned char *col, flo
  *
  * \attention defined in readimage.c
  */  
-struct ImBuf *IMB_loadifffile(int file, int flags, const char *descr);
+struct ImBuf *IMB_loadifffile(int file, int flags, char colorspace[IM_MAX_SPACE], const char *descr);
 
 /**
  *
index 571c54b..d5cc492 100644 (file)
@@ -191,6 +191,7 @@ struct anim {
        struct anim *proxy_anim[IMB_PROXY_MAX_SLOT];
        struct anim_index *curr_idx[IMB_TC_MAX_SLOT];
 
+       char colorspace[64];
 };
 
 #endif
index 293314c..67c99d5 100644 (file)
@@ -36,6 +36,7 @@
 #define BCM_CONFIG_FILE "config.ocio"
 
 struct ConstProcessorRcPtr;
+struct ImBuf;
 
 typedef struct ColorSpace {
        struct ColorSpace *next, *prev;
@@ -80,6 +81,11 @@ struct ColorManagedView *colormanage_view_get_named(const char *name);
 
 struct ColorSpace *colormanage_colorspace_add(const char *name, const char *description, int is_invertible);
 struct ColorSpace *colormanage_colorspace_get_named(const char *name);
+struct ColorSpace *colormanage_colorspace_get_roled(int role);
 struct ColorSpace *colormanage_colorspace_get_indexed(int index);
 
+void colorspace_set_default_role(char *colorspace, int size, int role);
+
+void colormanage_imbuf_make_linear(struct ImBuf *ibuf, const char *from_colorspace);
+
 #endif  /* IMB_COLORMANAGEMENT_INTERN_H */
index 74d0a92..56a0312 100644 (file)
@@ -40,12 +40,13 @@ typedef struct ImFileType {
 
        int (*is_a)(unsigned char *buf);
        int (*ftype)(struct ImFileType *type, struct ImBuf *ibuf);
-       struct ImBuf *(*load)(unsigned char *mem, size_t size, int flags);
+       struct ImBuf *(*load)(unsigned char *mem, size_t size, int flags, char colorspace[IM_MAX_SPACE]);
        int (*save)(struct ImBuf *ibuf, const char *name, int flags);
        void (*load_tile)(struct ImBuf *ibuf, unsigned char *mem, size_t size, int tx, int ty, unsigned int *rect);
 
        int flag;
        int filetype;
+       int default_save_role;
 } ImFileType;
 
 extern ImFileType IMB_FILE_TYPES[];
@@ -63,57 +64,57 @@ void imb_tile_cache_tile_free(struct ImBuf *ibuf, int tx, int ty);
 
 /* png */
 int imb_is_a_png(unsigned char *buf);
-struct ImBuf *imb_loadpng(unsigned char *mem, size_t size, int flags);
+struct ImBuf *imb_loadpng(unsigned char *mem, size_t size, int flags, char colorspace[IM_MAX_SPACE]);
 int imb_savepng(struct ImBuf *ibuf, const char *name, int flags);
 
 /* targa */
 int imb_is_a_targa(unsigned char *buf);
-struct ImBuf *imb_loadtarga(unsigned char *mem, size_t size, int flags);
+struct ImBuf *imb_loadtarga(unsigned char *mem, size_t size, int flags, char colorspace[IM_MAX_SPACE]);
 int imb_savetarga(struct ImBuf * ibuf, const char *name, int flags);
 
 /* iris */
 int imb_is_a_iris(unsigned char *mem);
-struct ImBuf *imb_loadiris(unsigned char *mem, size_t size, int flags);
+struct ImBuf *imb_loadiris(unsigned char *mem, size_t size, int flags, char colorspace[IM_MAX_SPACE]);
 int imb_saveiris(struct ImBuf * ibuf, const char *name, int flags);
 
 /* jp2 */
 int imb_is_a_jp2(unsigned char *buf);
-struct ImBuf *imb_jp2_decode(unsigned char *mem, size_t size, int flags);
+struct ImBuf *imb_jp2_decode(unsigned char *mem, size_t size, int flags, char colorspace[IM_MAX_SPACE]);
 int imb_savejp2(struct ImBuf *ibuf, const char *name, int flags);
 
 /* jpeg */
 int imb_is_a_jpeg(unsigned char *mem);
 int imb_savejpeg(struct ImBuf *ibuf, const char *name, int flags);
-struct ImBuf * imb_load_jpeg (unsigned char * buffer, size_t size, int flags);
+struct ImBuf * imb_load_jpeg (unsigned char * buffer, size_t size, int flags, char colorspace[IM_MAX_SPACE]);
 
 /* bmp */
 int imb_is_a_bmp(unsigned char *buf);
-struct ImBuf *imb_bmp_decode(unsigned char *mem, size_t size, int flags);
+struct ImBuf *imb_bmp_decode(unsigned char *mem, size_t size, int flags, char colorspace[IM_MAX_SPACE]);
 int imb_savebmp(struct ImBuf *ibuf, const char *name, int flags);
 
 /* cocoa */
-struct ImBuf *imb_cocoaLoadImage(unsigned char *mem, size_t size, int flags);
+struct ImBuf *imb_cocoaLoadImage(unsigned char *mem, size_t size, int flags, char colorspace[IM_MAX_SPACE]);
 short imb_cocoaSaveImage(struct ImBuf *ibuf, const char *name, int flags);
 
 /* cineon */
 int imb_savecineon(struct ImBuf *buf, const char *name, int flags);
-struct ImBuf *imb_loadcineon(unsigned char *mem, size_t size, int flags);
+struct ImBuf *imb_loadcineon(unsigned char *mem, size_t size, int flags, char colorspace[IM_MAX_SPACE]);
 int imb_is_cineon(unsigned char *buf);
 
 /* dpx */
 int imb_save_dpx(struct ImBuf *buf, const char *name, int flags);
-struct ImBuf *imb_loaddpx(unsigned char *mem, size_t size, int flags);
+struct ImBuf *imb_loaddpx(unsigned char *mem, size_t size, int flags, char colorspace[IM_MAX_SPACE]);
 int imb_is_dpx(unsigned char *buf);
 
 /* hdr */
 int imb_is_a_hdr(unsigned char *buf);
-struct ImBuf *imb_loadhdr(unsigned char *mem, size_t size, int flags);
+struct ImBuf *imb_loadhdr(unsigned char *mem, size_t size, int flags, char colorspace[IM_MAX_SPACE]);
 int imb_savehdr(struct ImBuf * ibuf, const char *name, int flags);
 
 /* tiff */
 void imb_inittiff(void);
 int imb_is_a_tiff(unsigned char *buf);
-struct ImBuf *imb_loadtiff(unsigned char *mem, size_t size, int flags);
+struct ImBuf *imb_loadtiff(unsigned char *mem, size_t size, int flags, char colorspace[IM_MAX_SPACE]);
 void imb_loadtiletiff(struct ImBuf *ibuf, unsigned char *mem, size_t size,
        int tx, int ty, unsigned int *rect);
 int imb_savetiff(struct ImBuf *ibuf, const char *name, int flags);
index 16dbd08..fa8cc6c 100644 (file)
 #endif
 #endif
 
+#include "IMB_colormanagement.h"
+#include "IMB_colormanagement_intern.h"
+
 int ismovie(const char *UNUSED(filepath))
 {
        return 0;
@@ -263,12 +266,20 @@ void IMB_close_anim_proxies(struct anim *anim)
        IMB_free_indices(anim);
 }
 
-struct anim *IMB_open_anim(const char *name, int ib_flags, int streamindex)
+struct anim *IMB_open_anim(const char *name, int ib_flags, int streamindex, char colorspace[IM_MAX_SPACE])
 {
        struct anim *anim;
 
        anim = (struct anim *)MEM_callocN(sizeof(struct anim), "anim struct");
        if (anim != NULL) {
+               if (colorspace) {
+                       colorspace_set_default_role(colorspace, IM_MAX_SPACE, COLOR_ROLE_DEFAULT_BYTE);
+                       BLI_strncpy(anim->colorspace, colorspace, sizeof(anim->colorspace));
+               }
+               else {
+                       colorspace_set_default_role(anim->colorspace, sizeof(anim->colorspace), COLOR_ROLE_DEFAULT_BYTE);
+               }
+
                BLI_strncpy(anim->name, name, sizeof(anim->name));
                anim->ib_flags = ib_flags;
                anim->streamindex = streamindex;
@@ -404,7 +415,7 @@ static ImBuf *avi_fetchibuf(struct anim *anim, int position)
                if (anim->pgf) {
                        lpbi = AVIStreamGetFrame(anim->pgf, position + AVIStreamStart(anim->pavi[anim->firstvideo]));
                        if (lpbi) {
-                               ibuf = IMB_ibImageFromMemory((unsigned char *) lpbi, 100, IB_rect, "<avi_fetchibuf>");
+                               ibuf = IMB_ibImageFromMemory((unsigned char *) lpbi, 100, IB_rect, anim->colorspace, "<avi_fetchibuf>");
 //Oh brother...
                        }
                }
@@ -433,7 +444,8 @@ static ImBuf *avi_fetchibuf(struct anim *anim, int position)
        }
        
        ibuf->profile = IB_PROFILE_SRGB;
-       
+       ibuf->rect_colorspace = colormanage_colorspace_get_named(anim->colorspace);
+
        return ibuf;
 }
 
@@ -1090,6 +1102,7 @@ static ImBuf *ffmpeg_fetchibuf(struct anim *anim, int position,
 
        IMB_freeImBuf(anim->last_frame);
        anim->last_frame = IMB_allocImBuf(anim->x, anim->y, 32, IB_rect);
+       anim->last_frame->rect_colorspace = colormanage_colorspace_get_named(anim->colorspace);
 
        ffmpeg_postprocess(anim);
 
@@ -1213,7 +1226,7 @@ static ImBuf *anim_getnew(struct anim *anim)
 
        switch (anim->curtype) {
                case ANIM_SEQUENCE:
-                       ibuf = IMB_loadiffname(anim->name, anim->ib_flags);
+                       ibuf = IMB_loadiffname(anim->name, anim->ib_flags, anim->colorspace);
                        if (ibuf) {
                                BLI_strncpy(anim->first, anim->name, sizeof(anim->first));
                                anim->duration = 1;
@@ -1309,7 +1322,7 @@ struct ImBuf *IMB_anim_absolute(struct anim *anim, int position,
                        pic = an_stringdec(anim->first, head, tail, &digits);
                        pic += position;
                        an_stringenc(anim->name, head, tail, digits, pic);
-                       ibuf = IMB_loadiffname(anim->name, IB_rect);
+                       ibuf = IMB_loadiffname(anim->name, IB_rect, anim->colorspace);
                        if (ibuf) {
                                anim->curposition = position;
                        }
@@ -1330,8 +1343,16 @@ struct ImBuf *IMB_anim_absolute(struct anim *anim, int position,
 #ifdef WITH_QUICKTIME
                case ANIM_QTIME:
                        ibuf = qtime_fetchibuf(anim, position);
-                       if (ibuf)
+                       if (ibuf) {
+                               if (ibuf->rect) {
+                                       /* OCIO_TODO: should happen in quicktime module, but it currently doesn't have access
+                                        *            to color management's internals
+                                        */
+                                       ibuf->rect_colorspace = colormanage_colorspace_get_named(anim->colorspace);
+                               }
+
                                anim->curposition = position;
+                       }
                        break;
 #endif
 #ifdef WITH_FFMPEG
index 8fa4689..5e7b1b8 100644 (file)
@@ -38,6 +38,9 @@
 #include "IMB_allocimbuf.h"
 #include "IMB_filetype.h"
 
+#include "IMB_colormanagement.h"
+#include "IMB_colormanagement_intern.h"
+
 /* some code copied from article on microsoft.com, copied
  * here for enhanced BMP support in the future
  * http://www.microsoft.com/msj/defaultframe.asp?page=/msj/0197/mfcp1/mfcp1.htm&nav=/msj/0197/newnav.htm
@@ -115,7 +118,7 @@ int imb_is_a_bmp(unsigned char *buf)
        return checkbmp(buf);
 }
 
-struct ImBuf *imb_bmp_decode(unsigned char *mem, size_t size, int flags)
+struct ImBuf *imb_bmp_decode(unsigned char *mem, size_t size, int flags, char colorspace[IM_MAX_SPACE])
 {
        struct ImBuf *ibuf = NULL;
        BMPINFOHEADER bmi;
@@ -127,6 +130,8 @@ struct ImBuf *imb_bmp_decode(unsigned char *mem, size_t size, int flags)
 
        if (checkbmp(mem) == 0) return(NULL);
 
+       colorspace_set_default_role(colorspace, IM_MAX_SPACE, COLOR_ROLE_DEFAULT_BYTE);
+
        if ((mem[0] == 'B') && (mem[1] == 'M')) {
                /* skip fileheader */
                mem += BMP_FILEHEADER_SIZE;
index 182e0a7..7705af1 100644 (file)
@@ -44,6 +44,9 @@
 #include "IMB_imbuf.h"
 #include "IMB_filetype.h"
 
+#include "IMB_colormanagement.h"
+#include "IMB_colormanagement_intern.h"
+
 #include "BKE_global.h"
 
 #include "MEM_guardedalloc.h"
@@ -63,7 +66,7 @@ static void cineon_conversion_parameters(LogImageByteConversionParameters *param
 }
 #endif
 
-static ImBuf *imb_load_dpx_cineon(unsigned char *mem, int use_cineon, int size, int flags)
+static ImBuf *imb_load_dpx_cineon(unsigned char *mem, int use_cineon, int size, int flags, char colorspace[IM_MAX_SPACE])
 {
        ImBuf *ibuf;
        LogImageFile *image;
@@ -72,6 +75,8 @@ static ImBuf *imb_load_dpx_cineon(unsigned char *mem, int use_cineon, int size,
        int width, height, depth;
        float *frow;
 
+       colorspace_set_default_role(colorspace, IM_MAX_SPACE, COLOR_ROLE_DEFAULT_FLOAT);
+
        logImageSetVerbose((G.debug & G_DEBUG) ? 1:0);
        
        image = logImageOpenFromMem(mem, size, use_cineon);
@@ -202,10 +207,10 @@ int imb_is_cineon(unsigned char *buf)
        return cineonIsMemFileCineon(buf);
 }
 
-ImBuf *imb_loadcineon(unsigned char *mem, size_t size, int flags)
+ImBuf *imb_loadcineon(unsigned char *mem, size_t size, int flags, char colorspace[IM_MAX_SPACE])
 {
        if (imb_is_cineon(mem))
-               return imb_load_dpx_cineon(mem, 1, size, flags);
+               return imb_load_dpx_cineon(mem, 1, size, flags, colorspace);
        return NULL;
 }
 
@@ -219,9 +224,9 @@ int imb_is_dpx(unsigned char *buf)
        return dpxIsMemFileCineon(buf);
 }
 
-ImBuf *imb_loaddpx(unsigned char *mem, size_t size, int flags)
+ImBuf *imb_loaddpx(unsigned char *mem, size_t size, int flags, char colorspace[IM_MAX_SPACE])
 {
        if (imb_is_dpx(mem))
-               return imb_load_dpx_cineon(mem, 0, size, flags);
+               return imb_load_dpx_cineon(mem, 0, size, flags, colorspace);
        return NULL;
 }
index b88ff3c..292c791 100644 (file)
@@ -45,6 +45,7 @@
 #include "IMB_filter.h"
 #include "IMB_imbuf.h"
 #include "IMB_imbuf_types.h"
+#include "IMB_filetype.h"
 #include "IMB_moviecache.h"
 
 #include "MEM_guardedalloc.h"
@@ -845,6 +846,38 @@ static void curve_mapping_apply_pixel(CurveMapping *curve_mapping, float *pixel,
        }
 }
 
+void colorspace_set_default_role(char *colorspace, int size, int role)
+{
+       if (colorspace && colorspace[0] == '\0') {
+               const char *role_colorspace;
+
+               role_colorspace = IMB_colormanagement_role_colorspace_name_get(role);
+
+               BLI_strncpy(colorspace, role_colorspace, size);
+       }
+}
+
+void colormanage_imbuf_make_linear(ImBuf *ibuf, const char *from_colorspace)
+{
+#ifdef WITH_OCIO
+       if (ibuf->rect_float) {
+               const char *to_colorspace = global_role_scene_linear;
+               int predivide = ibuf->flags & IB_cm_predivide;
+
+               if (ibuf->rect)
+                       imb_freerectImBuf(ibuf);
+
+               IMB_colormanagement_transform(ibuf->rect_float, ibuf->x, ibuf->y, ibuf->channels,
+                                             from_colorspace, to_colorspace, predivide);
+
+               ibuf->profile = IB_PROFILE_LINEAR_RGB;
+       }
+#else
+       (void) ibuf;
+       (void) role;
+#endif
+}
+
 /*********************** Generic functions *************************/
 
 #ifdef WITH_OCIO
@@ -1580,46 +1613,6 @@ void IMB_colormanagement_pixel_to_display_space_v3(float result[3], const float
        IMB_colormanagement_processor_free(cm_processor);
 }
 
-void IMB_colormanagement_imbuf_to_role(ImBuf *ibuf, int role)
-{
-#ifdef WITH_OCIO
-       if (ibuf->rect_float) {
-               const char *from_colorspace = global_role_scene_linear;
-               const char *to_colorspace = IMB_colormanagement_role_colorspace_name_get(role);
-               int predivide = ibuf->flags & IB_cm_predivide;
-
-               if (ibuf->rect)
-                       imb_freerectImBuf(ibuf);
-
-               IMB_colormanagement_transform_threaded(ibuf->rect_float, ibuf->x, ibuf->y, ibuf->channels,
-                                                      from_colorspace, to_colorspace, predivide);
-       }
-#else
-       (void) ibuf;
-       (void) role;
-#endif
-}
-
-void IMB_colormanagement_imbuf_from_role(ImBuf *ibuf, int role)
-{
-#ifdef WITH_OCIO
-       if (ibuf->rect_float) {
-               const char *from_colorspace = IMB_colormanagement_role_colorspace_name_get(role);
-               const char *to_colorspace = global_role_scene_linear;
-               int predivide = ibuf->flags & IB_cm_predivide;
-
-               if (ibuf->rect)
-                       imb_freerectImBuf(ibuf);
-
-               IMB_colormanagement_transform_threaded(ibuf->rect_float, ibuf->x, ibuf->y, ibuf->channels,
-                                                      from_colorspace, to_colorspace, predivide);
-       }
-#else
-       (void) ibuf;
-       (void) role;
-#endif
-}
-
 void IMB_colormanagement_pixel_to_role_v4(float pixel[4], int role)
 {
 #ifdef WITH_OCIO
@@ -1687,32 +1680,14 @@ void IMB_colormanagement_imbuf_assign_spaces(ImBuf *ibuf, ColorManagedColorspace
 #endif
 }
 
-void IMB_colormanagement_imbuf_assign_float_space(ImBuf *ibuf, ColorManagedColorspaceSettings *colorspace_settings)
+void IMB_colormanagement_imbuf_assign_default_spaces(ImBuf *ibuf)
 {
-       ibuf->float_colorspace = colormanage_colorspace_get_named(colorspace_settings->name);
+       IMB_colormanagement_imbuf_assign_spaces(ibuf, NULL);
 }
 
-void IMB_colormanagement_imbuf_make_scene_linear(ImBuf *ibuf, ColorManagedColorspaceSettings *colorspace_settings)
+void IMB_colormanagement_imbuf_assign_float_space(ImBuf *ibuf, ColorManagedColorspaceSettings *colorspace_settings)
 {
-#ifdef WITH_OCIO
-       /* for byte buffers only store it's color space, no affect on buffer itself
-        * that's because of precision issues of bytes
-        */
-       IMB_colormanagement_imbuf_assign_spaces(ibuf, colorspace_settings);
-
-       /* convert float buffer to scene linear space */
-       if (ibuf->rect_float) {
-               const char *from_colorspace = colorspace_settings->name;
-               const char *to_colorspace = global_role_scene_linear;
-               int predivide = ibuf->flags & IB_cm_predivide;
-
-               IMB_colormanagement_transform_threaded(ibuf->rect_float, ibuf->x, ibuf->y, ibuf->channels,
-                                                        from_colorspace, to_colorspace, predivide);
-       }
-#else
-       (void) ibuf;
-       (void) colorspace_settings;
-#endif
+       ibuf->float_colorspace = colormanage_colorspace_get_named(colorspace_settings->name);
 }
 
 void IMB_colormanagement_imbuf_make_display_space(ImBuf *ibuf, const ColorManagedViewSettings *view_settings,
@@ -1739,6 +1714,16 @@ void IMB_colormanagement_imbuf_make_display_space(ImBuf *ibuf, const ColorManage
 #endif
 }
 
+void IMB_colormanagement_imbuf_make_colorspace(ImBuf *ibuf, const char *to_colorspace, int flag)
+{
+       int predivide = ibuf->flags & IB_cm_predivide;
+
+       if (ibuf->rect_float && (flag & IB_rectfloat)) {
+               IMB_colormanagement_transform(ibuf->rect_float, ibuf->x, ibuf->y, ibuf->channels,
+                                             global_role_scene_linear, to_colorspace, predivide);
+       }
+}
+
 static void imbuf_verify_float(ImBuf *ibuf)
 {
        /* multiple threads could request for display buffer at once and in case
@@ -2208,6 +2193,13 @@ ColorSpace *colormanage_colorspace_get_named(const char *name)
        return NULL;
 }
 
+ColorSpace *colormanage_colorspace_get_roled(int role)
+{
+       const char *role_colorspace = IMB_colormanagement_role_colorspace_name_get(role);
+
+       return colormanage_colorspace_get_named(role_colorspace);
+}
+
 ColorSpace *colormanage_colorspace_get_indexed(int index)
 {
        /* display indices are 1-based */
@@ -2240,6 +2232,21 @@ const char *IMB_colormanagement_colorspace_get_indexed_name(int index)
        return "";
 }
 
+void IMB_colormanagment_colorspace_from_ibuf_ftype(ColorManagedColorspaceSettings *colorspace_settings, ImBuf *ibuf)
+{
+       ImFileType *type;
+
+       for (type = IMB_FILE_TYPES; type->is_a; type++) {
+               if (type->save && type->ftype(type, ibuf)) {
+                       const char *role_colorspace;
+
+                       role_colorspace = IMB_colormanagement_role_colorspace_name_get(type->default_save_role);
+
+                       BLI_strncpy(colorspace_settings->name, role_colorspace, sizeof(colorspace_settings->name));
+               }
+       }
+}
+
 /*********************** RNA helper functions *************************/
 
 void IMB_colormanagement_display_items_add(EnumPropertyItem **items, int *totitem)
index 71313d4..676dde1 100644 (file)
@@ -43,6 +43,9 @@ extern "C" {
 #include "IMB_imbuf.h"
 #include "IMB_allocimbuf.h"
 
+#include "IMB_colormanagement.h"
+#include "IMB_colormanagement_intern.h"
+
 int imb_save_dds(struct ImBuf * ibuf, const char *name, int flags)
 {
        return(0); /* todo: finish this function */
@@ -79,7 +82,7 @@ int imb_is_a_dds(unsigned char *mem) // note: use at most first 32 bytes
        return(1);
 }
 
-struct ImBuf *imb_load_dds(unsigned char *mem, size_t size, int flags)
+struct ImBuf *imb_load_dds(unsigned char *mem, size_t size, int flags, char colorspace[IM_MAX_SPACE])
 {
        struct ImBuf * ibuf = 0;
        DirectDrawSurface dds(mem, size); /* reads header */
@@ -92,6 +95,12 @@ struct ImBuf *imb_load_dds(unsigned char *mem, size_t size, int flags)
        Color32 pixel;
        Color32 *pixels = 0;
 
+       /* OCIO_TODO: never was able to save DDS, so can'ttest loading
+        *            but profile used to be set to sRGB and can't see rect_float here, so
+        *            default byte space should work fine
+        */
+       colorspace_set_default_role(colorspace, IM_MAX_SPACE, COLOR_ROLE_DEFAULT_BYTE);
+
        if (!imb_is_a_dds(mem))
                return (0);
 
index 5892578..2316fef 100644 (file)
 extern "C" {
 #endif
 
+#include "../../IMB_imbuf.h"
+
 int          imb_save_dds(struct ImBuf *ibuf, const char *name, int flags);
 int           imb_is_a_dds(unsigned char *mem); /* use only first 32 bytes of mem */
-struct ImBuf *imb_load_dds(unsigned char *mem, size_t size, int flags);
+struct ImBuf *imb_load_dds(unsigned char *mem, size_t size, int flags, char colorspace[IM_MAX_SPACE]);
 
 #ifdef __cplusplus
 }
index d67de3b..ed4db50 100644 (file)
@@ -30,6 +30,8 @@
 #include "IMB_imbuf_types.h"
 #include "IMB_filetype.h"
 
+#include "IMB_colormanagement.h"
+
 #ifdef WITH_OPENEXR
 #include "openexr/openexr_api.h"
 #endif
@@ -66,34 +68,34 @@ void quicktime_exit(void);
 #endif
 
 ImFileType IMB_FILE_TYPES[] = {
-       {NULL, NULL, imb_is_a_jpeg, imb_ftype_default, imb_load_jpeg, imb_savejpeg, NULL, 0, JPG},
-       {NULL, NULL, imb_is_a_png, imb_ftype_default, imb_loadpng, imb_savepng, NULL, 0, PNG},
-       {NULL, NULL, imb_is_a_bmp, imb_ftype_default, imb_bmp_decode, imb_savebmp, NULL, 0, BMP},
-       {NULL, NULL, imb_is_a_targa, imb_ftype_default, imb_loadtarga, imb_savetarga, NULL, 0, TGA},
-       {NULL, NULL, imb_is_a_iris, imb_ftype_iris, imb_loadiris, imb_saveiris, NULL, 0, IMAGIC},
+       {NULL, NULL, imb_is_a_jpeg, imb_ftype_default, imb_load_jpeg, imb_savejpeg, NULL, 0, JPG, COLOR_ROLE_DEFAULT_BYTE},
+       {NULL, NULL, imb_is_a_png, imb_ftype_default, imb_loadpng, imb_savepng, NULL, 0, PNG, COLOR_ROLE_DEFAULT_BYTE},
+       {NULL, NULL, imb_is_a_bmp, imb_ftype_default, imb_bmp_decode, imb_savebmp, NULL, 0, BMP, COLOR_ROLE_DEFAULT_BYTE},
+       {NULL, NULL, imb_is_a_targa, imb_ftype_default, imb_loadtarga, imb_savetarga, NULL, 0, TGA, COLOR_ROLE_DEFAULT_BYTE},
+       {NULL, NULL, imb_is_a_iris, imb_ftype_iris, imb_loadiris, imb_saveiris, NULL, 0, IMAGIC, COLOR_ROLE_DEFAULT_BYTE},
 #ifdef WITH_CINEON
-       {NULL, NULL, imb_is_dpx, imb_ftype_default, imb_loaddpx, imb_save_dpx, NULL, IM_FTYPE_FLOAT, DPX},
-       {NULL, NULL, imb_is_cineon, imb_ftype_default, imb_loadcineon, imb_savecineon, NULL, IM_FTYPE_FLOAT, CINEON},
+       {NULL, NULL, imb_is_dpx, imb_ftype_default, imb_loaddpx, imb_save_dpx, NULL, IM_FTYPE_FLOAT, DPX, COLOR_ROLE_DEFAULT_FLOAT},
+       {NULL, NULL, imb_is_cineon, imb_ftype_default, imb_loadcineon, imb_savecineon, NULL, IM_FTYPE_FLOAT, CINEON, COLOR_ROLE_DEFAULT_FLOAT},
 #endif
 #ifdef WITH_TIFF
-       {imb_inittiff, NULL, imb_is_a_tiff, imb_ftype_default, imb_loadtiff, imb_savetiff, imb_loadtiletiff, 0, TIF},
+       {imb_inittiff, NULL, imb_is_a_tiff, imb_ftype_default, imb_loadtiff, imb_savetiff, imb_loadtiletiff, 0, TIF, COLOR_ROLE_DEFAULT_BYTE},
 #endif
 #ifdef WITH_HDR
-       {NULL, NULL, imb_is_a_hdr, imb_ftype_default, imb_loadhdr, imb_savehdr, NULL, IM_FTYPE_FLOAT, RADHDR},
+       {NULL, NULL, imb_is_a_hdr, imb_ftype_default, imb_loadhdr, imb_savehdr, NULL, IM_FTYPE_FLOAT, RADHDR, COLOR_ROLE_DEFAULT_FLOAT},
 #endif
 #ifdef WITH_OPENEXR
-       {imb_initopenexr, NULL, imb_is_a_openexr, imb_ftype_default, imb_load_openexr, imb_save_openexr, NULL, IM_FTYPE_FLOAT, OPENEXR},
+       {imb_initopenexr, NULL, imb_is_a_openexr, imb_ftype_default, imb_load_openexr, imb_save_openexr, NULL, IM_FTYPE_FLOAT, OPENEXR, COLOR_ROLE_DEFAULT_FLOAT},
 #endif
 #ifdef WITH_OPENJPEG
-       {NULL, NULL, imb_is_a_jp2, imb_ftype_default, imb_jp2_decode, imb_savejp2, NULL, IM_FTYPE_FLOAT, JP2},
+       {NULL, NULL, imb_is_a_jp2, imb_ftype_default, imb_jp2_decode, imb_savejp2, NULL, IM_FTYPE_FLOAT, JP2, COLOR_ROLE_DEFAULT_BYTE},
 #endif
 #ifdef WITH_DDS
-       {NULL, NULL, imb_is_a_dds, imb_ftype_default, imb_load_dds, NULL, NULL, 0, DDS},
+       {NULL, NULL, imb_is_a_dds, imb_ftype_default, imb_load_dds, NULL, NULL, 0, DDS, COLOR_ROLE_DEFAULT_BYTE},
 #endif
 #ifdef WITH_QUICKTIME
-       {quicktime_init, quicktime_exit, imb_is_a_quicktime, imb_ftype_quicktime, imb_quicktime_decode, NULL, NULL, 0, QUICKTIME},
+       {quicktime_init, quicktime_exit, imb_is_a_quicktime, imb_ftype_quicktime, imb_quicktime_decode, NULL, NULL, 0, QUICKTIME, COLOR_ROLE_DEFAULT_BYTE},
 #endif
-       {NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0}
+       {NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, 0}
 };
        
 void imb_filetypes_init(void)
index ea493e2..97316c4 100644 (file)
@@ -1254,7 +1254,8 @@ struct anim *IMB_anim_open_proxy(
 
        get_proxy_filename(anim, preview_size, fname, FALSE);
 
-       anim->proxy_anim[i] = IMB_open_anim(fname, 0, 0);
+       /* proxies are generated in default color space */
+       anim->proxy_anim[i] = IMB_open_anim(fname, 0, 0, NULL);
        
        anim->proxies_tried |= preview_size;
 
index 13b0fc1..5835593 100644 (file)
@@ -42,6 +42,9 @@
 #include "IMB_allocimbuf.h"
 #include "IMB_filetype.h"
 
+#include "IMB_colormanagement.h"
+#include "IMB_colormanagement_intern.h"
+
 typedef struct {
        unsigned short  imagic;      /* stuff saved on disk . . */
        unsigned short  type;
@@ -247,7 +250,7 @@ int imb_is_a_iris(unsigned char *mem)
  *
  */
 
-struct ImBuf *imb_loadiris(unsigned char *mem, size_t size, int flags)
+struct ImBuf *imb_loadiris(unsigned char *mem, size_t size, int flags, char colorspace[IM_MAX_SPACE])
 {
        unsigned int *base, *lptr = NULL;
        float *fbase, *fptr = NULL;
@@ -265,6 +268,9 @@ struct ImBuf *imb_loadiris(unsigned char *mem, size_t size, int flags)
        
        if (!imb_is_a_iris(mem)) return NULL;
 
+       /* OCIO_TODO: only tested with 1 byte per pixel, not sure how to test with other settings */
+       colorspace_set_default_role(colorspace, IM_MAX_SPACE, COLOR_ROLE_DEFAULT_BYTE);
+
        /*printf("new iris\n");*/
        
        file_data = mem;
index 1fe9a5a..b2221a7 100644 (file)
@@ -36,6 +36,9 @@
 #include "IMB_allocimbuf.h"
 #include "IMB_filetype.h"
 
+#include "IMB_colormanagement.h"
+#include "IMB_colormanagement_intern.h"
+
 #include "openjpeg.h"
 
 #define JP2_FILEHEADER_SIZE 14
@@ -109,7 +112,7 @@ static void info_callback(const char *msg, void *client_data)
        } \
        } (void)0 \
 
-struct ImBuf *imb_jp2_decode(unsigned char *mem, size_t size, int flags)
+struct ImBuf *imb_jp2_decode(unsigned char *mem, size_t size, int flags, char colorspace[IM_MAX_SPACE])
 {
        struct ImBuf *ibuf = NULL;
        int use_float = FALSE; /* for precision higher then 8 use float */
@@ -137,6 +140,9 @@ struct ImBuf *imb_jp2_decode(unsigned char *mem, size_t size, int flags)
        if (!is_jp2 && !is_j2k)
                return(NULL);
 
+       /* both 8, 12 and 16 bit JP2Ks are default to standard byte colorspace */
+       colorspace_set_default_role(colorspace, IM_MAX_SPACE, COLOR_ROLE_DEFAULT_BYTE);
+
        /* configure the event callbacks (not required) */
        memset(&event_mgr, 0, sizeof(opj_event_mgr_t));
        event_mgr.error_handler = error_callback;
index 364950b..59cf790 100644 (file)
@@ -48,6 +48,9 @@
 #include "jpeglib.h" 
 #include "jerror.h"
 
+#include "IMB_colormanagement.h"
+#include "IMB_colormanagement_intern.h"
+
 #define IS_jpg(x)       (x->ftype & JPG)
 #define IS_stdjpg(x)    ((x->ftype & JPG_MSK) == JPG_STD)
 #define IS_vidjpg(x)    ((x->ftype & JPG_MSK) == JPG_VID)
@@ -442,14 +445,16 @@ next_stamp_marker:
        return(ibuf);
 }
 
-ImBuf *imb_load_jpeg(unsigned char *buffer, size_t size, int flags)
+ImBuf *imb_load_jpeg(unsigned char *buffer, size_t size, int flags, char colorspace[IM_MAX_SPACE])
 {
        struct jpeg_decompress_struct _cinfo, *cinfo = &_cinfo;
        struct my_error_mgr jerr;
        ImBuf *ibuf;
 
        if (!imb_is_a_jpeg(buffer)) return NULL;
-       
+
+       colorspace_set_default_role(colorspace, IM_MAX_SPACE, COLOR_ROLE_DEFAULT_BYTE);
+
        cinfo->err = jpeg_std_error(&jerr.pub);
        jerr.pub.error_exit = jpeg_error;
 
index 26aab29..4dfa168 100644 (file)
@@ -64,6 +64,9 @@ _CRTIMP void __cdecl _invalid_parameter_noinfo(void)
 #include "IMB_allocimbuf.h"
 #include "IMB_metadata.h"
 
+#include "IMB_colormanagement.h"
+#include "IMB_colormanagement_intern.h"
+
 #include "openexr_multi.h"
 }
 
@@ -1129,13 +1132,15 @@ static int exr_is_multilayer(InputFile *file)
        return 0;
 }
 
-struct ImBuf *imb_load_openexr(unsigned char *mem, size_t size, int flags)
+struct ImBuf *imb_load_openexr(unsigned char *mem, size_t size, int flags, char colorspace[IM_MAX_SPACE])
 {
        struct ImBuf *ibuf = NULL;
        InputFile *file = NULL;
 
        if (imb_is_a_openexr(mem) == 0) return(NULL);
 
+       colorspace_set_default_role(colorspace, IM_MAX_SPACE, COLOR_ROLE_DEFAULT_FLOAT);
+
        try
        {
                Mem_IStream *membuf = new Mem_IStream(mem, size);
index d12fe2f..3135795 100644 (file)
@@ -50,7 +50,7 @@ int           imb_is_a_openexr                        (unsigned char *mem);
        
 int            imb_save_openexr                        (struct ImBuf *ibuf, const char *name, int flags);
 
-struct ImBuf *imb_load_openexr         (unsigned char *mem, size_t size, int flags);
+struct ImBuf *imb_load_openexr         (unsigned char *mem, size_t size, int flags, char *colorspace);
 
 #ifdef __cplusplus
 }
index 92cd962..7db34e2 100644 (file)
@@ -47,6 +47,9 @@
 #include "IMB_metadata.h"
 #include "IMB_filetype.h"
 
+#include "IMB_colormanagement.h"
+#include "IMB_colormanagement_intern.h"
+
 typedef struct PNGReadStruct {
        unsigned char *data;
        unsigned int size;
@@ -302,7 +305,7 @@ int imb_savepng(struct ImBuf *ibuf, const char *name, int flags)
        return(1);
 }
 
-ImBuf *imb_loadpng(unsigned char *mem, size_t size, int flags)
+ImBuf *imb_loadpng(unsigned char *mem, size_t size, int flags, char colorspace[IM_MAX_SPACE])
 {
        struct ImBuf *ibuf = NULL;
        png_structp png_ptr;
@@ -317,11 +320,13 @@ ImBuf *imb_loadpng(unsigned char *mem, size_t size, int flags)
        unsigned char *from, *to;
        unsigned short *from16;
        float *to_float;
-       float tmp[4];
        int i, bytesperpixel;
 
        if (imb_is_a_png(mem) == 0) return(NULL);
 
+       /* both 8 and 16 bit PNGs are default to standard byte colorspace */
+       colorspace_set_default_role(colorspace, IM_MAX_SPACE, COLOR_ROLE_DEFAULT_BYTE);
+
        png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,
                                         NULL, NULL, NULL);
        if (png_ptr == NULL) {
@@ -443,37 +448,33 @@ ImBuf *imb_loadpng(unsigned char *mem, size_t size, int flags)
                        switch (bytesperpixel) {
                                case 4:
                                        for (i = ibuf->x * ibuf->y; i > 0; i--) {
-                                               tmp[0] = from16[0] / 65535.0;
-                                               tmp[1] = from16[1] / 65535.0;
-                                               tmp[2] = from16[2] / 65535.0;
-                                               tmp[3] = from16[3] / 65535.0;
-                                               srgb_to_linearrgb_v4(to_float, tmp);
+                                               to_float[0] = from16[0] / 65535.0;
+                                               to_float[1] = from16[1] / 65535.0;
+                                               to_float[2] = from16[2] / 65535.0;
+                                               to_float[3] = from16[3] / 65535.0;
                                                to_float += 4; from16 += 4;
                                        }
                                        break;
                                case 3:
                                        for (i = ibuf->x * ibuf->y; i > 0; i--) {
-                                               tmp[0] = from16[0] / 65535.0;
-                                               tmp[1] = from16[1] / 65535.0;
-                                               tmp[2] = from16[2] / 65535.0;
-                                               tmp[3] = 1.0;
-                                               srgb_to_linearrgb_v4(to_float, tmp);
+                                               to_float[0] = from16[0] / 65535.0;
+                                               to_float[1] = from16[1] / 65535.0;
+                                               to_float[2] = from16[2] / 65535.0;
+                                               to_float[3] = 1.0;
                                                to_float += 4; from16 += 3;
                                        }
                                        break;
                                case 2:
                                        for (i = ibuf->x * ibuf->y; i > 0; i--) {
-                                               tmp[0] = tmp[1] = tmp[2] = from16[0] / 65535.0;
-                                               tmp[3] = from16[1] / 65535.0;
-                                               srgb_to_linearrgb_v4(to_float, tmp);
+                                               to_float[0] = to_float[1] = to_float[2] = from16[0] / 65535.0;
+                                               to_float[3] = from16[1] / 65535.0;
                                                to_float += 4; from16 += 2;
                                        }
                                        break;
                                case 1:
                                        for (i = ibuf->x * ibuf->y; i > 0; i--) {
-                                               tmp[0] = tmp[1] = tmp[2] = from16[0] / 65535.0;
-                                               tmp[3] = 1.0;
-                                               srgb_to_linearrgb_v4(to_float, tmp);
+                                               to_float[0] = to_float[1] = to_float[2] = from16[0] / 65535.0;
+                                               to_float[3] = 1.0;
                                                to_float += 4; from16++;
                                        }
                                        break;
index 4cd5048..4eb6999 100644 (file)
@@ -53,6 +53,9 @@
 #include "IMB_allocimbuf.h"
 #include "IMB_filetype.h"
 
+#include "IMB_colormanagement.h"
+#include "IMB_colormanagement_intern.h"
+
 /* needed constants */
 #define MINELEN 8
 #define MAXELEN 0x7fff
@@ -171,7 +174,7 @@ int imb_is_a_hdr(unsigned char *buf)
        return 0;
 }
 
-struct ImBuf *imb_loadhdr(unsigned char *mem, size_t size, int flags)
+struct ImBuf *imb_loadhdr(unsigned char *mem, size_t size, int flags, char colorspace[IM_MAX_SPACE])
 {
        struct ImBuf *ibuf;
        RGBE *sline;
@@ -184,6 +187,8 @@ struct ImBuf *imb_loadhdr(unsigned char *mem, size_t size, int flags)
        char oriY[80], oriX[80];
 
        if (imb_is_a_hdr((void *)mem)) {
+               colorspace_set_default_role(colorspace, IM_MAX_SPACE, COLOR_ROLE_DEFAULT_FLOAT);
+
                /* find empty line, next line is resolution info */
                for (x = 1; x < size; x++) {
                        if ((mem[x - 1] == '\n') && (mem[x] == '\n')) {
index 4bde715..764c326 100644 (file)
 #include "IMB_imbuf.h"
 #include "IMB_filetype.h"
 
-ImBuf *IMB_ibImageFromMemory(unsigned char *mem, size_t size, int flags, const char *descr)
+#include "IMB_colormanagement.h"
+#include "IMB_colormanagement_intern.h"
+
+ImBuf *IMB_ibImageFromMemory(unsigned char *mem, size_t size, int flags, char colorspace[IM_MAX_SPACE], const char *descr)
 {
        ImBuf *ibuf;
        ImFileType *type;
+       char effective_colorspace[IM_MAX_SPACE] = "";
 
        if (mem == NULL) {
                fprintf(stderr, "%s: NULL pointer\n", __func__);
                return NULL;
        }
 
+       if (colorspace)
+               BLI_strncpy(effective_colorspace, colorspace, sizeof(effective_colorspace));
+
        for (type = IMB_FILE_TYPES; type->is_a; type++) {
                if (type->load) {
-                       ibuf = type->load(mem, size, flags);
+                       ibuf = type->load(mem, size, flags, effective_colorspace);
                        if (ibuf) {
+                               if (colorspace) {
+                                       if (ibuf->rect) {
+                                               /* byte buffer is never internally converted to some standard space,
+                                                * store pointer to it's color space descriptor instead
+                                                */
+                                               ibuf->rect_colorspace = colormanage_colorspace_get_named(colorspace);
+                                       }
+
+                                       BLI_strncpy(colorspace, effective_colorspace, IM_MAX_SPACE);
+                               }
+
+                               /* OCIO_TODO: in some cases it's faster to do threaded conversion,
+                                *            but how to distinguish such cases */
+                               colormanage_imbuf_make_linear(ibuf, effective_colorspace);
+
                                if (flags & IB_premul) {
                                        IMB_premultiply_alpha(ibuf);
                                        ibuf->flags |= IB_premul;
@@ -83,7 +105,7 @@ ImBuf *IMB_ibImageFromMemory(unsigned char *mem, size_t size, int flags, const c
        return NULL;
 }
 
-ImBuf *IMB_loadifffile(int file, int flags, const char *descr)
+ImBuf *IMB_loadifffile(int file, int flags, char colorspace[IM_MAX_SPACE], const char *descr)
 {
        ImBuf *ibuf;
        unsigned char *mem;
@@ -99,7 +121,7 @@ ImBuf *IMB_loadifffile(int file, int flags, const char *descr)
                return NULL;
        }
 
-       ibuf = IMB_ibImageFromMemory(mem, size, flags, descr);
+       ibuf = IMB_ibImageFromMemory(mem, size, flags, colorspace, descr);
 
        if (munmap(mem, size))
                fprintf(stderr, "%s: couldn't unmap file %s\n", __func__, descr);
@@ -122,7 +144,7 @@ static void imb_cache_filename(char *filename, const char *name, int flags)
        BLI_strncpy(filename, name, IB_FILENAME_SIZE);
 }
 
-ImBuf *IMB_loadiffname(const char *filepath, int flags)
+ImBuf *IMB_loadiffname(const char *filepath, int flags, char colorspace[IM_MAX_SPACE])
 {
        ImBuf *ibuf;
        int file, a;
@@ -133,7 +155,7 @@ ImBuf *IMB_loadiffname(const char *filepath, int flags)
        file = BLI_open(filepath_tx, O_BINARY | O_RDONLY, 0);
        if (file < 0) return NULL;
 
-       ibuf = IMB_loadifffile(file, flags, filepath_tx);
+       ibuf = IMB_loadifffile(file, flags, colorspace, filepath_tx);
 
        if (ibuf) {
                BLI_strncpy(ibuf->name, filepath, sizeof(ibuf->name));
@@ -148,7 +170,7 @@ ImBuf *IMB_loadiffname(const char *filepath, int flags)
        return ibuf;
 }
 
-ImBuf *IMB_testiffname(const char *filepath, int flags)
+ImBuf *IMB_testiffname(const char *filepath, int flags, char colorspace[IM_MAX_SPACE])
 {
        ImBuf *ibuf;
        int file;
@@ -159,7 +181,7 @@ ImBuf *IMB_testiffname(const char *filepath, int flags)
        file = BLI_open(filepath_tx, O_BINARY | O_RDONLY, 0);
        if (file < 0) return NULL;
 
-       ibuf = IMB_loadifffile(file, flags | IB_test | IB_multilayer, filepath_tx);
+       ibuf = IMB_loadifffile(file, flags | IB_test | IB_multilayer, colorspace, filepath_tx);
 
        if (ibuf) {
                BLI_strncpy(ibuf->name, filepath, sizeof(ibuf->name));
index 4df4938..be99050 100644 (file)
@@ -46,6 +46,8 @@
 #include "IMB_allocimbuf.h"
 #include "IMB_filetype.h"
 
+#include "IMB_colormanagement.h"
+#include "IMB_colormanagement_intern.h"
 
 /* this one is only def-ed once, strangely... related to GS? */
 #define GSS(x) (((uchar *)(x))[1] << 8 | ((uchar *)(x))[0])
@@ -546,16 +548,18 @@ partial_load:
 }
 
 
-ImBuf *imb_loadtarga(unsigned char *mem, size_t mem_size, int flags)
+ImBuf *imb_loadtarga(unsigned char *mem, size_t mem_size, int flags, char colorspace[IM_MAX_SPACE])
 {
        TARGA tga;
        struct ImBuf *ibuf;
        int col, count, size;
        unsigned int *rect, *cmap = NULL /*, mincol = 0*/, maxcol = 0;
        uchar *cp = (uchar *) &col;
-       
+
        if (checktarga(&tga, mem) == 0) return(NULL);
 
+       colorspace_set_default_role(colorspace, IM_MAX_SPACE, COLOR_ROLE_DEFAULT_BYTE);
+
        if (flags & IB_test) ibuf = IMB_allocImBuf(tga.xsize, tga.ysize, tga.pixsize, 0);
        else ibuf = IMB_allocImBuf(tga.xsize, tga.ysize, (tga.pixsize + 0x7) & ~0x7, IB_rect);
 
index 2a2aedb..ff7218d 100644 (file)
@@ -313,7 +313,7 @@ ImBuf *IMB_thumb_create(const char *path, ThumbSize size, ThumbSource source, Im
                                                img = IMB_loadblend_thumb(path);
                                        }
                                        else {
-                                               img = IMB_loadiffname(path, IB_rect | IB_metadata);
+                                               img = IMB_loadiffname(path, IB_rect | IB_metadata, NULL);
                                        }
                                }
 
@@ -326,7 +326,7 @@ ImBuf *IMB_thumb_create(const char *path, ThumbSize size, ThumbSource source, Im
                        }
                        else if (THB_SOURCE_MOVIE == source) {
                                struct anim *anim = NULL;
-                               anim = IMB_open_anim(path, IB_rect | IB_metadata, 0);
+                               anim = IMB_open_anim(path, IB_rect | IB_metadata, 0, NULL);
                                if (anim != NULL) {
                                        img = IMB_anim_absolute(anim, 0, IMB_TC_NONE, IMB_PROXY_NONE);
                                        if (img == NULL) {
@@ -376,6 +376,7 @@ ImBuf *IMB_thumb_create(const char *path, ThumbSize size, ThumbSource source, Im
                }
                img->ftype = PNG;
                img->planes = 32;
+
                if (IMB_saveiff(img, temp, IB_rect | IB_metadata)) {
 #ifndef WIN32
                        chmod(temp, S_IRUSR | S_IWUSR);
@@ -401,7 +402,7 @@ ImBuf *IMB_thumb_read(const char *path, ThumbSize size)
                return NULL;
        }
        if (thumbpath_from_uri(uri, thumb, sizeof(thumb), size)) {              
-               img = IMB_loadiffname(thumb, IB_rect | IB_metadata);
+               img = IMB_loadiffname(thumb, IB_rect | IB_metadata, NULL);
        }
 
        return img;
@@ -456,10 +457,10 @@ ImBuf *IMB_thumb_manage(const char *path, ThumbSize size, ThumbSource source)
 
        if (thumbpath_from_uri(uri, thumb, sizeof(thumb), size)) {
                if (BLI_path_ncmp(path, thumb, sizeof(thumb)) == 0) {
-                       img = IMB_loadiffname(path, IB_rect);
+                       img = IMB_loadiffname(path, IB_rect, NULL);
                }
                else {
-                       img = IMB_loadiffname(thumb, IB_rect | IB_metadata);
+                       img = IMB_loadiffname(thumb, IB_rect | IB_metadata, NULL);
                        if (img) {
                                char mtime[40];
                                if (!IMB_metadata_get_field(img, "Thumb::MTime", mtime, 40)) {
index ac5f5da..4ee3792 100644 (file)
@@ -57,6 +57,9 @@
 #include "IMB_filetype.h"
 #include "IMB_filter.h"
 
+#include "IMB_colormanagement.h"
+#include "IMB_colormanagement_intern.h"
+
 #include "tiffio.h"
 
 #ifdef WIN32
@@ -508,7 +511,7 @@ void imb_inittiff(void)
  *
  * \return: A newly allocated ImBuf structure if successful, otherwise NULL.
  */
-ImBuf *imb_loadtiff(unsigned char *mem, size_t size, int flags)
+ImBuf *imb_loadtiff(unsigned char *mem, size_t size, int flags, char colorspace[IM_MAX_SPACE])
 {
        TIFF *image = NULL;
        ImBuf *ibuf = NULL, *hbuf;
@@ -527,6 +530,9 @@ ImBuf *imb_loadtiff(unsigned char *mem, size_t size, int flags)
        if (imb_is_a_tiff(mem) == 0)
                return NULL;
 
+       /* both 8 and 16 bit PNGs are default to standard byte colorspace */
+       colorspace_set_default_role(colorspace, IM_MAX_SPACE, COLOR_ROLE_DEFAULT_BYTE);
+
        image = imb_tiff_client_open(&memFile, mem, size);
 
        if (image == NULL) {
index 1c182e9..5d785e0 100644 (file)
 #include "IMB_imbuf.h"
 #include "IMB_filetype.h"
 
+#include "IMB_colormanagement.h"
+#include "IMB_colormanagement_intern.h"
+
 #include "imbuf.h"
 
+static ImBuf *prepare_write_imbuf(ImFileType *type, ImBuf *ibuf)
+{
+       ImBuf *write_ibuf = ibuf;
+
+       if (type->flag & IM_FTYPE_FLOAT) {
+               /* pass */
+       }
+       else {
+               if (ibuf->rect == NULL && ibuf->rect_float) {
+                       ibuf->rect_colorspace = colormanage_colorspace_get_roled(COLOR_ROLE_DEFAULT_BYTE);
+                       IMB_rect_from_float(ibuf);
+               }
+       }
+
+       return write_ibuf;
+}
+
 short IMB_saveiff(struct ImBuf *ibuf, const char *name, int flags)
 {
        ImFileType *type;
@@ -49,11 +69,17 @@ short IMB_saveiff(struct ImBuf *ibuf, const char *name, int flags)
 
        for (type = IMB_FILE_TYPES; type->is_a; type++) {
                if (type->save && type->ftype(type, ibuf)) {
-                       if (!(type->flag & IM_FTYPE_FLOAT)) {
-                               if (ibuf->rect == NULL && ibuf->rect_float)
-                                       IMB_rect_from_float(ibuf);
-                       }
-                       return type->save(ibuf, name, flags);
+                       ImBuf *write_ibuf;
+                       short result = FALSE;
+
+                       write_ibuf = prepare_write_imbuf(type, ibuf);
+
+                       result = type->save(write_ibuf, name, flags);
+
+                       if (write_ibuf != ibuf)
+                               IMB_freeImBuf(write_ibuf);
+
+                       return result;
                }
        }
 
index 8c071ac..c66c008 100644 (file)
@@ -120,6 +120,8 @@ static void rna_Image_save(Image *image, ReportList *reports)
                        if (image->source == IMA_SRC_GENERATED)
                                image->source = IMA_SRC_FILE;
 
+                       IMB_colormanagment_colorspace_from_ibuf_ftype(&image->colorspace_settings, ibuf);
+
                        ibuf->userflags &= ~IB_BITMAPDIRTY;
                }
                else {
index 549868e..ab1dfbf 100644 (file)
@@ -188,7 +188,8 @@ static Sequence *rna_Sequences_new_movie(ID *id, Editing *ed, ReportList *report
        Scene *scene = (Scene *)id;
        Sequence *seq;
 
-       struct anim *an = openanim(file, IB_rect, 0);
+       /* OCIO_TODO: support configurable color spaces for strips */
+       struct anim *an = openanim(file, IB_rect, 0, NULL);
 
        if (an == NULL) {
                BKE_report(reports, RPT_ERROR, "Sequences.new_movie: unable to open movie file");
index 069062b..599d913 100644 (file)
@@ -2411,7 +2411,8 @@ void RE_init_threadcount(Render *re)
  * x/y offsets are only used on a partial copy when dimensions don't match */
 void RE_layer_load_from_file(RenderLayer *layer, ReportList *reports, const char *filename, int x, int y)
 {
-       ImBuf *ibuf = IMB_loadiffname(filename, IB_rect);
+       /* OCIO_TODO: assume layer was saved in defaule color space */
+       ImBuf *ibuf = IMB_loadiffname(filename, IB_rect, NULL);
 
        if (ibuf && (ibuf->rect || ibuf->rect_float)) {
                if (ibuf->x == layer->rectx && ibuf->y == layer->recty) {
index 0259146..1b76e71 100644 (file)
@@ -1296,7 +1296,7 @@ static uiBlock *wm_block_create_splash(bContext *C, ARegion *ar, void *UNUSED(ar
        extern int datatoc_splash_png_size;
 
        ImBuf *ibuf = IMB_ibImageFromMemory((unsigned char *)datatoc_splash_png,
-                                           datatoc_splash_png_size, IB_rect, "<splash screen>");
+                                           datatoc_splash_png_size, IB_rect, NULL, "<splash screen>");
 #else
        ImBuf *ibuf = NULL;
 #endif
index e3867c0..bbe5ddc 100644 (file)
@@ -279,7 +279,8 @@ static void build_pict_list(char *first, int totframes, int fstep, int fontid)
        struct anim *anim;
 
        if (IMB_isanim(first)) {
-               anim = IMB_open_anim(first, IB_rect, 0);
+               /* OCIO_TODO: support different input color space */
+               anim = IMB_open_anim(first, IB_rect, 0, NULL);
                if (anim) {
                        int pic;
                        ibuf = IMB_anim_absolute(anim, 0, IMB_TC_NONE, IMB_PROXY_NONE);
@@ -378,12 +379,13 @@ static void build_pict_list(char *first, int totframes, int fstep, int fontid)
                        pupdate_time();
 
                        if (ptottime > 1.0) {
+                               /* OCIO_TODO: support different input color space */
                                if (picture->mem) {
                                        ibuf = IMB_ibImageFromMemory((unsigned char *)picture->mem, picture->size,
-                                                                    picture->IB_flags, picture->name);
+                                                                    picture->IB_flags, NULL, picture->name);
                                }
                                else {
-                                       ibuf = IMB_loadiffname(picture->name, picture->IB_flags);
+                                       ibuf = IMB_loadiffname(picture->name, picture->IB_flags, NULL);
                                }
                                if (ibuf) {
                                        playanim_toscreen(picture, ibuf, fontid);
@@ -824,7 +826,8 @@ void playanim(int argc, const char **argv)
        }
 
        if (IMB_isanim(filepath)) {
-               anim = IMB_open_anim(filepath, IB_rect, 0);
+               /* OCIO_TODO: support different input color spaces */
+               anim = IMB_open_anim(filepath, IB_rect, 0, NULL);
                if (anim) {
                        ibuf = IMB_anim_absolute(anim, 0, IMB_TC_NONE, IMB_PROXY_NONE);
                        IMB_close_anim(anim);
@@ -836,7 +839,8 @@ void playanim(int argc, const char **argv)
        }
 
        if (ibuf == NULL) {
-               ibuf = IMB_loadiffname(filepath, IB_rect);
+               /* OCIO_TODO: support different input color space */
+               ibuf = IMB_loadiffname(filepath, IB_rect, NULL);
        }
 
        if (ibuf == NULL) {
@@ -948,11 +952,13 @@ void playanim(int argc, const char **argv)
                                ibuf = IMB_anim_absolute(ps.picture->anim, ps.picture->frame, IMB_TC_NONE, IMB_PROXY_NONE);
                        }
                        else if (ps.picture->mem) {
+                               /* use correct colorspace here */
                                ibuf = IMB_ibImageFromMemory((unsigned char *) ps.picture->mem, ps.picture->size,
-                                                            ps.picture->IB_flags, ps.picture->name);
+                                                            ps.picture->IB_flags, NULL, ps.picture->name);
                        }
                        else {
-                               ibuf = IMB_loadiffname(ps.picture->name, ps.picture->IB_flags);
+                               /* use correct colorspace here */
+                               ibuf = IMB_loadiffname(ps.picture->name, ps.picture->IB_flags, NULL);
                        }
 
                        if (ibuf) {