Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKent Mein <mein@cs.umn.edu>2005-03-11 23:16:14 +0300
committerKent Mein <mein@cs.umn.edu>2005-03-11 23:16:14 +0300
commita1919e6db4e20f1ab16646d3cbb273f569af23e1 (patch)
tree60642648c9d0b35a1c8f81bf96bdb7c60acba2d7 /source/blender/imbuf
parentc6d51245604b8c1bb329f5362ad528cc6f31c085 (diff)
Gernot Ziegler's patch to add OpenEXR support to blender.
To enable it you will need to download OpenEXR and install it. For the Makefiles you will need to set WITH_OPENEXR=true and set NAN_OPENEXR to point to where OpenEXR is installed. For scons you'll need to remove config.opts to get the new options so you can enable OpenEXR, I was not able to get blender to link with scons so the scons stuff may need to be tweaked a little but I think it should work. For other platform managers The OpenEXR stuff is similar to QUICKTIME you need to define WITH_OPENEXR and setup the library stuff and as you'll notice in this commit there are two extra files. Kent
Diffstat (limited to 'source/blender/imbuf')
-rw-r--r--source/blender/imbuf/IMB_imbuf.h2
-rw-r--r--source/blender/imbuf/IMB_imbuf_types.h5
-rw-r--r--source/blender/imbuf/SConscript4
-rw-r--r--source/blender/imbuf/intern/IMB_openexr.h46
-rw-r--r--source/blender/imbuf/intern/Makefile7
-rw-r--r--source/blender/imbuf/intern/cmap.c4
-rw-r--r--source/blender/imbuf/intern/openexr.cpp392
-rw-r--r--source/blender/imbuf/intern/readimage.c10
-rw-r--r--source/blender/imbuf/intern/writeimage.c8
9 files changed, 474 insertions, 4 deletions
diff --git a/source/blender/imbuf/IMB_imbuf.h b/source/blender/imbuf/IMB_imbuf.h
index 7f7b2b08a56..80eec374627 100644
--- a/source/blender/imbuf/IMB_imbuf.h
+++ b/source/blender/imbuf/IMB_imbuf.h
@@ -140,7 +140,7 @@ short IMB_converttocmap(struct ImBuf *ibuf);
*
* @attention Defined in cmap.c
*/
-int IMB_alpha_to_col0(int new);
+int IMB_alpha_to_col0(int value);
/**
*
diff --git a/source/blender/imbuf/IMB_imbuf_types.h b/source/blender/imbuf/IMB_imbuf_types.h
index 8abb00d722d..e0a1d42aa1a 100644
--- a/source/blender/imbuf/IMB_imbuf_types.h
+++ b/source/blender/imbuf/IMB_imbuf_types.h
@@ -75,6 +75,7 @@ typedef struct ImBuf{
int ftype; /**< File type */
unsigned int *cmap; /**< Color map data. */
unsigned int *rect; /**< databuffer */
+ float *rect_float; /**< databuffer in Float format, unclampled !! */
unsigned int **planes; /**< bitplanes */
int flags; /**< Controls which components should exist. */
int mall; /**< what is malloced internal, and can be freed */
@@ -151,6 +152,9 @@ typedef enum {
#ifdef WITH_IMAGEMAGICK
#define IMAGEMAGICK (1 << 23)
#endif
+#ifdef WITH_OPENEXR
+#define OPENEXR (1 << 22)
+#endif
#define RAWTGA (TGA | 1)
@@ -187,6 +191,7 @@ typedef enum {
#define IS_hamx(x) (x->ftype == AN_hamx)
#define IS_tga(x) (x->ftype & TGA)
#define IS_png(x) (x->ftype & PNG)
+#define IS_openexr(x) (x->ftype & OPENEXR)
#define IS_bmp(x) (x->ftype & BMP)
#define IMAGIC 0732
diff --git a/source/blender/imbuf/SConscript b/source/blender/imbuf/SConscript
index 11d7cfb2b30..199e872e49b 100644
--- a/source/blender/imbuf/SConscript
+++ b/source/blender/imbuf/SConscript
@@ -33,6 +33,9 @@ source_files = ['intern/allocimbuf.c',
'intern/util.c',
'intern/writeimage.c']
+if user_options_dict['USE_OPENEXR'] == 1:
+ source_files.append('intern/openexr.cpp')
+
imbuf_env.Append (CPPPATH = ['.',
'../makesdna',
'#/intern/guardedalloc',
@@ -43,6 +46,7 @@ imbuf_env.Append (CPPPATH = ['.',
imbuf_env.Append (CPPPATH = user_options_dict['JPEG_INCLUDE'])
imbuf_env.Append (CPPPATH = user_options_dict['PNG_INCLUDE'])
+imbuf_env.Append (CPPPATH = user_options_dict['OPENEXR_INCLUDE'])
imbuf_env.Append (CPPPATH = user_options_dict['Z_INCLUDE'])
imbuf_env.Append (CPPPATH = extra_includes)
imbuf_env.Library (target='#'+user_options_dict['BUILD_DIR']+'/lib/blender_imbuf', source=source_files)
diff --git a/source/blender/imbuf/intern/IMB_openexr.h b/source/blender/imbuf/intern/IMB_openexr.h
new file mode 100644
index 00000000000..edf8b144bde
--- /dev/null
+++ b/source/blender/imbuf/intern/IMB_openexr.h
@@ -0,0 +1,46 @@
+/*
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+/**
+ * \file IMB_openexr.h
+ * \ingroup imbuf
+ * \brief Function declarations for openexr.cc
+ */
+
+#ifndef IMB_OPENEXR_H
+#define IMB_OPENEXR_H
+
+struct ImBuf;
+
+int imb_is_a_openexr(void *buf);
+
+struct ImBuf *imb_load_openexr(unsigned char *mem, int size, int flags);
+short imb_save_openexr(struct ImBuf * ibuf, char *name, int flags);
+#endif
diff --git a/source/blender/imbuf/intern/Makefile b/source/blender/imbuf/intern/Makefile
index 0cb0316524d..15062044716 100644
--- a/source/blender/imbuf/intern/Makefile
+++ b/source/blender/imbuf/intern/Makefile
@@ -60,6 +60,11 @@ CPPFLAGS += -I../../makesdna
CPPFLAGS += -I..
ifeq ($(WITH_QUICKTIME), true)
- CPPFLAGS += -DWITH_QUICKTIME
+ CPPFLAGS += -DWITH_QUICKTIME
+endif
+
+ifeq ($(WITH_OPENEXR), true)
+ CPPFLAGS += -DWITH_OPENEXR
+ CPPFLAGS += -I$(NAN_OPENEXR)/include/OpenEXR
endif
diff --git a/source/blender/imbuf/intern/cmap.c b/source/blender/imbuf/intern/cmap.c
index f5302b311d8..c955fbf7e60 100644
--- a/source/blender/imbuf/intern/cmap.c
+++ b/source/blender/imbuf/intern/cmap.c
@@ -64,12 +64,12 @@ void IMB_freeImBufdata(void)
}
-int IMB_alpha_to_col0(int new)
+int IMB_alpha_to_col0(int value)
{
int old;
old = alpha_col0;
- alpha_col0 = new;
+ alpha_col0 = value;
return (old);
}
diff --git a/source/blender/imbuf/intern/openexr.cpp b/source/blender/imbuf/intern/openexr.cpp
new file mode 100644
index 00000000000..96c897715d8
--- /dev/null
+++ b/source/blender/imbuf/intern/openexr.cpp
@@ -0,0 +1,392 @@
+/**
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright by Gernot Ziegler <gz@lysator.liu.se>.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ *
+ */
+#include <stdlib.h>
+#include <stdio.h>
+#include <string>
+
+#include <iostream>
+
+#include <half.h>
+#include <ImfVersion.h>
+#include <ImathBox.h>
+#include <ImfArray.h>
+#include <ImfIO.h>
+#include <ImfChannelList.h>
+#include <ImfPixelType.h>
+#include <ImfInputFile.h>
+#include <ImfOutputFile.h>
+
+using namespace Imf;
+using namespace Imath;
+
+extern "C"
+{
+#ifdef WIN32
+#include "BLI_winstuff.h"
+#endif
+#include "BLI_blenlib.h"
+
+#include "imbuf.h"
+#include "imbuf_patch.h"
+
+#include "IMB_imbuf_types.h"
+#include "IMB_imbuf.h"
+
+#include "IMB_allocimbuf.h"
+#include "IMB_cmap.h"
+}
+
+
+int imb_is_a_openexr(void *mem)
+{
+ return Imf::isImfMagic ((const char *)mem);
+}
+
+
+class Mem_IStream: public IStream
+{
+ public:
+
+ Mem_IStream (unsigned char *exrbuf, int exrsize):
+ IStream("dummy"), _exrpos (0), _exrsize(exrsize) { _exrbuf = exrbuf; }
+
+ virtual bool read (char c[], int n);
+ virtual Int64 tellg ();
+ virtual void seekg (Int64 pos);
+ virtual void clear ();
+//virtual ~Mem_IStream() {}; // unused
+
+ private:
+
+ Int64 _exrpos;
+ Int64 _exrsize;
+ unsigned char *_exrbuf;
+};
+
+bool Mem_IStream::read (char c[], int n)
+{
+ if (n + _exrpos <= _exrsize)
+ {
+ memcpy(c, (void *)(&_exrbuf[_exrpos]), n);
+ _exrpos += n;
+ return true;
+ }
+ else
+ return false;
+}
+
+
+Int64 Mem_IStream::tellg ()
+{
+ return _exrpos;
+}
+
+
+void Mem_IStream::seekg (Int64 pos)
+{
+ _exrpos = pos;
+}
+
+
+void Mem_IStream::clear ()
+{
+}
+
+
+struct _RGBAZ
+{
+ half r;
+ half g;
+ half b;
+ half a;
+ half z;
+};
+
+typedef struct _RGBAZ RGBAZ;
+
+extern "C"
+{
+ short imb_save_openexr(struct ImBuf *ibuf, char *name, int flags)
+ {
+ int width = ibuf->x;
+ int height = ibuf->y;
+ int i;
+
+ // summarize
+ int write_zbuf = (flags & IB_zbuf) && ibuf->zbuf != 0;
+
+ printf("OpenEXR-save: Saving %s image of %d x %d\n",
+ write_zbuf ? "RGBAZ" : "RGBA", width, height);
+
+ try
+ {
+ Header header (width, height);
+ header.channels().insert ("R", Channel (HALF));
+ header.channels().insert ("G", Channel (HALF));
+ header.channels().insert ("B", Channel (HALF));
+ header.channels().insert ("A", Channel (HALF));
+ if (write_zbuf)
+ header.channels().insert ("Z", Channel (HALF));
+
+ FrameBuffer frameBuffer;
+ OutputFile *file;
+
+ if (flags & IB_mem)
+ {
+ printf("OpenEXR-save: Create EXR in memory CURRENTLY NOT SUPPORTED !\n");
+ imb_addencodedbufferImBuf(ibuf);
+ ibuf->encodedsize = 0;
+ return(0);
+ }
+ else
+ {
+ printf("OpenEXR-save: Creating output file %s\n", name);
+ file = new OutputFile(name, header);
+ }
+
+ RGBAZ *pixels = new RGBAZ[height * width];
+
+ int bytesperpixel = (ibuf->depth + 7) >> 3;
+ if ((bytesperpixel > 4) || (bytesperpixel == 2))
+ {
+ printf("OpenEXR-save: unsupported bytes per pixel: %d\n", bytesperpixel);
+ return (0);
+ }
+
+ frameBuffer.insert ("R",
+ Slice (HALF,
+ (char *) &pixels[0].r,
+ sizeof (pixels[0]) * 1,
+ sizeof (pixels[0]) * width));
+
+ frameBuffer.insert ("G",
+ Slice (HALF,
+ (char *) &pixels[0].g,
+ sizeof (pixels[0]) * 1,
+ sizeof (pixels[0]) * width));
+
+ frameBuffer.insert ("B",
+ Slice (HALF,
+ (char *) &pixels[0].b,
+ sizeof (pixels[0]) * 1,
+ sizeof (pixels[0]) * width));
+
+ frameBuffer.insert ("A",
+ Slice (HALF,
+ (char *) &pixels[0].a,
+ sizeof (pixels[0]) * 1,
+ sizeof (pixels[0]) * width));
+
+ if (write_zbuf)
+ frameBuffer.insert ("Z",
+ Slice (HALF,
+ (char *) &pixels[0].z,
+ sizeof (pixels[0]) * 1,
+ sizeof (pixels[0]) * width));
+
+ if (!ibuf->rect_float)
+ {
+ printf("OpenEXR-save: Converting Blender 8/8/8/8 pixels to OpenEXR format\n");
+
+ RGBAZ *to = pixels;
+ unsigned char *from = (unsigned char *) ibuf->rect;
+
+ for (i = ibuf->x * ibuf->y; i > 0; i--)
+ {
+ to->r = (float)(from[0])/255.0;
+ to->g = (float)(from[1])/255.0;
+ to->b = (float)(from[2])/255.0;
+ to->a = (float)(from[3])/255.0;
+ to++; from += 4;
+ }
+ }
+ else
+ {
+ printf("OpenEXR-save: Converting Blender FLOAT pixels to OpenEXR format\n");
+
+ RGBAZ *to = pixels;
+ float *from = ibuf->rect_float;
+
+ for (i = ibuf->x * ibuf->y; i > 0; i--)
+ {
+ to->r = from[0];
+ to->g = from[1];
+ to->b = from[2];
+ to->a = from[3];
+ to++; from += 4;
+ }
+ }
+
+ if (write_zbuf)
+ {
+ RGBAZ *to = pixels;
+ int *fromz = ibuf->zbuf;
+
+ for (int i = ibuf->x * ibuf->y; i > 0; i--)
+ {
+ to->z = (0.5+((float)(*fromz/65536)/65536.0));
+ to++; fromz ++;
+ }
+ }
+
+ printf("OpenEXR-save: Writing OpenEXR file of height %d.\n", height);
+
+ file->setFrameBuffer (frameBuffer);
+ file->writePixels (height);
+ delete file;
+ }
+ catch (const std::exception &exc)
+ {
+ printf("OpenEXR-save: ERROR: %s\n", exc.what());
+ if (ibuf) IMB_freeImBuf(ibuf);
+
+ return (0);
+ }
+
+ return (1);
+ printf("OpenEXR-save: Done.\n");
+ }
+
+ struct ImBuf *imb_load_openexr(unsigned char *mem, int size, int flags)
+ {
+ struct ImBuf *ibuf = 0;
+
+ printf("OpenEXR-load: testing input, size is %d\n", size);
+ if (imb_is_a_openexr(mem) == 0) return(0);
+
+ InputFile *file = NULL;
+
+ try
+ {
+ printf("OpenEXR-load: Creating InputFile from mem source\n");
+ Mem_IStream membuf(mem, size);
+ file = new InputFile(membuf);
+
+ Box2i dw = file->header().dataWindow();
+ int width = dw.max.x - dw.min.x + 1;
+ int height = dw.max.y - dw.min.y + 1;
+
+ printf("OpenEXR-load: image data window %d %d %d %d\n",
+ dw.min.x, dw.min.y, dw.max.x, dw.max.y);
+
+ const ChannelList &channels = file->header().channels();
+
+ for (ChannelList::ConstIterator i = channels.begin(); i != channels.end(); ++i)
+ {
+ const Channel &channel = i.channel();
+ printf("OpenEXR-load: Found channel %s of type %d\n", i.name(), channel.type);
+ if (channel.type != 1)
+ {
+ printf("OpenEXR-load: Can only process HALF input !!\n");
+ return(NULL);
+ }
+ }
+
+ RGBAZ *pixels = new RGBAZ[height * width];
+
+ FrameBuffer frameBuffer;
+
+ frameBuffer.insert ("R",
+ Slice (HALF,
+ (char *) &pixels[0].r,
+ sizeof (pixels[0]) * 1,
+ sizeof (pixels[0]) * width));
+
+ frameBuffer.insert ("G",
+ Slice (HALF,
+ (char *) &pixels[0].g,
+ sizeof (pixels[0]) * 1,
+ sizeof (pixels[0]) * width));
+
+ frameBuffer.insert ("B",
+ Slice (HALF,
+ (char *) &pixels[0].b,
+ sizeof (pixels[0]) * 1,
+ sizeof (pixels[0]) * width));
+
+ frameBuffer.insert ("A",
+ Slice (HALF,
+ (char *) &pixels[0].a,
+ sizeof (pixels[0]) * 1,
+ sizeof (pixels[0]) * width));
+
+// FIXME ? Would be able to read Z data or other channels here !
+
+ printf("OpenEXR-load: Reading pixel data\n");
+ file->setFrameBuffer (frameBuffer);
+ file->readPixels (dw.min.y, dw.max.y);
+
+ printf("OpenEXR-load: Converting to Blender ibuf\n");
+
+ int bytesperpixel = 4; // since OpenEXR fills in unknown channels
+ ibuf = IMB_allocImBuf(width, height, 8 * bytesperpixel, 0, 0);
+
+ if (ibuf)
+ {
+ ibuf->ftype = PNG;
+ imb_addrectImBuf(ibuf);
+
+ if (!(flags & IB_test))
+ {
+ unsigned char *to = (unsigned char *) ibuf->rect;
+ RGBAZ *from = pixels;
+ RGBAZ prescale;
+
+ for (int i = ibuf->x * ibuf->y; i > 0; i--)
+ {
+ to[0] = (unsigned char)(((float)from->r > 1.0) ? 1.0 : (float)from->r) * 255;
+ to[1] = (unsigned char)(((float)from->g > 1.0) ? 1.0 : (float)from->g) * 255;
+ to[2] = (unsigned char)(((float)from->b > 1.0) ? 1.0 : (float)from->b) * 255;
+ to[3] = (unsigned char)(((float)from->a > 1.0) ? 1.0 : (float)from->a) * 255;
+ to += 4; from++;
+ }
+ }
+
+ }
+ else
+ printf("Couldn't allocate memory for PNG image\n");
+
+ printf("OpenEXR-load: Done\n");
+
+ return(ibuf);
+ }
+ catch (const std::exception &exc)
+ {
+ std::cerr << exc.what() << std::endl;
+ if (ibuf) IMB_freeImBuf(ibuf);
+
+ return (0);
+ }
+
+ }
+
+} // export "C"
diff --git a/source/blender/imbuf/intern/readimage.c b/source/blender/imbuf/intern/readimage.c
index 0f817e22dd1..9d40ef602f8 100644
--- a/source/blender/imbuf/intern/readimage.c
+++ b/source/blender/imbuf/intern/readimage.c
@@ -47,6 +47,11 @@
#include "IMB_jpeg.h"
#include "IMB_bmp.h"
#include "BKE_global.h"
+
+#ifdef WITH_OPENEXR
+#include "IMB_openexr.h"
+#endif
+
#ifdef WITH_QUICKTIME
#if defined(_WIN32) || defined (__APPLE__)
#include "quicktime_import.h"
@@ -137,6 +142,11 @@ ImBuf *IMB_ibImageFromMemory(int *mem, int size, int flags) {
ibuf = imb_loadtarga((uchar *)mem, flags);
if (ibuf) return(ibuf);
+#ifdef WITH_OPENEXR
+ ibuf = imb_load_openexr((uchar *)mem, size, flags);
+ if (ibuf) return(ibuf);
+#endif
+
#ifdef WITH_QUICKTIME
#if defined(_WIN32) || defined (__APPLE__)
if(G.have_quicktime) {
diff --git a/source/blender/imbuf/intern/writeimage.c b/source/blender/imbuf/intern/writeimage.c
index 150ab8aac26..925eaca3e87 100644
--- a/source/blender/imbuf/intern/writeimage.c
+++ b/source/blender/imbuf/intern/writeimage.c
@@ -50,6 +50,9 @@
#include "IMB_amiga.h"
#include "IMB_png.h"
#include "IMB_bmp.h"
+#ifdef WITH_OPENEXR
+#include "IMB_openexr.h"
+#endif
#include "IMB_iff.h"
#include "IMB_bitplanes.h"
@@ -70,6 +73,11 @@ short IMB_saveiff(struct ImBuf *ibuf,char *naam,int flags)
if (IS_png(ibuf)) {
return imb_savepng(ibuf,naam,flags);
}
+#ifdef WITH_OPENEXR
+ if (IS_openexr(ibuf)) {
+ return imb_save_openexr(ibuf,naam,flags);
+ }
+#endif
if (IS_bmp(ibuf)) {
return imb_savebmp(ibuf,naam,flags);
}