image save operator now shares settings and UI with render & image out node.

details:
- setting format options from python isnt possible anymore since this isnt exposed via op->properties, python should use image.save() function instead.
- image save UI now hides 'Relative' option when copy is selected since it has no effect.
- default image depth is set to 8 or more if the image has no float buffer, otherwise its set to 32 or less.

other fixes:
- image new was adding an image with a filepath set to "untitled", if this file happened to exist in the current directory a save on the generated image would overwrite it, now initialize to empty path.
- BKE_ftype_to_imtype was returning an invalid value if ftype==0.
This commit is contained in:
Campbell Barton 2011-11-21 23:56:32 +00:00
parent 30fd1ab523
commit da25b50ccb
15 changed files with 142 additions and 136 deletions

View File

@ -53,17 +53,17 @@ void BKE_stamp_buf(struct Scene *scene, struct Object *camera, unsigned char *re
int BKE_alphatest_ibuf(struct ImBuf *ibuf);
int BKE_write_ibuf_stamp(struct Scene *scene, struct Object *camera, struct ImBuf *ibuf, const char *name, struct ImageFormatData *imf);
int BKE_write_ibuf(struct ImBuf *ibuf, const char *name, struct ImageFormatData *imf);
void BKE_makepicstring(char *string, const char *base, const char *relbase, int frame, int imtype, const short use_ext, const short use_frames);
int BKE_add_image_extension(char *string, int imtype);
int BKE_ftype_to_imtype(int ftype);
int BKE_imtype_to_ftype(int imtype);
void BKE_makepicstring(char *string, const char *base, const char *relbase, int frame, char imtype, const short use_ext, const short use_frames);
int BKE_add_image_extension(char *string, const char imtype);
char BKE_ftype_to_imtype(const int ftype);
int BKE_imtype_to_ftype(char imtype);
int BKE_imtype_is_movie(int imtype);
int BKE_imtype_is_alpha_ok(int imtype);
int BKE_imtype_is_zbuf_ok(int imtype);
int BKE_imtype_is_compression_ok(int imtype);
int BKE_imtype_is_quality_ok(int imtype);
int BKE_imtype_is_depth_ok(int imtype);
int BKE_imtype_is_movie(const char imtype);
int BKE_imtype_is_alpha_ok(const char imtype);
int BKE_imtype_is_zbuf_ok(const char imtype);
int BKE_imtype_is_compression_ok(const char imtype);
int BKE_imtype_is_quality_ok(const char imtype);
char BKE_imtype_is_depth_ok(const char imtype);
struct anim *openanim(const char *name, int flags, int streamindex);

View File

@ -50,7 +50,7 @@ typedef struct bMovieHandle {
void (*get_movie_path)(char *string, struct RenderData *rd); /* optional */
} bMovieHandle;
bMovieHandle *BKE_get_movie_handle(int imtype);
bMovieHandle *BKE_get_movie_handle(const char imtype);
void BKE_makeanimstring(char *string, struct RenderData *rd);
#ifdef __cplusplus

View File

@ -556,13 +556,13 @@ Image *BKE_add_image_size(unsigned int width, unsigned int height, const char *n
if (ima) {
ImBuf *ibuf;
BLI_strncpy(ima->name, name, FILE_MAX);
/* BLI_strncpy(ima->name, name, FILE_MAX); */ /* dont do this, this writes in ain invalid filepath! */
ima->gen_x= width;
ima->gen_y= height;
ima->gen_type= uvtestgrid;
ima->gen_flag |= (floatbuf ? IMA_GEN_FLOAT : 0);
ibuf= add_ibuf_size(width, height, name, depth, floatbuf, uvtestgrid, color);
ibuf= add_ibuf_size(width, height, ima->name, depth, floatbuf, uvtestgrid, color);
image_assign_ibuf(ima, ibuf, IMA_NO_INDEX, 0);
ima->ok= IMA_OK_LOADED;
@ -800,7 +800,7 @@ void BKE_image_all_free_anim_ibufs(int cfra)
/* *********** READ AND WRITE ************** */
int BKE_imtype_to_ftype(int imtype)
int BKE_imtype_to_ftype(const char imtype)
{
if(imtype==R_TARGA)
return TGA;
@ -840,10 +840,10 @@ int BKE_imtype_to_ftype(int imtype)
return JPG|90;
}
int BKE_ftype_to_imtype(int ftype)
char BKE_ftype_to_imtype(const int ftype)
{
if(ftype==0)
return TGA;
return R_TARGA;
else if(ftype == IMAGIC)
return R_IRIS;
#ifdef WITH_HDR
@ -883,7 +883,7 @@ int BKE_ftype_to_imtype(int ftype)
}
int BKE_imtype_is_movie(int imtype)
int BKE_imtype_is_movie(const char imtype)
{
switch(imtype) {
case R_AVIRAW:
@ -900,7 +900,7 @@ int BKE_imtype_is_movie(int imtype)
return 0;
}
int BKE_imtype_is_alpha_ok(int imtype)
int BKE_imtype_is_alpha_ok(const char imtype)
{
switch(imtype) {
case R_TARGA:
@ -918,7 +918,7 @@ int BKE_imtype_is_alpha_ok(int imtype)
return 0;
}
int BKE_imtype_is_zbuf_ok(int imtype)
int BKE_imtype_is_zbuf_ok(const char imtype)
{
switch(imtype) {
case R_IRIZ:
@ -928,7 +928,7 @@ int BKE_imtype_is_zbuf_ok(int imtype)
return 0;
}
int BKE_imtype_is_compression_ok(int imtype)
int BKE_imtype_is_compression_ok(const char imtype)
{
switch(imtype) {
case R_PNG:
@ -937,7 +937,7 @@ int BKE_imtype_is_compression_ok(int imtype)
return 0;
}
int BKE_imtype_is_quality_ok(int imtype)
int BKE_imtype_is_quality_ok(const char imtype)
{
switch(imtype) {
case R_JPEG90:
@ -947,7 +947,7 @@ int BKE_imtype_is_quality_ok(int imtype)
return 0;
}
int BKE_imtype_is_depth_ok(int imtype)
char BKE_imtype_is_depth_ok(const char imtype)
{
switch (imtype) {
case R_RADHDR:
@ -970,7 +970,7 @@ int BKE_imtype_is_depth_ok(int imtype)
}
}
int BKE_add_image_extension(char *string, int imtype)
int BKE_add_image_extension(char *string, const char imtype)
{
const char *extension= NULL;
@ -1557,7 +1557,7 @@ int BKE_write_ibuf_stamp(Scene *scene, struct Object *camera, ImBuf *ibuf, const
}
void BKE_makepicstring(char *string, const char *base, const char *relbase, int frame, int imtype, const short use_ext, const short use_frames)
void BKE_makepicstring(char *string, const char *base, const char *relbase, int frame, const char imtype, const short use_ext, const short use_frames)
{
if (string==NULL) return;
BLI_strncpy(string, base, FILE_MAX - 10); /* weak assumption */

View File

@ -67,7 +67,7 @@ static void filepath_avi(char *string, RenderData *rd);
#include "BKE_writeframeserver.h"
bMovieHandle *BKE_get_movie_handle(int imtype)
bMovieHandle *BKE_get_movie_handle(const char imtype)
{
static bMovieHandle mh;

View File

@ -515,7 +515,7 @@ uiBut *uiDefHotKeyevtButS(uiBlock *block, int retval, const char *str, int x1, i
uiBut *uiDefSearchBut(uiBlock *block, void *arg, int retval, int icon, int maxlen, int x1, int y1, short x2, short y2, float a1, float a2, const char *tip);
uiBut *uiDefAutoButR(uiBlock *block, struct PointerRNA *ptr, struct PropertyRNA *prop, int index, const char *name, int icon, int x1, int y1, int x2, int y2);
int uiDefAutoButsRNA(uiLayout *layout, struct PointerRNA *ptr, int (*check_prop)(struct PropertyRNA *), const char label_align);
int uiDefAutoButsRNA(uiLayout *layout, struct PointerRNA *ptr, int (*check_prop)(struct PointerRNA *, struct PropertyRNA *), const char label_align);
/* Links
*
@ -688,7 +688,7 @@ uiBlock *uiLayoutGetBlock(uiLayout *layout);
void uiLayoutSetFunc(uiLayout *layout, uiMenuHandleFunc handlefunc, void *argv);
void uiLayoutSetContextPointer(uiLayout *layout, const char *name, struct PointerRNA *ptr);
const char *uiLayoutIntrospect(uiLayout *layout); // XXX - testing
void uiLayoutOperatorButs(const struct bContext *C, struct uiLayout *layout, struct wmOperator *op, int (*check_prop)(struct PropertyRNA *), const char label_align, const short flag);
void uiLayoutOperatorButs(const struct bContext *C, struct uiLayout *layout, struct wmOperator *op, int (*check_prop)(struct PointerRNA *, struct PropertyRNA *), const char label_align, const short flag);
struct MenuType *uiButGetMenuType(uiBut *but);
void uiLayoutSetOperatorContext(uiLayout *layout, int opcontext);

View File

@ -2743,7 +2743,7 @@ const char *uiLayoutIntrospect(uiLayout *layout)
}
/* this function does not initialize the layout, functions can be called on the layout before and after */
void uiLayoutOperatorButs(const bContext *C, uiLayout *layout, wmOperator *op,int (*check_prop)(struct PropertyRNA *), const char label_align, const short flag)
void uiLayoutOperatorButs(const bContext *C, uiLayout *layout, wmOperator *op,int (*check_prop)(struct PointerRNA *, struct PropertyRNA *), const char label_align, const short flag)
{
if(!op->properties) {
IDPropertyTemplate val = {0};

View File

@ -130,7 +130,7 @@ uiBut *uiDefAutoButR(uiBlock *block, PointerRNA *ptr, PropertyRNA *prop, int ind
return but;
}
int uiDefAutoButsRNA(uiLayout *layout, PointerRNA *ptr, int (*check_prop)(PropertyRNA *), const char label_align)
int uiDefAutoButsRNA(uiLayout *layout, PointerRNA *ptr, int (*check_prop)(PointerRNA *, PropertyRNA *), const char label_align)
{
uiLayout *split, *col;
int flag;
@ -141,7 +141,7 @@ int uiDefAutoButsRNA(uiLayout *layout, PointerRNA *ptr, int (*check_prop)(Proper
RNA_STRUCT_BEGIN(ptr, prop) {
flag= RNA_property_flag(prop);
if(flag & PROP_HIDDEN || (check_prop && check_prop(prop)==FALSE))
if(flag & PROP_HIDDEN || (check_prop && check_prop(ptr, prop)==FALSE))
continue;
if(label_align != '\0') {

View File

@ -658,7 +658,7 @@ void TEXTURE_OT_slot_move(wmOperatorType *ot)
/********************** environment map operators *********************/
static int save_envmap(wmOperator *op, Scene *scene, EnvMap *env, char *path, int imtype)
static int save_envmap(wmOperator *op, Scene *scene, EnvMap *env, char *path, const char imtype)
{
float layout[12];
if ( RNA_struct_find_property(op->ptr, "layout") )
@ -680,7 +680,7 @@ static int envmap_save_exec(bContext *C, wmOperator *op)
Tex *tex= CTX_data_pointer_get_type(C, "texture", &RNA_Texture).data;
Scene *scene = CTX_data_scene(C);
//int imtype = RNA_enum_get(op->ptr, "file_type");
int imtype = scene->r.im_format.imtype;
char imtype = scene->r.im_format.imtype;
char path[FILE_MAX];
RNA_string_get(op->ptr, "filepath", path);

View File

@ -265,7 +265,7 @@ static int sound_mixdown_invoke(bContext *C, wmOperator *op, wmEvent *event)
return WM_operator_filesel(C, op, event);
}
static int sound_mixdown_draw_check_prop(PropertyRNA *prop)
static int sound_mixdown_draw_check_prop(PointerRNA *UNUSED(ptr), PropertyRNA *prop)
{
const char *prop_id= RNA_property_identifier(prop);
return !( strcmp(prop_id, "filepath") == 0 ||

View File

@ -177,7 +177,7 @@ static void file_panel_operator_header(const bContext *C, Panel *pa)
BLI_strncpy(pa->drawname, op->type->name, sizeof(pa->drawname));
}
static int file_panel_check_prop(PropertyRNA *prop)
static int file_panel_check_prop(PointerRNA *UNUSED(ptr), PropertyRNA *prop)
{
const char *prop_id= RNA_property_identifier(prop);
return !( strcmp(prop_id, "filepath") == 0 ||

View File

@ -707,40 +707,6 @@ void IMAGE_OT_view_zoom_ratio(wmOperatorType *ot)
}
/**************** load/replace/save callbacks ******************/
/* XXX make dynamic */
static const EnumPropertyItem image_file_type_items[] = {
{R_TARGA, "TARGA", 0, "Targa", ""},
{R_RAWTGA, "TARGA RAW", 0, "Targa Raw", ""},
{R_PNG, "PNG", 0, "PNG", ""},
#ifdef WITH_DDS
{R_DDS, "DDS", 0, "DirectDraw Surface", ""},
#endif
{R_BMP, "BMP", 0, "BMP", ""},
{R_JPEG90, "JPEG", 0, "Jpeg", ""},
#ifdef WITH_OPENJPEG
{R_JP2, "JPEG_2000", 0, "Jpeg 2000", ""},
#endif
{R_IRIS, "IRIS", 0, "Iris", ""},
#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 */
/*if(ima->source==IMA_SRC_SEQUENCE && ima->type==IMA_TYPE_MULTILAYER);
else*/
{R_MULTILAYER, "MULTILAYER", 0, "MultiLayer", ""},
#endif
{0, NULL, 0, NULL, NULL}};
static void image_filesel(bContext *C, wmOperator *op, const char *path)
{
RNA_string_set(op->ptr, "filepath", path);
@ -943,19 +909,42 @@ void IMAGE_OT_replace(wmOperatorType *ot)
typedef struct {
/* matching scene->r settings */
short planes, imtype, subimtype, quality;
//short planes, imtype, subimtype, quality;
ImageFormatData im_format;
char filepath[FILE_MAX]; /* keep absolute */
} SaveImageOptions;
static void save_image_options_defaults(SaveImageOptions *simopts)
{
simopts->planes= R_IMF_PLANES_RGB;
simopts->imtype= R_PNG;
simopts->subimtype= 0;
simopts->quality= 90;
memset(&simopts->im_format, 0, sizeof(simopts->im_format));
simopts->im_format.planes= R_IMF_PLANES_RGB;
simopts->im_format.imtype= R_PNG;
simopts->im_format.quality= 90;
simopts->im_format.compress= 90;
simopts->filepath[0]= '\0';
}
static char imtype_best_depth(ImBuf *ibuf, const char imtype)
{
const char depth_ok= BKE_imtype_is_depth_ok(imtype);
if (ibuf->rect_float) {
if (depth_ok & R_IMF_CHAN_DEPTH_32) return R_IMF_CHAN_DEPTH_32;
if (depth_ok & R_IMF_CHAN_DEPTH_24) return R_IMF_CHAN_DEPTH_24;
if (depth_ok & R_IMF_CHAN_DEPTH_16) return R_IMF_CHAN_DEPTH_16;
if (depth_ok & R_IMF_CHAN_DEPTH_12) return R_IMF_CHAN_DEPTH_12;
return R_IMF_CHAN_DEPTH_8;
}
else {
if (depth_ok & R_IMF_CHAN_DEPTH_8) return R_IMF_CHAN_DEPTH_8;
if (depth_ok & R_IMF_CHAN_DEPTH_12) return R_IMF_CHAN_DEPTH_12;
if (depth_ok & R_IMF_CHAN_DEPTH_16) return R_IMF_CHAN_DEPTH_16;
if (depth_ok & R_IMF_CHAN_DEPTH_24) return R_IMF_CHAN_DEPTH_24;
if (depth_ok & R_IMF_CHAN_DEPTH_32) return R_IMF_CHAN_DEPTH_32;
return R_IMF_CHAN_DEPTH_8; /* fallback, should not get here */
}
}
static int save_image_options_init(SaveImageOptions *simopts, SpaceImage *sima, Scene *scene, const short guess_path)
{
void *lock;
@ -963,34 +952,41 @@ static int save_image_options_init(SaveImageOptions *simopts, SpaceImage *sima,
if(ibuf) {
Image *ima= sima->image;
short is_depth_set= FALSE;
simopts->planes= ibuf->planes;
simopts->im_format.planes= ibuf->planes;
if(ELEM(ima->type, IMA_TYPE_R_RESULT, IMA_TYPE_COMPOSITE)) {
simopts->imtype= scene->r.im_format.imtype;
simopts->planes= scene->r.im_format.planes;
/* imtype */
simopts->im_format= scene->r.im_format;
is_depth_set= TRUE;
}
else if (ima->source == IMA_SRC_GENERATED) {
simopts->imtype= R_PNG;
simopts->im_format.imtype= R_PNG;
}
else {
simopts->imtype= BKE_ftype_to_imtype(ibuf->ftype);
simopts->im_format.imtype= BKE_ftype_to_imtype(ibuf->ftype);
}
//simopts->subimtype= scene->r.subimtype; /* XXX - this is lame, we need to make these available too! */
simopts->quality= ibuf->ftype & 0xff;
simopts->im_format.quality= ibuf->ftype & 0xff;
BLI_strncpy(simopts->filepath, ibuf->name, sizeof(simopts->filepath));
/* sanitize all settings */
/* unlikely but just incase */
if (ELEM3(simopts->planes, R_IMF_PLANES_BW, R_IMF_PLANES_RGB, R_IMF_PLANES_RGBA) == 0) {
simopts->planes= R_IMF_PLANES_RGBA;
if (ELEM3(simopts->im_format.planes, R_IMF_PLANES_BW, R_IMF_PLANES_RGB, R_IMF_PLANES_RGBA) == 0) {
simopts->im_format.planes= R_IMF_PLANES_RGBA;
}
/* depth, account for float buffer and format support */
if (is_depth_set == FALSE) {
simopts->im_format.depth= imtype_best_depth(ibuf, simopts->im_format.imtype);
}
/* some formats dont use quality so fallback to scenes quality */
if (simopts->quality == 0) {
simopts->quality= scene->r.im_format.quality;
if (simopts->im_format.quality == 0) {
simopts->im_format.quality= scene->r.im_format.quality;
}
/* check for empty path */
@ -1009,19 +1005,11 @@ static int save_image_options_init(SaveImageOptions *simopts, SpaceImage *sima,
return (ibuf != NULL);
}
static void save_image_options_from_op(SaveImageOptions *simopts, wmOperator *op, Scene *evil_scene)
static void save_image_options_from_op(SaveImageOptions *simopts, wmOperator *op)
{
if (RNA_property_is_set(op->ptr, "color_mode")) simopts->planes= RNA_enum_get(op->ptr, "color_mode");
if (RNA_property_is_set(op->ptr, "file_format")) simopts->imtype= RNA_enum_get(op->ptr, "file_format");
#if 0
if (RNA_property_is_set(op->ptr, "subimtype")) simopts->subimtype= RNA_enum_get(op->ptr, "subimtype"); // XXX
#else
// simopts->subimtype= evil_scene->r.subimtype;
(void)evil_scene;
#endif
if (RNA_property_is_set(op->ptr, "file_quality")) simopts->quality= RNA_int_get(op->ptr, "file_quality");
if (op->customdata) {
simopts->im_format= *(ImageFormatData *)op->customdata;
}
if (RNA_property_is_set(op->ptr, "filepath")) {
RNA_string_get(op->ptr, "filepath", simopts->filepath);
@ -1031,10 +1019,9 @@ static void save_image_options_from_op(SaveImageOptions *simopts, wmOperator *op
static void save_image_options_to_op(SaveImageOptions *simopts, wmOperator *op)
{
RNA_enum_set(op->ptr, "color_mode", simopts->planes);
RNA_enum_set(op->ptr, "file_format", simopts->imtype);
// RNA_enum_set(op->ptr, "subimtype", simopts->subimtype);
RNA_int_set(op->ptr, "file_quality", simopts->quality);
if (op->customdata) {
*(ImageFormatData *)op->customdata= simopts->im_format;
}
RNA_string_set(op->ptr, "filepath", simopts->filepath);
}
@ -1060,10 +1047,10 @@ static void save_image_doit(bContext *C, SpaceImage *sima, wmOperator *op, SaveI
if(ima->type == IMA_TYPE_R_RESULT) {
/* enforce user setting for RGB or RGBA, but skip BW */
if(simopts->planes==R_IMF_PLANES_RGBA) {
if(simopts->im_format.planes==R_IMF_PLANES_RGBA) {
ibuf->planes= R_IMF_PLANES_RGBA;
}
else if(simopts->planes==R_IMF_PLANES_RGB) {
else if(simopts->im_format.planes==R_IMF_PLANES_RGB) {
ibuf->planes= R_IMF_PLANES_RGB;
}
}
@ -1075,11 +1062,11 @@ static void save_image_doit(bContext *C, SpaceImage *sima, wmOperator *op, SaveI
}
}
if(simopts->imtype==R_MULTILAYER) {
if(simopts->im_format.imtype==R_MULTILAYER) {
Scene *scene= CTX_data_scene(C);
RenderResult *rr= BKE_image_acquire_renderresult(scene, ima);
if(rr) {
RE_WriteRenderResult(op->reports, rr, simopts->filepath, simopts->quality);
RE_WriteRenderResult(op->reports, rr, simopts->filepath, simopts->im_format.quality);
ok= TRUE;
}
else {
@ -1088,15 +1075,7 @@ static void save_image_doit(bContext *C, SpaceImage *sima, wmOperator *op, SaveI
BKE_image_release_renderresult(scene, ima);
}
else {
ImageFormatData imf= {0};
/* todo, make operator use template, this works for now */
imf.imtype= simopts->imtype;
imf.quality= simopts->quality;
imf.compress= simopts->quality;
imf.depth= R_IMF_CHAN_DEPTH_8;
if (BKE_write_ibuf(ibuf, simopts->filepath, &imf)) {
if (BKE_write_ibuf(ibuf, simopts->filepath, &simopts->im_format)) {
ok= TRUE;
}
}
@ -1150,27 +1129,40 @@ static void save_image_doit(bContext *C, SpaceImage *sima, wmOperator *op, SaveI
ED_space_image_release_buffer(sima, lock);
}
static void image_save_as_free(wmOperator *op)
{
if (op->customdata) {
MEM_freeN(op->customdata);
op->customdata= NULL;
}
}
static int image_save_as_exec(bContext *C, wmOperator *op)
{
SpaceImage *sima= CTX_wm_space_image(C);
SaveImageOptions simopts;
save_image_options_defaults(&simopts);
/* just incase to initialize values,
* these should be set on invoke or by the caller. */
save_image_options_defaults(&simopts);
save_image_options_from_op(&simopts, op, CTX_data_scene(C));
save_image_options_init(&simopts, sima, CTX_data_scene(C), 0);
save_image_options_from_op(&simopts, op);
save_image_doit(C, sima, op, &simopts, TRUE);
image_save_as_free(op);
return OPERATOR_FINISHED;
}
static int image_save_as_check(bContext *UNUSED(C), wmOperator *op)
{
ImageFormatData *imf= op->customdata;
char filepath[FILE_MAX];
RNA_string_get(op->ptr, "filepath", filepath);
if(BKE_add_image_extension(filepath, RNA_enum_get(op->ptr, "file_format"))) {
if(BKE_add_image_extension(filepath, imf->imtype)) {
RNA_string_set(op->ptr, "filepath", filepath);
return TRUE;
}
@ -1196,15 +1188,36 @@ static int image_save_as_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(eve
RNA_boolean_set(op->ptr, "copy", TRUE);
}
// XXX note: we can give default menu enums to operator for this
op->customdata= MEM_mallocN(sizeof(simopts.im_format), __func__);
memcpy(op->customdata, &simopts.im_format, sizeof(simopts.im_format));
image_filesel(C, op, simopts.filepath);
return OPERATOR_RUNNING_MODAL;
}
#if 0
static void image_save_as_draw(bContext *C, wmOperator *op)
static int image_save_as_cancel(bContext *UNUSED(C), wmOperator *op)
{
image_save_as_free(op);
return OPERATOR_CANCELLED;
}
static int image_save_as_draw_check_prop(PointerRNA *ptr, PropertyRNA *prop)
{
const char *prop_id= RNA_property_identifier(prop);
return !(strcmp(prop_id, "filepath") == 0 ||
strcmp(prop_id, "directory") == 0 ||
strcmp(prop_id, "filename") == 0 ||
/* when saving a copy, relative path has no effect */
((strcmp(prop_id, "relative_path") == 0) && RNA_boolean_get(ptr, "copy"))
);
}
static void image_save_as_draw(bContext *UNUSED(C), wmOperator *op)
{
uiLayout *layout= op->layout;
ImageFormatData *imf= op->customdata;
PointerRNA ptr;
@ -1213,14 +1226,13 @@ static void image_save_as_draw(bContext *C, wmOperator *op)
uiTemplateImageSettings(layout, &ptr);
/* main draw call */
RNA_pointer_create(&wm->id, op->type->srna, op->properties, &ptr);
uiDefAutoButsRNA(layout, &ptr, NULL, '\0');
RNA_pointer_create(NULL, op->type->srna, op->properties, &ptr);
uiDefAutoButsRNA(layout, &ptr, image_save_as_draw_check_prop, '\0');
}
#endif
void IMAGE_OT_save_as(wmOperatorType *ot)
{
PropertyRNA *prop;
// PropertyRNA *prop;
/* identifiers */
ot->name= "Save As Image";
@ -1230,23 +1242,17 @@ void IMAGE_OT_save_as(wmOperatorType *ot)
ot->exec= image_save_as_exec;
ot->check= image_save_as_check;
ot->invoke= image_save_as_invoke;
// ot->ui= image_save_as_draw;
ot->cancel= image_save_as_cancel;
ot->ui= image_save_as_draw;
ot->poll= space_image_buffer_exists_poll;
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
/* properties */
/* format options */
RNA_def_enum(ot->srna, "file_format", image_file_type_items, R_PNG, "File Type", "File type to save image as");
RNA_def_enum(ot->srna, "color_mode", image_color_mode_items, R_IMF_PLANES_RGB, "Channels", "Image channels to save");
prop= RNA_def_int(ot->srna, "file_quality", 90, 0, 100, "Quality", "", 0, 100);
RNA_def_property_subtype(prop, PROP_PERCENTAGE);
RNA_def_boolean(ot->srna, "copy", 0, "Copy", "Create a new image file without modifying the current image in blender");
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");
}
/******************** save image operator ********************/
@ -1259,7 +1265,7 @@ static int image_save_exec(bContext *C, wmOperator *op)
if (save_image_options_init(&simopts, sima, scene, FALSE) == 0)
return OPERATOR_CANCELLED;
save_image_options_from_op(&simopts, op, scene);
save_image_options_from_op(&simopts, op);
if (BLI_exists(simopts.filepath) && BLI_file_is_writable(simopts.filepath)) {
save_image_doit(C, sima, op, &simopts, FALSE);

View File

@ -2488,7 +2488,7 @@ static void rna_def_scene_image_format_data(BlenderRNA *brna)
RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL);
prop= RNA_def_property(srna, "use_jpeg2k_cinema_48", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "jp2_flag", R_IMF_JP2_FLAG_CINE_PRESET);
RNA_def_property_boolean_sdna(prop, NULL, "jp2_flag", R_IMF_JP2_FLAG_CINE_48);
RNA_def_property_ui_text(prop, "Cinema (48)", "Use Openjpeg Cinema Preset (48fps)");
RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL);
#endif

View File

@ -227,7 +227,7 @@ int RE_WriteRenderResult(struct ReportList *reports, RenderResult *rr, const cha
struct RenderResult *RE_MultilayerConvert(void *exrhandle, int rectx, int recty);
extern const float default_envmap_layout[];
int RE_WriteEnvmapResult(struct ReportList *reports, struct Scene *scene, struct EnvMap *env, const char *relpath, int imtype, float layout[12]);
int RE_WriteEnvmapResult(struct ReportList *reports, struct Scene *scene, struct EnvMap *env, const char *relpath, const char imtype, float layout[12]);
/* do a full sample buffer compo */
void RE_MergeFullSample(struct Render *re, struct Main *bmain, struct Scene *sce, struct bNodeTree *ntree);

View File

@ -3343,7 +3343,7 @@ void RE_result_load_from_file(RenderResult *result, ReportList *reports, const c
const float default_envmap_layout[] = { 0,0, 1,0, 2,0, 0,1, 1,1, 2,1 };
int RE_WriteEnvmapResult(struct ReportList *reports, Scene *scene, EnvMap *env, const char *relpath, int imtype, float layout[12])
int RE_WriteEnvmapResult(struct ReportList *reports, Scene *scene, EnvMap *env, const char *relpath, const char imtype, float layout[12])
{
ImageFormatData imf;
ImBuf *ibuf=NULL;

View File

@ -154,7 +154,7 @@ double elbeemEstimateMemreq(int res, float sx, float sy, float sz, int refine, c
struct Render *RE_NewRender(const char *name){return (struct Render*) NULL;}
void RE_SwapResult(struct Render *re, struct RenderResult **rr){}
void RE_BlenderFrame(struct Render *re, struct Scene *scene, int frame){}
int RE_WriteEnvmapResult(struct ReportList *reports, struct Scene *scene, struct EnvMap *env, const char *relpath, int imtype, float layout[12]) { return 0; }
int RE_WriteEnvmapResult(struct ReportList *reports, struct Scene *scene, struct EnvMap *env, const char *relpath, const char imtype, float layout[12]) { return 0; }
/* rna */
float *give_cursor(struct Scene *scene, struct View3D *v3d){return (float *) NULL;}