catch exception and report an error when failing to write exr files - was crashing with debug builds.

This commit is contained in:
Campbell Barton 2011-08-30 23:08:38 +00:00
parent 5ac81bfe9c
commit c58a0c5eb8
6 changed files with 46 additions and 19 deletions

@ -1069,7 +1069,7 @@ static void save_image_doit(bContext *C, SpaceImage *sima, wmOperator *op, SaveI
Scene *scene= CTX_data_scene(C); Scene *scene= CTX_data_scene(C);
RenderResult *rr= BKE_image_acquire_renderresult(scene, ima); RenderResult *rr= BKE_image_acquire_renderresult(scene, ima);
if(rr) { if(rr) {
RE_WriteRenderResult(rr, simopts->filepath, simopts->quality); RE_WriteRenderResult(op->reports, rr, simopts->filepath, simopts->quality);
ok= TRUE; ok= TRUE;
} }
else { else {

@ -487,7 +487,7 @@ void IMB_exr_add_channel(void *handle, const char *layname, const char *passname
} }
/* only used for writing temp. render results (not image files) */ /* only used for writing temp. render results (not image files) */
void IMB_exr_begin_write(void *handle, const char *filename, int width, int height, int compress) int IMB_exr_begin_write(void *handle, const char *filename, int width, int height, int compress)
{ {
ExrHandle *data= (ExrHandle *)handle; ExrHandle *data= (ExrHandle *)handle;
Header header (width, height); Header header (width, height);
@ -505,8 +505,17 @@ void IMB_exr_begin_write(void *handle, const char *filename, int width, int heig
header.insert ("BlenderMultiChannel", StringAttribute ("Blender V2.55.1 and newer")); header.insert ("BlenderMultiChannel", StringAttribute ("Blender V2.55.1 and newer"));
/* avoid crash/abort when we dont have permission to write here */
try {
data->ofile = new OutputFile(filename, header); data->ofile = new OutputFile(filename, header);
} }
catch (const std::exception &exc) {
std::cerr << "IMB_exr_begin_write: ERROR: " << exc.what() << std::endl;
data->ofile = NULL;
}
return (data->ofile != NULL);
}
void IMB_exrtile_begin_write(void *handle, const char *filename, int mipmap, int width, int height, int tilex, int tiley) void IMB_exrtile_begin_write(void *handle, const char *filename, int mipmap, int width, int height, int tilex, int tiley)
{ {

@ -50,7 +50,7 @@ void * IMB_exr_get_handle (void);
void IMB_exr_add_channel (void *handle, const char *layname, const char *passname, int xstride, int ystride, float *rect); void IMB_exr_add_channel (void *handle, const char *layname, const char *passname, int xstride, int ystride, float *rect);
int IMB_exr_begin_read (void *handle, const char *filename, int *width, int *height); int IMB_exr_begin_read (void *handle, const char *filename, int *width, int *height);
void IMB_exr_begin_write (void *handle, const char *filename, int width, int height, int compress); int IMB_exr_begin_write (void *handle, const char *filename, int width, int height, int compress);
void IMB_exrtile_begin_write (void *handle, const char *filename, int mipmap, int width, int height, int tilex, int tiley); void IMB_exrtile_begin_write (void *handle, const char *filename, int mipmap, int width, int height, int tilex, int tiley);
void IMB_exr_set_channel (void *handle, const char *layname, const char *passname, int xstride, int ystride, float *rect); void IMB_exr_set_channel (void *handle, const char *layname, const char *passname, int xstride, int ystride, float *rect);
@ -75,7 +75,7 @@ void * IMB_exr_get_handle (void) {return NULL;}
void IMB_exr_add_channel (void *handle, const char *layname, const char *channame, int xstride, int ystride, float *rect) { (void)handle; (void)layname; (void)channame; (void)xstride; (void)ystride; (void)rect; } void IMB_exr_add_channel (void *handle, const char *layname, const char *channame, int xstride, int ystride, float *rect) { (void)handle; (void)layname; (void)channame; (void)xstride; (void)ystride; (void)rect; }
int IMB_exr_begin_read (void *handle, const char *filename, int *width, int *height) { (void)handle; (void)filename; (void)width; (void)height; return 0;} int IMB_exr_begin_read (void *handle, const char *filename, int *width, int *height) { (void)handle; (void)filename; (void)width; (void)height; return 0;}
void IMB_exr_begin_write (void *handle, const char *filename, int width, int height, int compress) { (void)handle; (void)filename; (void)width; (void)height; (void)compress; } int IMB_exr_begin_write (void *handle, const char *filename, int width, int height, int compress) { (void)handle; (void)filename; (void)width; (void)height; (void)compress; return 0;}
void IMB_exrtile_begin_write (void *handle, const char *filename, int mipmap, int width, int height, int tilex, int tiley) { (void)handle; (void)filename; (void)mipmap; (void)width; (void)height; (void)tilex; (void)tiley; } void IMB_exrtile_begin_write (void *handle, const char *filename, int mipmap, int width, int height, int tilex, int tiley) { (void)handle; (void)filename; (void)mipmap; (void)width; (void)height; (void)tilex; (void)tiley; }
void IMB_exr_set_channel (void *handle, char *layname, const char *channame, int xstride, int ystride, float *rect) { (void)handle; (void)layname; (void)channame; (void)xstride; (void)ystride; (void)rect; } void IMB_exr_set_channel (void *handle, char *layname, const char *channame, int xstride, int ystride, float *rect) { (void)handle; (void)layname; (void)channame; (void)xstride; (void)ystride; (void)rect; }

@ -55,7 +55,6 @@ short IMB_saveiff(struct ImBuf *ibuf, const char *name, int flags)
if(ibuf->rect==NULL && ibuf->rect_float) if(ibuf->rect==NULL && ibuf->rect_float)
IMB_rect_from_float(ibuf); IMB_rect_from_float(ibuf);
} }
/* TODO. have const char for image write funcs */
return type->save(ibuf, name, flags); return type->save(ibuf, name, flags);
} }
} }

@ -227,8 +227,8 @@ void RE_SetReports(struct Render *re, struct ReportList *reports);
/* main preview render call */ /* main preview render call */
void RE_PreviewRender(struct Render *re, struct Main *bmain, struct Scene *scene); void RE_PreviewRender(struct Render *re, struct Main *bmain, struct Scene *scene);
void RE_ReadRenderResult(struct Scene *scene, struct Scene *scenode); int RE_ReadRenderResult(struct Scene *scene, struct Scene *scenode);
void RE_WriteRenderResult(RenderResult *rr, const char *filename, int compress); int RE_WriteRenderResult(struct ReportList *reports, RenderResult *rr, const char *filename, int compress);
struct RenderResult *RE_MultilayerConvert(void *exrhandle, int rectx, int recty); struct RenderResult *RE_MultilayerConvert(void *exrhandle, int rectx, int recty);
extern const float default_envmap_layout[]; extern const float default_envmap_layout[];

@ -824,11 +824,12 @@ static char *make_pass_name(RenderPass *rpass, int chan)
/* filename already made absolute */ /* filename already made absolute */
/* called from within UI, saves both rendered result as a file-read result */ /* called from within UI, saves both rendered result as a file-read result */
void RE_WriteRenderResult(RenderResult *rr, const char *filename, int compress) int RE_WriteRenderResult(ReportList *reports, RenderResult *rr, const char *filename, int compress)
{ {
RenderLayer *rl; RenderLayer *rl;
RenderPass *rpass; RenderPass *rpass;
void *exrhandle= IMB_exr_get_handle(); void *exrhandle= IMB_exr_get_handle();
int success;
BLI_make_existing_file(filename); BLI_make_existing_file(filename);
@ -865,10 +866,19 @@ void RE_WriteRenderResult(RenderResult *rr, const char *filename, int compress)
} }
} }
IMB_exr_begin_write(exrhandle, filename, rr->rectx, rr->recty, compress); /* when the filename has no permissions, this can fail */
if(IMB_exr_begin_write(exrhandle, filename, rr->rectx, rr->recty, compress)) {
IMB_exr_write_channels(exrhandle); IMB_exr_write_channels(exrhandle);
success= TRUE;
}
else {
/* TODO, get the error from openexr's exception */
BKE_report(reports, RPT_ERROR, "Error Writing Render Result, see console");
success= FALSE;
}
IMB_exr_close(exrhandle); IMB_exr_close(exrhandle);
return success;
} }
/* callbacks for RE_MultilayerConvert */ /* callbacks for RE_MultilayerConvert */
@ -992,9 +1002,10 @@ static int read_render_result_from_file(const char *filename, RenderResult *rr)
} }
/* only for temp buffer files, makes exact copy of render result */ /* only for temp buffer files, makes exact copy of render result */
static void read_render_result(Render *re, int sample) static int read_render_result(Render *re, int sample)
{ {
char str[FILE_MAX]; char str[FILE_MAX];
int success;
BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE); BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE);
@ -1004,10 +1015,18 @@ static void read_render_result(Render *re, int sample)
render_unique_exr_name(re, str, sample); render_unique_exr_name(re, str, sample);
printf("read exr tmp file: %s\n", str); printf("read exr tmp file: %s\n", str);
if(!read_render_result_from_file(str, re->result)) if(read_render_result_from_file(str, re->result)) {
success= TRUE;
}
else {
printf("cannot read: %s\n", str); printf("cannot read: %s\n", str);
success= FALSE;
}
BLI_rw_mutex_unlock(&re->resultmutex); BLI_rw_mutex_unlock(&re->resultmutex);
return success;
} }
/* *************************************************** */ /* *************************************************** */
@ -2981,7 +3000,7 @@ static int do_write_image_or_movie(Render *re, Scene *scene, bMovieHandle *mh, c
if(re->r.imtype==R_MULTILAYER) { if(re->r.imtype==R_MULTILAYER) {
if(re->result) { if(re->result) {
RE_WriteRenderResult(re->result, name, scene->r.quality); RE_WriteRenderResult(re->reports, re->result, name, scene->r.quality);
printf("Saved: %s", name); printf("Saved: %s", name);
} }
} }
@ -3198,7 +3217,7 @@ void RE_PreviewRender(Render *re, Main *bmain, Scene *sce)
/* note; repeated win/disprect calc... solve that nicer, also in compo */ /* note; repeated win/disprect calc... solve that nicer, also in compo */
/* only the temp file! */ /* only the temp file! */
void RE_ReadRenderResult(Scene *scene, Scene *scenode) int RE_ReadRenderResult(Scene *scene, Scene *scenode)
{ {
Render *re; Render *re;
int winx, winy; int winx, winy;
@ -3232,7 +3251,7 @@ void RE_ReadRenderResult(Scene *scene, Scene *scenode)
RE_InitState(re, NULL, &scene->r, NULL, winx, winy, &disprect); RE_InitState(re, NULL, &scene->r, NULL, winx, winy, &disprect);
re->scene= scene; re->scene= scene;
read_render_result(re, 0); return read_render_result(re, 0);
} }
void RE_set_max_threads(int threads) void RE_set_max_threads(int threads)