[Bf-blender-cvs] [de68066] master: Fix multilayer OpenEXR not supporting metadata.

Antony Riakiotakis noreply at git.blender.org
Tue May 26 12:02:50 CEST 2015


Commit: de68066c1ccfbdd3d9f185164e728677c91874ec
Author: Antony Riakiotakis
Date:   Tue May 26 12:02:14 2015 +0200
Branches: master
https://developer.blender.org/rBde68066c1ccfbdd3d9f185164e728677c91874ec

Fix multilayer OpenEXR not supporting metadata.

This will fix exporting of metadata and importing for imbufs, but image
editor will not display these metadata since multilayer gets converted
to renderresult, which does not support metadata display yet.
This commit is more meant for external image editors/viewers.

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

M	source/blender/blenkernel/BKE_image.h
M	source/blender/blenkernel/intern/image.c
M	source/blender/compositor/operations/COM_OutputFileMultiViewOperation.cpp
M	source/blender/compositor/operations/COM_OutputFileOperation.cpp
M	source/blender/imbuf/intern/openexr/openexr_api.cpp
M	source/blender/imbuf/intern/openexr/openexr_multi.h
M	source/blender/render/intern/source/render_result.c

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

diff --git a/source/blender/blenkernel/BKE_image.h b/source/blender/blenkernel/BKE_image.h
index 6b80e6b..a2eb26d 100644
--- a/source/blender/blenkernel/BKE_image.h
+++ b/source/blender/blenkernel/BKE_image.h
@@ -47,6 +47,7 @@ struct ImagePool;
 struct Main;
 struct ReportList;
 struct RenderResult;
+struct StampData;
 
 #define IMA_MAX_SPACE       64
 
@@ -59,8 +60,11 @@ void    BKE_image_free_buffers(struct Image *image);
 /* call from library */
 void    BKE_image_free(struct Image *image);
 
+typedef void (StampCallback)(void *data, const char *propname, const char *propvalue);
+
 void    BKE_render_result_stamp_info(struct Scene *scene, struct Object *camera, struct RenderResult *rr);
 void    BKE_imbuf_stamp_info(struct RenderResult *rr, struct ImBuf *ibuf);
+void    BKE_stamp_info_callback(void *data, struct StampData *stamp_data, StampCallback callback);
 void    BKE_image_stamp_buf(struct Scene *scene, struct Object *camera, unsigned char *rect, float *rectf, int width, int height, int channels);
 bool    BKE_imbuf_alpha_test(struct ImBuf *ibuf);
 int     BKE_imbuf_write_stamp(struct Scene *scene, struct RenderResult *rr, struct ImBuf *ibuf, const char *name, struct ImageFormatData *imf);
diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c
index c6d302e..7b6e749 100644
--- a/source/blender/blenkernel/intern/image.c
+++ b/source/blender/blenkernel/intern/image.c
@@ -2089,6 +2089,24 @@ void BKE_imbuf_stamp_info(RenderResult *rr, struct ImBuf *ibuf)
 	if (stamp_data->rendertime[0]) IMB_metadata_change_field(ibuf, "RenderTime", stamp_data->rendertime);
 }
 
+void BKE_stamp_info_callback(void *data, struct StampData *stamp_data, StampCallback callback)
+{
+	if (!callback || !stamp_data) return;
+
+	if (stamp_data->file[0])       callback(data, "File",       stamp_data->file);
+	if (stamp_data->note[0])       callback(data, "Note",       stamp_data->note);
+	if (stamp_data->date[0])       callback(data, "Date",       stamp_data->date);
+	if (stamp_data->marker[0])     callback(data, "Marker",     stamp_data->marker);
+	if (stamp_data->time[0])       callback(data, "Time",       stamp_data->time);
+	if (stamp_data->frame[0])      callback(data, "Frame",      stamp_data->frame);
+	if (stamp_data->camera[0])     callback(data, "Camera",     stamp_data->camera);
+	if (stamp_data->cameralens[0]) callback(data, "Lens",       stamp_data->cameralens);
+	if (stamp_data->scene[0])      callback(data, "Scene",      stamp_data->scene);
+	if (stamp_data->strip[0])      callback(data, "Strip",      stamp_data->strip);
+	if (stamp_data->rendertime[0]) callback(data, "RenderTime", stamp_data->rendertime);
+}
+
+
 bool BKE_imbuf_alpha_test(ImBuf *ibuf)
 {
 	int tot;
diff --git a/source/blender/compositor/operations/COM_OutputFileMultiViewOperation.cpp b/source/blender/compositor/operations/COM_OutputFileMultiViewOperation.cpp
index c927dfa..e89af9c 100644
--- a/source/blender/compositor/operations/COM_OutputFileMultiViewOperation.cpp
+++ b/source/blender/compositor/operations/COM_OutputFileMultiViewOperation.cpp
@@ -81,7 +81,7 @@ void *OutputOpenExrSingleLayerMultiViewOperation::get_handle(const char *filenam
 
 		/* prepare the file with all the channels */
 
-		if (IMB_exr_begin_write(exrhandle, filename, width, height, this->m_format->exr_codec) == 0) {
+		if (IMB_exr_begin_write(exrhandle, filename, width, height, this->m_format->exr_codec, NULL) == 0) {
 			printf("Error Writing Singlelayer Multiview Openexr\n");
 			IMB_exr_close(exrhandle);
 		}
@@ -168,7 +168,7 @@ void *OutputOpenExrMultiLayerMultiViewOperation::get_handle(const char *filename
 		BLI_make_existing_file(filename);
 
 		/* prepare the file with all the channels for the header */
-		if (IMB_exr_begin_write(exrhandle, filename, width, height, this->m_exr_codec) == 0) {
+		if (IMB_exr_begin_write(exrhandle, filename, width, height, this->m_exr_codec, NULL) == 0) {
 			printf("Error Writing Multilayer Multiview Openexr\n");
 			IMB_exr_close(exrhandle);
 		}
diff --git a/source/blender/compositor/operations/COM_OutputFileOperation.cpp b/source/blender/compositor/operations/COM_OutputFileOperation.cpp
index 1a7a356..b99b0d5 100644
--- a/source/blender/compositor/operations/COM_OutputFileOperation.cpp
+++ b/source/blender/compositor/operations/COM_OutputFileOperation.cpp
@@ -288,7 +288,7 @@ void OutputOpenExrMultiLayerOperation::deinitExecution()
 		}
 		
 		/* when the filename has no permissions, this can fail */
-		if (IMB_exr_begin_write(exrhandle, filename, width, height, this->m_exr_codec)) {
+		if (IMB_exr_begin_write(exrhandle, filename, width, height, this->m_exr_codec, NULL)) {
 			IMB_exr_write_channels(exrhandle);
 		}
 		else {
diff --git a/source/blender/imbuf/intern/openexr/openexr_api.cpp b/source/blender/imbuf/intern/openexr/openexr_api.cpp
index b4f81eb..1950fd8 100644
--- a/source/blender/imbuf/intern/openexr/openexr_api.cpp
+++ b/source/blender/imbuf/intern/openexr/openexr_api.cpp
@@ -63,6 +63,7 @@ _CRTIMP void __cdecl _invalid_parameter_noinfo(void)
 #include "BLI_threads.h"
 
 #include "BKE_idprop.h"
+#include "BKE_image.h"
 
 #include "IMB_imbuf_types.h"
 #include "IMB_imbuf.h"
@@ -363,6 +364,13 @@ static void openexr_header_metadata(Header *header, struct ImBuf *ibuf)
 		addXDensity(*header, ibuf->ppm[0] / 39.3700787); /* 1 meter = 39.3700787 inches */
 }
 
+static void openexr_header_metadata_callback(void *data, const char *propname, const char *prop)
+{
+	Header *header = (Header *)data;
+	header->insert(propname, StringAttribute(prop));
+}
+
+
 static bool imb_save_openexr_half(ImBuf *ibuf, const char *name, const int flags, const size_t totviews,
                                   const char * (*getview)(void *base, size_t view_id),
                                   ImBuf * (*getbuffer)(void *base, const size_t view_id))
@@ -821,7 +829,7 @@ void IMB_exr_add_channel(void *handle, const char *layname, const char *passname
 }
 
 /* used for output files (from RenderResult) (single and multilayer, single and multiview) */
-int 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, struct StampData *stamp)
 {
 	ExrHandle *data = (ExrHandle *)handle;
 	Header header(width, height);
@@ -836,7 +844,7 @@ int IMB_exr_begin_write(void *handle, const char *filename, int width, int heigh
 		header.channels().insert(echan->name, Channel(Imf::FLOAT));
 
 	openexr_header_compression(&header, compress);
-	// openexr_header_metadata(&header, ibuf); // no imbuf. cant write
+	BKE_stamp_info_callback(&header, stamp, openexr_header_metadata_callback);
 	/* header.lineOrder() = DECREASING_Y; this crashes in windows for file read! */
 
 	imb_exr_type_by_channels(header.channels(), *data->multiView, &is_singlelayer, &is_multilayer, &is_multiview);
@@ -1888,6 +1896,22 @@ struct ImBuf *imb_load_openexr(unsigned char *mem, size_t size, int flags, char
 			ibuf->ftype = OPENEXR;
 
 			if (!(flags & IB_test)) {
+
+				if (flags & IB_metadata) {
+					const Header & header = file->header(0);
+					Header::ConstIterator iter;
+
+					for (iter = header.begin(); iter != header.end(); iter++) {
+						const StringAttribute *attrib = file->header(0).findTypedAttribute <StringAttribute> (iter.name());
+
+						/* not all attributes are string attributes so we might get some NULLs here */
+						if (attrib) {
+							IMB_metadata_add_field(ibuf, iter.name(), attrib->value().c_str());
+							ibuf->flags |= IB_metadata;
+						}
+					}
+				}
+
 				if (is_multi && ((flags & IB_thumbnail) == 0)) { /* only enters with IB_multilayer flag set */
 					/* constructs channels for reading, allocates memory in channels */
 					ExrHandle *handle = imb_exr_begin_read_mem(*file, width, height);
@@ -1973,21 +1997,6 @@ struct ImBuf *imb_load_openexr(unsigned char *mem, size_t size, int flags, char
 						}
 					}
 
-					if (flags & IB_metadata) {
-						const Header & header = file->header(0);
-						Header::ConstIterator iter;
-
-						for (iter = header.begin(); iter != header.end(); iter++) {
-							const StringAttribute *attrib = file->header(0).findTypedAttribute <StringAttribute> (iter.name());
-
-							/* not all attributes are string attributes so we might get some NULLs here */
-							if (attrib) {
-								IMB_metadata_add_field(ibuf, iter.name(), attrib->value().c_str());
-								ibuf->flags |= IB_metadata;
-							}
-						}
-					}
-
 					/* file is no longer needed */
 					delete file;
 				}
diff --git a/source/blender/imbuf/intern/openexr/openexr_multi.h b/source/blender/imbuf/intern/openexr/openexr_multi.h
index 45ab0ed..dbef24c 100644
--- a/source/blender/imbuf/intern/openexr/openexr_multi.h
+++ b/source/blender/imbuf/intern/openexr/openexr_multi.h
@@ -48,12 +48,14 @@
 extern "C" {
 #endif
 
+struct StampData;
+
 void *IMB_exr_get_handle(void);
 void *IMB_exr_get_handle_name(const char *name);
 void    IMB_exr_add_channel(void *handle, const char *layname, const char *passname, const char *view, int xstride, int ystride, float *rect);
 
 int     IMB_exr_begin_read(void *handle, const char *filename, int *width, int *height);
-int     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, struct StampData *stamp);
 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);
diff --git a/source/blender/render/intern/source/render_result.c b/source/blender/render/intern/source/render_result.c
index 525c035..9e722ac 100644
--- a/source/blender/render/intern/source/render_result.c
+++ b/source/blender/render/intern/source/render_result.c
@@ -1110,7 +1110,7 @@ bool RE_WriteRenderResult(ReportList *reports, RenderResult *rr, const char *fil
 
 	BLI_make_existing_file(filename);
 
-	if (IMB_exr_begin_write(exrhandle, filename, width, height, compress)) {
+	if (IMB_exr_begin_write(exrha

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list