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
path: root/source
diff options
context:
space:
mode:
authorBrecht Van Lommel <brechtvanlommel@pandora.be>2012-08-24 16:10:35 +0400
committerBrecht Van Lommel <brechtvanlommel@pandora.be>2012-08-24 16:10:35 +0400
commit61a39c7b1756cebb4a13949b5a880aa9d0d4ee3e (patch)
treefe44acb063021684089a4eb325423c3f9ee9d885 /source
parent7a66f139b4283dd4cf3ad0936d825cb905bfc676 (diff)
Fix second part #32377: saving/loading exr files to file paths with non-ascii
characters should now work on Windows.
Diffstat (limited to 'source')
-rw-r--r--source/blender/imbuf/intern/openexr/CMakeLists.txt1
-rw-r--r--source/blender/imbuf/intern/openexr/SConscript4
-rw-r--r--source/blender/imbuf/intern/openexr/openexr_api.cpp135
3 files changed, 122 insertions, 18 deletions
diff --git a/source/blender/imbuf/intern/openexr/CMakeLists.txt b/source/blender/imbuf/intern/openexr/CMakeLists.txt
index 4ee2ff4cc47..a5afc1abdc6 100644
--- a/source/blender/imbuf/intern/openexr/CMakeLists.txt
+++ b/source/blender/imbuf/intern/openexr/CMakeLists.txt
@@ -31,6 +31,7 @@ set(INC
../../../blenlib
../../../makesdna
../../../../../intern/guardedalloc
+ ../../../../../intern/utfconv
)
set(INC_SYS
diff --git a/source/blender/imbuf/intern/openexr/SConscript b/source/blender/imbuf/intern/openexr/SConscript
index e590077db2b..a6c5ad984e2 100644
--- a/source/blender/imbuf/intern/openexr/SConscript
+++ b/source/blender/imbuf/intern/openexr/SConscript
@@ -10,7 +10,9 @@ incs = ['.',
'../../../blenlib',
'intern/include',
'#/intern/guardedalloc',
- '../../../makesdna']
+ '../../../makesdna',
+ '#/intern/utfconv']
+
incs += Split(env['BF_OPENEXR_INC'])
defs = ['WITH_OPENEXR']
diff --git a/source/blender/imbuf/intern/openexr/openexr_api.cpp b/source/blender/imbuf/intern/openexr/openexr_api.cpp
index 91876249bf6..1b99a3040a8 100644
--- a/source/blender/imbuf/intern/openexr/openexr_api.cpp
+++ b/source/blender/imbuf/intern/openexr/openexr_api.cpp
@@ -32,12 +32,17 @@
#include <stdlib.h>
#include <stdio.h>
#include <stddef.h>
+#include <fstream>
#include <string>
#include <set>
#include <openexr_api.h>
+#if defined (WIN32) && !defined(FREE_WINDOWS)
+#include "utfconv.h"
+#endif
+
extern "C"
{
@@ -76,6 +81,7 @@ _CRTIMP void __cdecl _invalid_parameter_noinfo(void)
#include <IlmImf/ImfCompression.h>
#include <IlmImf/ImfCompressionAttribute.h>
#include <IlmImf/ImfStringAttribute.h>
+#include <IlmImf/ImfStdIO.h>
#include <Imath/ImathBox.h>
#else
#include <half.h>
@@ -90,6 +96,7 @@ _CRTIMP void __cdecl _invalid_parameter_noinfo(void)
#include <ImfCompression.h>
#include <ImfCompressionAttribute.h>
#include <ImfStringAttribute.h>
+#include <ImfStdIO.h>
#endif
using namespace Imf;
@@ -192,6 +199,28 @@ static void openexr_header_metadata(Header *header, struct ImBuf *ibuf)
header->insert(info->key, StringAttribute(info->value));
}
+static void openexr_ofstream_open(std::ofstream& ofs, const char *name)
+{
+#if defined (WIN32) && !defined(FREE_WINDOWS)
+ wchar_t *wname = alloc_utf16_from_8(name, 0);
+ ofs.open(wname, std::ios_base::binary);
+ free(wname);
+#else
+ ofs.open(name, std::ios_base::binary);
+#endif
+}
+
+static void openexr_ifstream_open(std::ifstream& ifs, const char *name)
+{
+#if defined (WIN32) && !defined(FREE_WINDOWS)
+ wchar_t *wname = alloc_utf16_from_8(name, 0);
+ ifs.open(wname, std::ios_base::binary);
+ free(wname);
+#else
+ ifs.open(name, std::ios_base::binary);
+#endif
+}
+
static int imb_save_openexr_half(struct ImBuf *ibuf, const char *name, int flags)
{
const int channels = ibuf->channels;
@@ -216,7 +245,13 @@ static int imb_save_openexr_half(struct ImBuf *ibuf, const char *name, int flags
header.channels().insert("Z", Channel(Imf::FLOAT));
FrameBuffer frameBuffer;
- OutputFile *file = new OutputFile(name, header);
+
+ /* manually create ofstream, so we can handle utf-8 filepaths on windows */
+ std::ofstream std_ostream;
+ openexr_ofstream_open(std_ostream, name);
+ StdOFStream exr_ostream(std_ostream, name);
+
+ OutputFile file(exr_ostream, header);
/* we store first everything in half array */
RGBAZ *pixels = new RGBAZ[height * width];
@@ -281,9 +316,9 @@ static int imb_save_openexr_half(struct ImBuf *ibuf, const char *name, int flags
// printf("OpenEXR-save: Writing OpenEXR file of height %d.\n", height);
- file->setFrameBuffer(frameBuffer);
- file->writePixels(height);
- delete file;
+ file.setFrameBuffer(frameBuffer);
+ file.writePixels(height);
+
delete[] pixels;
}
catch (const std::exception &exc)
@@ -321,7 +356,14 @@ static int imb_save_openexr_float(struct ImBuf *ibuf, const char *name, int flag
header.channels().insert("Z", Channel(Imf::FLOAT));
FrameBuffer frameBuffer;
- OutputFile *file = new OutputFile(name, header);
+
+ /* manually create ofstream, so we can handle utf-8 filepaths on windows */
+ std::ofstream std_ostream;
+ openexr_ofstream_open(std_ostream, name);
+ StdOFStream exr_ostream(std_ostream, name);
+
+ OutputFile file(exr_ostream, header);
+
int xstride = sizeof(float) * channels;
int ystride = -xstride * width;
float *rect[4] = {NULL, NULL, NULL, NULL};
@@ -340,9 +382,8 @@ static int imb_save_openexr_float(struct ImBuf *ibuf, const char *name, int flag
if (is_zbuf)
frameBuffer.insert("Z", Slice(Imf::FLOAT, (char *) (ibuf->zbuf_float + (height - 1) * width),
sizeof(float), sizeof(float) * -width));
- file->setFrameBuffer(frameBuffer);
- file->writePixels(height);
- delete file;
+ file.setFrameBuffer(frameBuffer);
+ file.writePixels(height);
}
catch (const std::exception &exc)
{
@@ -391,9 +432,15 @@ static ListBase exrhandles = {NULL, NULL};
typedef struct ExrHandle {
struct ExrHandle *next, *prev;
+ std::ifstream *std_istream;
+ StdIFStream *exr_istream;
InputFile *ifile;
+
+ std::ofstream *std_ostream;
+ StdOFStream *exr_ostream;
TiledOutputFile *tofile;
OutputFile *ofile;
+
int tilex, tiley;
int width, height;
int mipmap;
@@ -486,12 +533,24 @@ int IMB_exr_begin_write(void *handle, const char *filename, int width, int heigh
header.insert("BlenderMultiChannel", StringAttribute("Blender V2.55.1 and newer"));
/* avoid crash/abort when we don't have permission to write here */
+ /* manually create ofstream, so we can handle utf-8 filepaths on windows */
try {
- data->ofile = new OutputFile(filename, header);
+ data->std_ostream = new std::ofstream();
+ openexr_ofstream_open(*(data->std_ostream), filename);
+
+ data->exr_ostream = new StdOFStream(*(data->std_ostream), filename);
+ data->ofile = new OutputFile(*(data->exr_ostream), header);
}
catch (const std::exception &exc) {
std::cerr << "IMB_exr_begin_write: ERROR: " << exc.what() << std::endl;
+
+ delete data->ofile;
+ delete data->exr_ostream;
+ delete data->std_ostream;
+
data->ofile = NULL;
+ data->exr_ostream = NULL;
+ data->std_ostream = NULL;
}
return (data->ofile != NULL);
@@ -518,7 +577,24 @@ void IMB_exrtile_begin_write(void *handle, const char *filename, int mipmap, int
header.insert("BlenderMultiChannel", StringAttribute("Blender V2.43"));
- data->tofile = new TiledOutputFile(filename, header);
+ /* avoid crash/abort when we don't have permission to write here */
+ /* manually create ofstream, so we can handle utf-8 filepaths on windows */
+ try {
+ data->std_ostream = new std::ofstream();
+ openexr_ofstream_open(*(data->std_ostream), filename);
+
+ data->exr_ostream = new StdOFStream(*(data->std_ostream), filename);
+ data->tofile = new TiledOutputFile(*(data->exr_ostream), header);
+ }
+ catch (const std::exception &exc) {
+ delete data->tofile;
+ delete data->exr_ostream;
+ delete data->std_ostream;
+
+ data->tofile = NULL;
+ data->exr_ostream = NULL;
+ data->std_ostream = NULL;
+ }
}
/* read from file */
@@ -527,7 +603,25 @@ int IMB_exr_begin_read(void *handle, const char *filename, int *width, int *heig
ExrHandle *data = (ExrHandle *)handle;
if (BLI_exists(filename) && BLI_file_size(filename) > 32) { /* 32 is arbitrary, but zero length files crashes exr */
- data->ifile = new InputFile(filename);
+ /* avoid crash/abort when we don't have permission to write here */
+ /* manually create ofstream, so we can handle utf-8 filepaths on windows */
+ try {
+ data->std_istream = new std::ifstream();
+ openexr_ifstream_open(*(data->std_istream), filename);
+
+ data->exr_istream = new StdIFStream(*(data->std_istream), filename);
+ data->ifile = new InputFile(*(data->exr_istream));
+ }
+ catch (const std::exception &exc) {
+ delete data->ifile;
+ delete data->exr_istream;
+ delete data->std_istream;
+
+ data->ifile = NULL;
+ data->exr_istream = NULL;
+ data->std_istream = NULL;
+ }
+
if (data->ifile) {
Box2i dw = data->ifile->header().dataWindow();
data->width = *width = dw.max.x - dw.min.x + 1;
@@ -696,16 +790,23 @@ void IMB_exr_close(void *handle)
ExrLayer *lay;
ExrPass *pass;
- if (data->ifile)
- delete data->ifile;
- else if (data->ofile)
- delete data->ofile;
- else if (data->tofile)
- delete data->tofile;
+ delete data->ifile;
+ delete data->exr_istream;
+ delete data->std_istream;
+
+ delete data->ofile;
+ delete data->tofile;
+ delete data->exr_ostream;
+ delete data->std_ostream;
data->ifile = NULL;
+ data->exr_istream = NULL;
+ data->std_istream = NULL;
+
data->ofile = NULL;
data->tofile = NULL;
+ data->exr_ostream = NULL;
+ data->std_ostream = NULL;
BLI_freelistN(&data->channels);