Merging r50248 through r50264 from trunk into soc-2011-tomato
[blender-staging.git] / source / blender / editors / space_image / image_ops.c
index 3eeae1f16de1c45d2ee3d2f7ce1999acec385a66..43e4db16b7d6c4c1fd2e3145f418bdd877ea5623 100644 (file)
@@ -55,6 +55,7 @@
 #include "BKE_report.h"
 #include "BKE_screen.h"
 
+#include "IMB_colormanagement.h"
 #include "IMB_imbuf.h"
 #include "IMB_imbuf_types.h"
 
@@ -1168,6 +1169,10 @@ static int save_image_options_init(SaveImageOptions *simopts, SpaceImage *sima,
                        }
                        BLI_path_abs(simopts->filepath, G.main->name);
                }
+
+               /* color management */
+               BKE_color_managed_display_settings_copy(&simopts->im_format.display_settings, &scene->display_settings);
+               BKE_color_managed_view_settings_copy(&simopts->im_format.view_settings, &scene->view_settings);
        }
 
        ED_space_image_release_buffer(sima, lock);
@@ -1196,6 +1201,38 @@ static void save_image_options_to_op(SaveImageOptions *simopts, wmOperator *op)
        RNA_string_set(op->ptr, "filepath", simopts->filepath);
 }
 
+static ImBuf *save_image_colormanaged_imbuf_acquire(ImBuf *ibuf, SaveImageOptions *simopts, void **cache_handle)
+{
+       ImageFormatData *imf = &simopts->im_format;
+       ImBuf *colormanaged_ibuf;
+       int do_colormanagement;
+
+       *cache_handle = NULL;
+       do_colormanagement = !BKE_imtype_supports_float(imf->imtype);
+
+       if (do_colormanagement) {
+               unsigned char *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);
+                       colormanaged_ibuf->rect = (unsigned int *) display_buffer;
+               }
+               else {
+                       /* no cache handle means color management didn't run transformation
+                        * or performed transformation to image's byte buffer which doesn't
+                        * require allocating new image buffer
+                        */
+                       colormanaged_ibuf = ibuf;
+               }
+       }
+       else {
+               colormanaged_ibuf = ibuf;
+       }
+
+       return colormanaged_ibuf;
+}
+
 /* assumes name is FILE_MAX */
 /* ima->name and ibuf->name should end up the same */
 static void save_image_doit(bContext *C, SpaceImage *sima, wmOperator *op, SaveImageOptions *simopts, int do_newpath)
@@ -1205,6 +1242,8 @@ static void save_image_doit(bContext *C, SpaceImage *sima, wmOperator *op, SaveI
        ImBuf *ibuf = ED_space_image_acquire_buffer(sima, &lock);
 
        if (ibuf) {
+               void *cache_handle;
+               ImBuf *colormanaged_ibuf;
                const char *relbase = ID_BLEND_PATH(CTX_data_main(C), &ima->id);
                const short relative = (RNA_struct_find_property(op->ptr, "relative_path") && RNA_boolean_get(op->ptr, "relative_path"));
                const short save_copy = (RNA_struct_find_property(op->ptr, "copy") && RNA_boolean_get(op->ptr, "copy"));
@@ -1231,7 +1270,9 @@ static void save_image_doit(bContext *C, SpaceImage *sima, wmOperator *op, SaveI
                                ibuf->planes = BKE_imbuf_alpha_test(ibuf) ? 32 : 24;
                        }
                }
-               
+
+               colormanaged_ibuf = save_image_colormanaged_imbuf_acquire(ibuf, simopts, &cache_handle);
+
                if (simopts->im_format.imtype == R_IMF_IMTYPE_MULTILAYER) {
                        Scene *scene = CTX_data_scene(C);
                        RenderResult *rr = BKE_image_acquire_renderresult(scene, ima);
@@ -1245,7 +1286,7 @@ static void save_image_doit(bContext *C, SpaceImage *sima, wmOperator *op, SaveI
                        BKE_image_release_renderresult(scene, ima);
                }
                else {
-                       if (BKE_imbuf_write_as(ibuf, simopts->filepath, &simopts->im_format, save_copy)) {
+                       if (BKE_imbuf_write_as(colormanaged_ibuf, simopts->filepath, &simopts->im_format, save_copy)) {
                                ok = TRUE;
                        }
                }
@@ -1294,6 +1335,13 @@ static void save_image_doit(bContext *C, SpaceImage *sima, wmOperator *op, SaveI
                WM_event_add_notifier(C, NC_IMAGE | NA_EDITED, sima->image);
 
                WM_cursor_wait(0);
+
+               if (cache_handle) {
+                       colormanaged_ibuf->rect = NULL;
+                       IMB_freeImBuf(colormanaged_ibuf);
+
+                       IMB_display_buffer_release(cache_handle);
+               }
        }
 
        ED_space_image_release_buffer(sima, lock);
@@ -1389,7 +1437,7 @@ static void image_save_as_draw(bContext *UNUSED(C), wmOperator *op)
 
        /* image template */
        RNA_pointer_create(NULL, &RNA_ImageFormatSettings, imf, &ptr);
-       uiTemplateImageSettings(layout, &ptr);
+       uiTemplateImageSettings(layout, &ptr, TRUE);
 
        /* main draw call */
        RNA_pointer_create(NULL, op->type->srna, op->properties, &ptr);
@@ -1940,12 +1988,14 @@ typedef struct ImageSampleInfo {
        int draw;
 } ImageSampleInfo;
 
-static void image_sample_draw(const bContext *UNUSED(C), ARegion *ar, void *arg_info)
+static void image_sample_draw(const bContext *C, ARegion *ar, void *arg_info)
 {
        ImageSampleInfo *info = arg_info;
        if (info->draw) {
+               Scene *scene = CTX_data_scene(C);
+
                /* no color management needed for images (color_manage=0) */
-               ED_image_draw_info(ar, 0, info->channels, info->x, info->y, info->colp, info->colfp, info->zp, info->zfp);
+               ED_image_draw_info(scene, ar, 0, info->channels, info->x, info->y, info->colp, info->colfp, info->zp, info->zfp);
        }
 }