- added GCC warning -Wstrict-prototypes
[blender.git] / source / blender / editors / space_image / image_ops.c
index f84fd6fc430d7cec0b1f57d538cbc5cfae8205c1..dab486949ead37073d03ddf70783ad935fd0dd87 100644 (file)
 #include <stddef.h>
 #include <string.h>
 #include <stdlib.h>
+#include <errno.h>
 
 #include "MEM_guardedalloc.h"
 
 #include "DNA_object_types.h"
+#include "DNA_node_types.h"
 #include "DNA_packedFile_types.h"
 #include "DNA_scene_types.h"
 
@@ -39,7 +41,6 @@
 #include "BKE_context.h"
 #include "BKE_image.h"
 #include "BKE_global.h"
-#include "BKE_image.h"
 #include "BKE_library.h"
 #include "BKE_main.h"
 #include "BKE_node.h"
@@ -123,13 +124,19 @@ static int space_image_buffer_exists_poll(bContext *C)
 static int space_image_file_exists_poll(bContext *C)
 {
        if(space_image_buffer_exists_poll(C)) {
+               Main *bmain= CTX_data_main(C);
                SpaceImage *sima= CTX_wm_space_image(C);
                ImBuf *ibuf;
                void *lock;
-               int poll;
-               
+               int poll= 0;
+               char name[FILE_MAX];
+
                ibuf= ED_space_image_acquire_buffer(sima, &lock);
-               poll= (ibuf && BLI_exists(ibuf->name) && BLI_is_writable(ibuf->name));
+               if(ibuf) {
+                       BLI_strncpy(name, ibuf->name, FILE_MAX);
+                       BLI_path_abs(name, bmain->name);
+                       poll= (BLI_exists(name) && BLI_is_writable(name));
+               }
                ED_space_image_release_buffer(sima, lock);
 
                return poll;
@@ -426,7 +433,7 @@ void IMAGE_OT_view_zoom(wmOperatorType *ot)
  * Default behavior is to reset the position of the image and set the zoom to 1
  * If the image will not fit within the window rectangle, the zoom is adjusted */
 
-static int view_all_exec(bContext *C, wmOperator *op)
+static int view_all_exec(bContext *C, wmOperator *UNUSED(op))
 {
        SpaceImage *sima;
        ARegion *ar;
@@ -480,7 +487,7 @@ void IMAGE_OT_view_all(wmOperatorType *ot)
 
 /********************** view selected operator *********************/
 
-static int view_selected_exec(bContext *C, wmOperator *op)
+static int view_selected_exec(bContext *C, wmOperator *UNUSED(op))
 {
        SpaceImage *sima;
        ARegion *ar;
@@ -537,7 +544,7 @@ void IMAGE_OT_view_selected(wmOperatorType *ot)
 
 /********************** view zoom in/out operator *********************/
 
-static int view_zoom_in_exec(bContext *C, wmOperator *op)
+static int view_zoom_in_exec(bContext *C, wmOperator *UNUSED(op))
 {
        SpaceImage *sima= CTX_wm_space_image(C);
        ARegion *ar= CTX_wm_region(C);
@@ -560,7 +567,7 @@ void IMAGE_OT_view_zoom_in(wmOperatorType *ot)
        ot->poll= space_image_main_area_poll;
 }
 
-static int view_zoom_out_exec(bContext *C, wmOperator *op)
+static int view_zoom_out_exec(bContext *C, wmOperator *UNUSED(op))
 {
        SpaceImage *sima= CTX_wm_space_image(C);
        ARegion *ar= CTX_wm_region(C);
@@ -641,9 +648,13 @@ static const EnumPropertyItem image_file_type_items[] = {
 #ifdef WITH_TIFF
                {R_TIFF, "TIFF", 0, "Tiff", ""},
 #endif
+#ifdef WITH_DDS
                {R_RADHDR, "RADIANCE_HDR", 0, "Radiance HDR", ""},
+#endif
+#ifdef WITH_CINEON
                {R_CINEON, "CINEON", 0, "Cineon", ""},
                {R_DPX, "DPX", 0, "DPX", ""},
+#endif
 #ifdef WITH_OPENEXR
                {R_OPENEXR, "OPENEXR", 0, "OpenEXR", ""},
        /* saving sequences of multilayer won't work, they copy buffers  */
@@ -669,7 +680,7 @@ static void open_init(bContext *C, wmOperator *op)
        uiIDContextProperty(C, &pprop->ptr, &pprop->prop);
 }
 
-static int open_cancel(bContext *C, wmOperator *op)
+static int open_cancel(bContext *UNUSED(C), wmOperator *op)
 {
        MEM_freeN(op->customdata);
        op->customdata= NULL;
@@ -678,9 +689,10 @@ static int open_cancel(bContext *C, wmOperator *op)
 
 static int open_exec(bContext *C, wmOperator *op)
 {
-       SpaceImage *sima= CTX_wm_space_image(C);
+       SpaceImage *sima= CTX_wm_space_image(C); /* XXX other space types can call */
        Scene *scene= CTX_data_scene(C);
        Object *obedit= CTX_data_edit_object(C);
+       ImageUser *iuser= NULL;
        PropertyPointerRNA *pprop;
        PointerRNA idptr;
        Image *ima= NULL;
@@ -688,10 +700,14 @@ static int open_exec(bContext *C, wmOperator *op)
 
        RNA_string_get(op->ptr, "filepath", str);
        /* default to frame 1 if there's no scene in context */
-       ima= BKE_add_image_file(str, scene ? scene->r.cfra : 1);
+
+       errno= 0;
+
+       ima= BKE_add_image_file(str);
 
        if(!ima) {
                if(op->customdata) MEM_freeN(op->customdata);
+               BKE_reportf(op->reports, RPT_ERROR, "Can't read: \"%s\", %s.", str, errno ? strerror(errno) : "Unsupported image format");
                return OPERATOR_CANCELLED;
        }
        
@@ -710,11 +726,25 @@ static int open_exec(bContext *C, wmOperator *op)
                RNA_property_pointer_set(&pprop->ptr, pprop->prop, idptr);
                RNA_property_update(C, &pprop->ptr, pprop->prop);
        }
-       else if(sima)
+       else if(sima) {
                ED_space_image_set(C, sima, scene, obedit, ima);
+               iuser= &sima->iuser;
+       }
+       else {
+               Tex *tex= CTX_data_pointer_get_type(C, "texture", &RNA_Texture).data;
+               if(tex && tex->type==TEX_IMAGE)
+                       iuser= &tex->iuser;
+               
+       }
+       
+       /* initialize because of new image */
+       if(iuser) {
+               iuser->sfra= 1;
+               iuser->offset= 0;
+               iuser->fie_ima= 2;
+       }
 
-       // XXX other users?
-       BKE_image_signal(ima, (sima)? &sima->iuser: NULL, IMA_SIGNAL_RELOAD);
+       BKE_image_signal(ima, iuser, IMA_SIGNAL_RELOAD);
        WM_event_add_notifier(C, NC_IMAGE|NA_EDITED, ima);
        
        MEM_freeN(op->customdata);
@@ -722,10 +752,25 @@ static int open_exec(bContext *C, wmOperator *op)
        return OPERATOR_FINISHED;
 }
 
-static int open_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int open_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
 {
-       SpaceImage *sima= CTX_wm_space_image(C);
-       char *path= (sima && sima->image)? sima->image->name: U.textudir;
+       SpaceImage *sima= CTX_wm_space_image(C); /* XXX other space types can call */
+       char *path=U.textudir;
+       Image *ima= NULL;
+
+       if(sima) {
+                ima= sima->image;
+       }
+
+       if (ima==NULL) {
+                Tex *tex= CTX_data_pointer_get_type(C, "texture", &RNA_Texture).data;
+                if(tex && tex->type==TEX_IMAGE)
+                        ima= tex->ima;
+       }
+
+       if(ima)
+               path= ima->name;
+       
 
        if(!RNA_property_is_set(op->ptr, "relative_path"))
                RNA_boolean_set(op->ptr, "relative_path", U.flag & USER_RELPATHS);
@@ -740,6 +785,7 @@ static int open_invoke(bContext *C, wmOperator *op, wmEvent *event)
        return OPERATOR_RUNNING_MODAL;
 }
 
+/* called by other space types too */
 void IMAGE_OT_open(wmOperatorType *ot)
 {
        /* identifiers */
@@ -755,7 +801,7 @@ void IMAGE_OT_open(wmOperatorType *ot)
        ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
 
        /* properties */
-       WM_operator_properties_filesel(ot, FOLDERFILE|IMAGEFILE|MOVIEFILE, FILE_SPECIAL, FILE_OPENFILE, FILE_RELPATH);
+       WM_operator_properties_filesel(ot, FOLDERFILE|IMAGEFILE|MOVIEFILE, FILE_SPECIAL, FILE_OPENFILE, WM_FILESEL_FILEPATH|WM_FILESEL_RELPATH);
 }
 
 /******************** replace image operator ********************/
@@ -769,7 +815,7 @@ static int replace_exec(bContext *C, wmOperator *op)
                return OPERATOR_CANCELLED;
        
        RNA_string_get(op->ptr, "filepath", str);
-       BLI_strncpy(sima->image->name, str, sizeof(sima->image->name)-1); /* we cant do much if the str is longer then 240 :/ */
+       BLI_strncpy(sima->image->name, str, sizeof(sima->image->name)); /* we cant do much if the str is longer then 240 :/ */
 
        BKE_image_signal(sima->image, &sima->iuser, IMA_SIGNAL_RELOAD);
        WM_event_add_notifier(C, NC_IMAGE|NA_EDITED, sima->image);
@@ -777,7 +823,7 @@ static int replace_exec(bContext *C, wmOperator *op)
        return OPERATOR_FINISHED;
 }
 
-static int replace_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int replace_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
 {
        SpaceImage *sima= CTX_wm_space_image(C);
 
@@ -810,67 +856,79 @@ void IMAGE_OT_replace(wmOperatorType *ot)
        ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
 
        /* properties */
-       WM_operator_properties_filesel(ot, FOLDERFILE|IMAGEFILE|MOVIEFILE, FILE_SPECIAL, FILE_OPENFILE, FILE_RELPATH);
+       WM_operator_properties_filesel(ot, FOLDERFILE|IMAGEFILE|MOVIEFILE, FILE_SPECIAL, FILE_OPENFILE, WM_FILESEL_FILEPATH|WM_FILESEL_RELPATH);
 }
 
 /******************** save image as operator ********************/
 
 /* assumes name is FILE_MAX */
 /* ima->name and ibuf->name should end up the same */
-static void save_image_doit(bContext *C, SpaceImage *sima, Scene *scene, wmOperator *op, char *path)
+static void save_image_doit(bContext *C, SpaceImage *sima, Scene *scene, wmOperator *op, char *path, int do_newpath)
 {
        Image *ima= ED_space_image(sima);
        void *lock;
        ImBuf *ibuf= ED_space_image_acquire_buffer(sima, &lock);
 
        if (ibuf) {
-               int relative= RNA_boolean_get(op->ptr, "relative_path");
-               int save_copy= (RNA_struct_find_property(op->ptr, "copy") && RNA_boolean_get(op->ptr, "copy"));
+               Main *bmain= CTX_data_main(C);
+               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"));
+               short ok= FALSE;
+
+               BLI_path_abs(path, bmain->name);
+
+               WM_cursor_wait(1);
+
+               if(ima->type == IMA_TYPE_R_RESULT) {
+                       /* enforce user setting for RGB or RGBA, but skip BW */
+                       if(scene->r.planes==32) {
+                               ibuf->depth= 32;
+                       }
+                       else if(scene->r.planes==24) {
+                               ibuf->depth= 24;
+                       }
+               }
+               else {
+                       /* TODO, better solution, if a 24bit image is painted onto it may contain alpha */
+                       if(ibuf->userflags & IB_BITMAPDIRTY) { /* it has been painted onto */
+                               /* checks each pixel, not ideal */
+                               ibuf->depth= BKE_alphatest_ibuf(ibuf) ? 32 : 24;
+                       }
+               }
 
-               BLI_path_abs(path, G.sce);
-               
                if(scene->r.scemode & R_EXTENSION)  {
                        BKE_add_image_extension(path, sima->imtypenr);
                }
                
-               /* enforce user setting for RGB or RGBA, but skip BW */
-               if(scene->r.planes==32)
-                       ibuf->depth= 32;
-               else if(scene->r.planes==24)
-                       ibuf->depth= 24;
-               
-               WM_cursor_wait(1);
-
                if(sima->imtypenr==R_MULTILAYER) {
                        RenderResult *rr= BKE_image_acquire_renderresult(scene, ima);
                        if(rr) {
                                RE_WriteRenderResult(rr, path, scene->r.quality);
-
-                               if(relative)
-                                       BLI_path_rel(path, G.sce); /* only after saving */
-
-                               if(!save_copy) {
-                                       BLI_strncpy(ima->name, path, sizeof(ima->name));
-                                       BLI_strncpy(ibuf->name, path, sizeof(ibuf->name));
-
-                                       /* should be function? nevertheless, saving only happens here */
-                                       for(ibuf= ima->ibufs.first; ibuf; ibuf= ibuf->next)
-                                               ibuf->userflags &= ~IB_BITMAPDIRTY;
-                               }
+                               ok= TRUE;
                        }
-                       else
+                       else {
                                BKE_report(op->reports, RPT_ERROR, "Did not write, no Multilayer Image");
+                       }
                        BKE_image_release_renderresult(scene, ima);
                }
                else if (BKE_write_ibuf(scene, ibuf, path, sima->imtypenr, scene->r.subimtype, scene->r.quality)) {
+                       ok= TRUE;
+               }
 
+               if(ok)  {
                        if(relative)
-                               BLI_path_rel(path, G.sce); /* only after saving */
+                               BLI_path_rel(path, bmain->name); /* only after saving */
 
-                       if(!save_copy) {
-
-                               BLI_strncpy(ima->name, path, sizeof(ima->name));
+                       if(ibuf->name[0]==0) {
                                BLI_strncpy(ibuf->name, path, sizeof(ibuf->name));
+                               BLI_strncpy(ima->name, path, sizeof(ima->name));
+                       }
+
+                       if(!save_copy) {
+                               if(do_newpath) {
+                                       BLI_strncpy(ima->name, path, sizeof(ima->name));
+                                       BLI_strncpy(ibuf->name, path, sizeof(ibuf->name));
+                               }
 
                                ibuf->userflags &= ~IB_BITMAPDIRTY;
 
@@ -894,13 +952,12 @@ static void save_image_doit(bContext *C, SpaceImage *sima, Scene *scene, wmOpera
                                        ima->source= IMA_SRC_FILE;
                                        ima->type= IMA_TYPE_IMAGE;
                                }
-
-                               /* name image as how we saved it */
-                               rename_id(&ima->id, BLI_path_basename(path));
                        }
-               } 
-               else
+               }
+               else {
                        BKE_reportf(op->reports, RPT_ERROR, "Couldn't write image: %s", path);
+               }
+
 
                WM_event_add_notifier(C, NC_IMAGE|NA_EDITED, sima->image);
 
@@ -923,17 +980,31 @@ static int save_as_exec(bContext *C, wmOperator *op)
        sima->imtypenr= RNA_enum_get(op->ptr, "file_type");
        RNA_string_get(op->ptr, "filepath", str);
 
-       save_image_doit(C, sima, scene, op, str);
+       save_image_doit(C, sima, scene, op, str, TRUE);
 
        return OPERATOR_FINISHED;
 }
 
-static int save_as_invoke(bContext *C, wmOperator *op, wmEvent *event)
+
+static int save_as_check(bContext *UNUSED(C), wmOperator *op)
+{
+       char filepath[FILE_MAX];
+       RNA_string_get(op->ptr, "filepath", filepath);
+       if(BKE_add_image_extension(filepath, RNA_enum_get(op->ptr, "file_type"))) {
+               RNA_string_set(op->ptr, "filepath", filepath);
+               return TRUE;
+       }
+       return FALSE;
+}
+
+static int save_as_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
 {
        SpaceImage *sima= CTX_wm_space_image(C);
        Image *ima = ED_space_image(sima);
        Scene *scene= CTX_data_scene(C);
        ImBuf *ibuf;
+       char filename[FILE_MAX];
+       
        void *lock;
 
        if(!RNA_property_is_set(op->ptr, "relative_path"))
@@ -962,15 +1033,21 @@ static int save_as_invoke(bContext *C, wmOperator *op, wmEvent *event)
                RNA_enum_set(op->ptr, "file_type", sima->imtypenr);
                
                if(ibuf->name[0]==0)
-                       BLI_strncpy(ibuf->name, G.ima, FILE_MAX);
-
+                       if ( (G.ima[0] == '/') && (G.ima[1] == '/') && (G.ima[2] == '\0') ) {
+                               BLI_strncpy(filename, "//untitled", FILE_MAX);
+                       } else {
+                               BLI_strncpy(filename, G.ima, FILE_MAX);
+                       }
+               else
+                       BLI_strncpy(filename, ibuf->name, FILE_MAX);
+               
                /* enable save_copy by default for render results */
                if(ELEM(ima->type, IMA_TYPE_R_RESULT, IMA_TYPE_COMPOSITE) && !RNA_property_is_set(op->ptr, "copy")) {
                        RNA_boolean_set(op->ptr, "copy", TRUE);
                }
 
                // XXX note: we can give default menu enums to operator for this 
-               image_filesel(C, op, ibuf->name);
+               image_filesel(C, op, filename);
 
                ED_space_image_release_buffer(sima, lock);
                
@@ -990,6 +1067,7 @@ void IMAGE_OT_save_as(wmOperatorType *ot)
        
        /* api callbacks */
        ot->exec= save_as_exec;
+       ot->check= save_as_check;
        ot->invoke= save_as_invoke;
        ot->poll= space_image_buffer_exists_poll;
 
@@ -998,7 +1076,7 @@ void IMAGE_OT_save_as(wmOperatorType *ot)
 
        /* properties */
        RNA_def_enum(ot->srna, "file_type", image_file_type_items, R_PNG, "File Type", "File type to save image as.");
-       WM_operator_properties_filesel(ot, FOLDERFILE|IMAGEFILE|MOVIEFILE, FILE_SPECIAL, FILE_SAVE, FILE_RELPATH);
+       WM_operator_properties_filesel(ot, FOLDERFILE|IMAGEFILE|MOVIEFILE, FILE_SPECIAL, FILE_SAVE, WM_FILESEL_FILEPATH|WM_FILESEL_RELPATH);
 
        RNA_def_boolean(ot->srna, "copy", 0, "Copy", "Create a new image file without modifying the current image in blender");
 }
@@ -1007,6 +1085,7 @@ void IMAGE_OT_save_as(wmOperatorType *ot)
 
 static int save_exec(bContext *C, wmOperator *op)
 {
+       Main *bmain= CTX_data_main(C);
        SpaceImage *sima= CTX_wm_space_image(C);
        Image *ima = ED_space_image(sima);
        void *lock;
@@ -1022,9 +1101,11 @@ static int save_exec(bContext *C, wmOperator *op)
 
        /* if exists, saves over without fileselect */
        
-       BLI_strncpy(name, ibuf->name, FILE_MAX);
+       BLI_strncpy(name, ima->name, FILE_MAX);
        if(name[0]==0)
                BLI_strncpy(name, G.ima, FILE_MAX);
+       else
+               BLI_path_abs(name, bmain->name);
        
        if(BLI_exists(name) && BLI_is_writable(name)) {
                rr= BKE_image_acquire_renderresult(scene, ima);
@@ -1037,7 +1118,7 @@ static int save_exec(bContext *C, wmOperator *op)
                BKE_image_release_renderresult(scene, ima);
                ED_space_image_release_buffer(sima, lock);
                
-               save_image_doit(C, sima, scene, op, name);
+               save_image_doit(C, sima, scene, op, name, FALSE);
        }
        else {
                ED_space_image_release_buffer(sima, lock);
@@ -1067,6 +1148,7 @@ void IMAGE_OT_save(wmOperatorType *ot)
 
 static int save_sequence_exec(bContext *C, wmOperator *op)
 {
+       Main *bmain= CTX_data_main(C);
        SpaceImage *sima= CTX_wm_space_image(C);
        ImBuf *ibuf;
        int tot= 0;
@@ -1110,7 +1192,7 @@ static int save_sequence_exec(bContext *C, wmOperator *op)
                        char name[FILE_MAX];
                        BLI_strncpy(name, ibuf->name, sizeof(name));
                        
-                       BLI_path_abs(name, G.sce);
+                       BLI_path_abs(name, bmain->name);
 
                        if(0 == IMB_saveiff(ibuf, name, IB_rect | IB_zbuf | IB_zbuffloat)) {
                                BKE_reportf(op->reports, RPT_ERROR, "Could not write image %s.", name);
@@ -1141,7 +1223,7 @@ void IMAGE_OT_save_sequence(wmOperatorType *ot)
 
 /******************** reload image operator ********************/
 
-static int reload_exec(bContext *C, wmOperator *op)
+static int reload_exec(bContext *C, wmOperator *UNUSED(op))
 {
        Image *ima= CTX_data_edit_image(C);
        SpaceImage *sima= CTX_wm_space_image(C);
@@ -1172,7 +1254,7 @@ void IMAGE_OT_reload(wmOperatorType *ot)
 
 /********************** new image operator *********************/
 
-static int new_exec(bContext *C, wmOperator *op)
+static int image_new_exec(bContext *C, wmOperator *op)
 {
        SpaceImage *sima;
        Scene *scene;
@@ -1182,7 +1264,7 @@ static int new_exec(bContext *C, wmOperator *op)
        PropertyRNA *prop;
        char name[22];
        float color[4];
-       int width, height, floatbuf, uvtestgrid;
+       int width, height, floatbuf, uvtestgrid, alpha;
 
        /* retrieve state */
        sima= CTX_wm_space_image(C);
@@ -1195,12 +1277,15 @@ static int new_exec(bContext *C, wmOperator *op)
        floatbuf= RNA_boolean_get(op->ptr, "float");
        uvtestgrid= RNA_boolean_get(op->ptr, "uv_test_grid");
        RNA_float_get_array(op->ptr, "color", color);
-       color[3]= RNA_float_get(op->ptr, "alpha");
+       alpha= RNA_boolean_get(op->ptr, "alpha");
        
        if (!floatbuf && scene->r.color_mgt_flag & R_COLOR_MANAGEMENT)
                linearrgb_to_srgb_v3_v3(color, color);
 
-       ima = BKE_add_image_size(width, height, name, floatbuf, uvtestgrid, color);
+       if(!alpha)
+               color[3]= 1.0f;
+
+       ima = BKE_add_image_size(width, height, name, alpha ? 32 : 24, floatbuf, uvtestgrid, color);
 
        if(!ima)
                return OPERATOR_CANCELLED;
@@ -1226,25 +1311,36 @@ static int new_exec(bContext *C, wmOperator *op)
        return OPERATOR_FINISHED;
 }
 
+/* XXX, Ton is not a fan of OK buttons but using this function to avoid undo/redo bug while in mesh-editmode, - campbell */
+static int image_new_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+{
+       return WM_operator_props_dialog_popup(C, op, 300, 100);
+
+}
+
 void IMAGE_OT_new(wmOperatorType *ot)
 {
+       PropertyRNA *prop;
+       static float default_color[4]= {0.0f, 0.0f, 0.0f, 1.0f};
+       
        /* identifiers */
        ot->name= "New";
        ot->idname= "IMAGE_OT_new";
        
        /* api callbacks */
-       ot->exec= new_exec;
-       ot->invoke= WM_operator_props_popup;
-
+       ot->exec= image_new_exec;
+       ot->invoke= image_new_invoke;
+       
        /* flags */
        ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
 
        /* properties */
-       RNA_def_string(ot->srna, "name", "Untitled", 21, "Name", "Image datablock name.");
+       RNA_def_string(ot->srna, "name", "untitled", 21, "Name", "Image datablock name.");
        RNA_def_int(ot->srna, "width", 1024, 1, INT_MAX, "Width", "Image width.", 1, 16384);
        RNA_def_int(ot->srna, "height", 1024, 1, INT_MAX, "Height", "Image height.", 1, 16384);
-       RNA_def_float_color(ot->srna, "color", 3, NULL, 0.0f, FLT_MAX, "Color", "Default fill color.", 0.0f, 1.0f);
-       RNA_def_float(ot->srna, "alpha", 1.0f, 0.0f, 1.0f, "Alpha", "Default fill alpha.", 0.0f, 1.0f);
+       prop= RNA_def_float_color(ot->srna, "color", 4, NULL, 0.0f, FLT_MAX, "Color", "Default fill color.", 0.0f, 1.0f);
+       RNA_def_property_float_array_default(prop, default_color);
+       RNA_def_boolean(ot->srna, "alpha", 1, "Alpha", "Create an image with an alpha channel.");
        RNA_def_boolean(ot->srna, "uv_test_grid", 0, "UV Test Grid", "Fill the image with a grid for UV map testing.");
        RNA_def_boolean(ot->srna, "float", 0, "32 bit Float", "Create image with 32 bit floating point bit depth.");
 }
@@ -1262,7 +1358,7 @@ static int pack_test(bContext *C, wmOperator *op)
                return 0;
 
        if(ima->source==IMA_SRC_SEQUENCE || ima->source==IMA_SRC_MOVIE) {
-               BKE_report(op->reports, RPT_ERROR, "Can't pack movie or image sequence.");
+               BKE_report(op->reports, RPT_ERROR, "Packing movies or image sequences not supported.");
                return 0;
        }
 
@@ -1293,7 +1389,7 @@ static int pack_exec(bContext *C, wmOperator *op)
        return OPERATOR_FINISHED;
 }
 
-static int pack_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int pack_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
 {
        Image *ima= CTX_data_edit_image(C);
        ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL);
@@ -1439,7 +1535,7 @@ static int unpack_exec(bContext *C, wmOperator *op)
                return OPERATOR_CANCELLED;
 
        if(ima->source==IMA_SRC_SEQUENCE || ima->source==IMA_SRC_MOVIE) {
-               BKE_report(op->reports, RPT_ERROR, "Can't unpack movie or image sequence.");
+               BKE_report(op->reports, RPT_ERROR, "Unpacking movies or image sequences not supported.");
                return OPERATOR_CANCELLED;
        }
 
@@ -1453,7 +1549,7 @@ static int unpack_exec(bContext *C, wmOperator *op)
        return OPERATOR_FINISHED;
 }
 
-static int unpack_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int unpack_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
 {
        Image *ima= CTX_data_edit_image(C);
 
@@ -1464,7 +1560,7 @@ static int unpack_invoke(bContext *C, wmOperator *op, wmEvent *event)
                return OPERATOR_CANCELLED;
 
        if(ima->source==IMA_SRC_SEQUENCE || ima->source==IMA_SRC_MOVIE) {
-               BKE_report(op->reports, RPT_ERROR, "Can't unpack movie or image sequence.");
+               BKE_report(op->reports, RPT_ERROR, "Unpacking movies or image sequences not supported.");
                return OPERATOR_CANCELLED;
        }
 
@@ -1516,7 +1612,7 @@ typedef struct ImageSampleInfo {
        int draw;
 } ImageSampleInfo;
 
-static void sample_draw(const bContext *C, ARegion *ar, void *arg_info)
+static void sample_draw(const bContext *UNUSED(C), ARegion *ar, void *arg_info)
 {
        ImageSampleInfo *info= arg_info;
 
@@ -1532,16 +1628,16 @@ static void sample_apply(bContext *C, wmOperator *op, wmEvent *event)
        ImBuf *ibuf= ED_space_image_acquire_buffer(sima, &lock);
        ImageSampleInfo *info= op->customdata;
        float fx, fy;
-       int x, y;
+       int mx, my;
        
        if(ibuf == NULL) {
                ED_space_image_release_buffer(sima, lock);
                return;
        }
 
-       x= event->x - ar->winrct.xmin;
-       y= event->y - ar->winrct.ymin;
-       UI_view2d_region_to_view(&ar->v2d, x, y, &fx, &fy);
+       mx= event->x - ar->winrct.xmin;
+       my= event->y - ar->winrct.ymin;
+       UI_view2d_region_to_view(&ar->v2d, mx, my, &fx, &fy);
 
        if(fx>=0.0 && fy>=0.0 && fx<1.0 && fy<1.0) {
                float *fp;
@@ -1602,11 +1698,13 @@ static void sample_apply(bContext *C, wmOperator *op, wmEvent *event)
 
                                if(point == 1) {
                                        curvemapping_set_black_white(sima->cumap, NULL, info->colfp);
-                                       curvemapping_do_ibuf(sima->cumap, ibuf);
+                                       if(ibuf->rect_float)
+                                               curvemapping_do_ibuf(sima->cumap, ibuf);
                                }
                                else if(point == 0) {
                                        curvemapping_set_black_white(sima->cumap, info->colfp, NULL);
-                                       curvemapping_do_ibuf(sima->cumap, ibuf);
+                                       if(ibuf->rect_float)
+                                               curvemapping_do_ibuf(sima->cumap, ibuf);
                                }
                        }
                }
@@ -1929,7 +2027,7 @@ static int record_composite_exec(bContext *C, wmOperator *op)
        return OPERATOR_FINISHED;
 }
 
-static int record_composite_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int record_composite_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
 {
        RecordCompositeData *rcd= op->customdata;
        
@@ -1996,7 +2094,7 @@ static int cycle_render_slot_poll(bContext *C)
        return (ima && ima->type == IMA_TYPE_R_RESULT);
 }
 
-static int cycle_render_slot_exec(bContext *C, wmOperator *op)
+static int cycle_render_slot_exec(bContext *C, wmOperator *UNUSED(op))
 {
        Image *ima= CTX_data_edit_image(C);
        int a, slot, cur= ima->render_slot;
@@ -2008,6 +2106,10 @@ static int cycle_render_slot_exec(bContext *C, wmOperator *op)
                        ima->render_slot= slot;
                        break;
                }
+               else if((slot - 1) == ima->last_render_slot && slot < IMA_MAX_RENDER_SLOT) {
+                       ima->render_slot= slot;
+                       break;
+               }
        }
 
        if(a == IMA_MAX_RENDER_SLOT)
@@ -2038,10 +2140,10 @@ void IMAGE_OT_cycle_render_slot(wmOperatorType *ot)
 
 /* goes over all ImageUsers, and sets frame numbers if auto-refresh is set */
 
-void ED_image_update_frame(const bContext *C)
+void ED_image_update_frame(const Main *mainp, int cfra)
 {
-       Main *mainp = CTX_data_main(C);
-       Scene *scene= CTX_data_scene(C);
+       wmWindowManager *wm;
+       wmWindow *win;
        Tex *tex;
        
        /* texture users */
@@ -2049,46 +2151,45 @@ void ED_image_update_frame(const bContext *C)
                if(tex->type==TEX_IMAGE && tex->ima) {
                        if(ELEM(tex->ima->source, IMA_SRC_MOVIE, IMA_SRC_SEQUENCE)) {
                                if(tex->iuser.flag & IMA_ANIM_ALWAYS)
-                                       BKE_image_user_calc_frame(&tex->iuser, scene->r.cfra, 0);
+                                       BKE_image_user_calc_frame(&tex->iuser, cfra, 0);
                        }
                }
        }
        
-#if 0
        /* image window, compo node users */
-       if(G.curscreen) {
-               ScrArea *sa;
-               for(sa= G.curscreen->areabase.first; sa; sa= sa->next) {
-                       if(sa->spacetype==SPACE_VIEW3D) {
-                               View3D *v3d= sa->spacedata.first;
-                               if(v3d->bgpic)
-                                       if(v3d->bgpic->iuser.flag & IMA_ANIM_ALWAYS)
-                                               BKE_image_user_calc_frame(&v3d->bgpic->iuser, scene->r.cfra, 0);
-                       }
-                       else if(sa->spacetype==SPACE_IMAGE) {
-                               SpaceImage *sima= sa->spacedata.first;
-                               if(sima->iuser.flag & IMA_ANIM_ALWAYS)
-                                       BKE_image_user_calc_frame(&sima->iuser, scene->r.cfra, 0);
-                       }
-                       else if(sa->spacetype==SPACE_NODE) {
-                               SpaceNode *snode= sa->spacedata.first;
-                               if((snode->treetype==NTREE_COMPOSIT) && (snode->nodetree)) {
-                                       bNode *node;
-                                       for(node= snode->nodetree->nodes.first; node; node= node->next) {
-                                               if(node->id && node->type==CMP_NODE_IMAGE) {
-                                                       Image *ima= (Image *)node->id;
-                                                       ImageUser *iuser= node->storage;
-                                                       if(ELEM(ima->source, IMA_SRC_MOVIE, IMA_SRC_SEQUENCE))
-                                                               if(iuser->flag & IMA_ANIM_ALWAYS)
-                                                                       BKE_image_user_calc_frame(iuser, scene->r.cfra, 0);
+       for(wm=mainp->wm.first; wm; wm= wm->id.next) { /* only 1 wm */
+               for(win= wm->windows.first; win; win= win->next) {
+                       ScrArea *sa;
+                       for(sa= win->screen->areabase.first; sa; sa= sa->next) {
+                               if(sa->spacetype==SPACE_VIEW3D) {
+                                       View3D *v3d= sa->spacedata.first;
+                                       BGpic *bgpic;
+                                       for(bgpic= v3d->bgpicbase.first; bgpic; bgpic= bgpic->next)
+                                               if(bgpic->iuser.flag & IMA_ANIM_ALWAYS)
+                                                       BKE_image_user_calc_frame(&bgpic->iuser, cfra, 0);
+                               }
+                               else if(sa->spacetype==SPACE_IMAGE) {
+                                       SpaceImage *sima= sa->spacedata.first;
+                                       if(sima->iuser.flag & IMA_ANIM_ALWAYS)
+                                               BKE_image_user_calc_frame(&sima->iuser, cfra, 0);
+                               }
+                               else if(sa->spacetype==SPACE_NODE) {
+                                       SpaceNode *snode= sa->spacedata.first;
+                                       if((snode->treetype==NTREE_COMPOSIT) && (snode->nodetree)) {
+                                               bNode *node;
+                                               for(node= snode->nodetree->nodes.first; node; node= node->next) {
+                                                       if(node->id && node->type==CMP_NODE_IMAGE) {
+                                                               Image *ima= (Image *)node->id;
+                                                               ImageUser *iuser= node->storage;
+                                                               if(ELEM(ima->source, IMA_SRC_MOVIE, IMA_SRC_SEQUENCE))
+                                                                       if(iuser->flag & IMA_ANIM_ALWAYS)
+                                                                               BKE_image_user_calc_frame(iuser, cfra, 0);
+                                                       }
                                                }
                                        }
                                }
                        }
                }
        }
-#endif
 }
 
-
-