[Bf-blender-cvs] [876bc2b] multiview: Compositor: final fix for access-memory after freed - note: valgrind caught this while asan did not

Dalai Felinto noreply at git.blender.org
Wed Sep 17 15:42:35 CEST 2014


Commit: 876bc2b9470f2e4f0a8fabb8b9576c31c9eb40ba
Author: Dalai Felinto
Date:   Wed Sep 17 15:42:36 2014 +0200
Branches: multiview
https://developer.blender.org/rB876bc2b9470f2e4f0a8fabb8b9576c31c9eb40ba

Compositor: final fix for access-memory after freed - note: valgrind caught this while asan did not

===================================================================

M	source/blender/compositor/operations/COM_OutputFileMultiViewOperation.cpp
M	source/blender/compositor/operations/COM_OutputFileOperation.cpp
M	source/blender/compositor/operations/COM_OutputFileOperation.h

===================================================================

diff --git a/source/blender/compositor/operations/COM_OutputFileMultiViewOperation.cpp b/source/blender/compositor/operations/COM_OutputFileMultiViewOperation.cpp
index d37c341..c9e802b 100644
--- a/source/blender/compositor/operations/COM_OutputFileMultiViewOperation.cpp
+++ b/source/blender/compositor/operations/COM_OutputFileMultiViewOperation.cpp
@@ -110,15 +110,18 @@ void OutputOpenExrSingleLayerMultiViewOperation::deinitExecution()
 		exrhandle = this->get_handle(filename);
 		add_exr_channels(exrhandle, NULL, this->m_datatype, this->m_viewName, width, this->m_outputBuffer);
 
-		if (this->m_outputBuffer)
-			MEM_freeN(this->m_outputBuffer);
-
+		/* memory can only be freed after we write all views to the file */
 		this->m_outputBuffer = NULL;
 		this->m_imageInput = NULL;
 
 		/* ready to close the file */
 		if (BKE_scene_render_view_last(this->m_rd, this->m_viewName)) {
 			IMB_exr_write_channels(exrhandle);
+
+			/* free buffer memory for all the views */
+			free_exr_channels(exrhandle, this->m_rd, NULL, this->m_datatype);
+
+			/* remove exr handle and data */
 			IMB_exr_close(exrhandle);
 		}
 	}
@@ -196,17 +199,20 @@ void OutputOpenExrMultiLayerMultiViewOperation::deinitExecution()
 			add_exr_channels(exrhandle, this->m_layers[i].name, this->m_layers[i].datatype, this->m_viewName, width, this->m_layers[i].outputBuffer);
 
 		for (unsigned int i = 0; i < this->m_layers.size(); ++i) {
-			if (this->m_layers[i].outputBuffer) {
-				MEM_freeN(this->m_layers[i].outputBuffer);
-				this->m_layers[i].outputBuffer = NULL;
-			}
-			
+			/* memory can only be freed after we write all views to the file */
+			this->m_layers[i].outputBuffer = NULL;
 			this->m_layers[i].imageInput = NULL;
 		}
 
 		/* ready to close the file */
 		if (BKE_scene_render_view_last(this->m_rd, this->m_viewName)) {
 			IMB_exr_write_channels(exrhandle);
+
+			/* free buffer memory for all the views */
+			for (unsigned int i = 0; i < this->m_layers.size(); ++i) {
+				free_exr_channels(exrhandle, this->m_rd, this->m_layers[i].name, this->m_layers[i].datatype);
+			}
+
 			IMB_exr_close(exrhandle);
 		}
 	}
@@ -242,9 +248,8 @@ void *OutputStereoOperation::get_handle(const char* filename)
 
 		IMB_exr_clear_channels(exrhandle);
 
-		for (i = 0; i < 2; i++) {
+		for (i = 0; i < 2; i++)
 			IMB_exr_add_view(exrhandle, names[i]);
-		}
 
 		return exrhandle;
 	}
@@ -300,11 +305,10 @@ void OutputStereoOperation::deinitExecution()
 
 			BKE_imbuf_write(ibuf[2], filename, this->m_format);
 
-			/* cleanup */
 			/* imbuf knows which rects are not part of ibuf */
-			for (i = 0; i < 3; i++) {
+			for (i = 0; i < 3; i++)
 				IMB_freeImBuf(ibuf[i]);
-			}
+
 			IMB_exr_close(exrhandle);
 		}
 	}
diff --git a/source/blender/compositor/operations/COM_OutputFileOperation.cpp b/source/blender/compositor/operations/COM_OutputFileOperation.cpp
index 1528146..f411b8e 100644
--- a/source/blender/compositor/operations/COM_OutputFileOperation.cpp
+++ b/source/blender/compositor/operations/COM_OutputFileOperation.cpp
@@ -63,6 +63,36 @@ void add_exr_channels(void *exrhandle, const char *layerName, const DataType dat
 	}
 }
 
+void free_exr_channels(void *exrhandle, const RenderData *rd, const char *layerName, const DataType datatype)
+{
+	SceneRenderView *srv;
+
+	/* check renderdata for amount of views */
+	for (srv = (SceneRenderView *) rd->views.first; srv; srv = srv->next) {
+		float *rect = NULL;
+
+		if (BKE_scene_render_view_active(rd, srv) == false)
+			continue;
+
+		/* the pointer is stored in the first channel of each datatype */
+		switch (datatype) {
+			case COM_DT_VALUE:
+				rect = IMB_exr_channel_rect(exrhandle, layerName, "V", srv->name);
+				break;
+			case COM_DT_VECTOR:
+				rect = IMB_exr_channel_rect(exrhandle, layerName, "X", srv->name);
+				break;
+			case COM_DT_COLOR:
+				rect = IMB_exr_channel_rect(exrhandle, layerName, "R", srv->name);
+				break;
+			default:
+				break;
+		}
+		if (rect)
+			MEM_freeN(rect);
+	}
+}
+
 int get_datatype_size(DataType datatype)
 {
 	switch (datatype) {
diff --git a/source/blender/compositor/operations/COM_OutputFileOperation.h b/source/blender/compositor/operations/COM_OutputFileOperation.h
index d9626cd..44e2899 100644
--- a/source/blender/compositor/operations/COM_OutputFileOperation.h
+++ b/source/blender/compositor/operations/COM_OutputFileOperation.h
@@ -103,6 +103,7 @@ public:
 };
 
 void add_exr_channels(void *exrhandle, const char *layerName, const DataType datatype, const char *viewName, const size_t width, float *buf);
+void free_exr_channels(void *exrhandle, const RenderData *rd, const char *layerName, const DataType datatype);
 int get_datatype_size(DataType datatype);
 
 #endif




More information about the Bf-blender-cvs mailing list