catch exception and report an error when failing to write exr files - was crashing with debug builds.
This commit is contained in:
		@@ -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)
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user