Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
alta
alta
Commits
55788034
Commit
55788034
authored
Jan 24, 2017
by
Laurent Belcour
Browse files
[EXR] Code cleaning and adding a warning if TinyEXR is not present
parent
95b068de
Changes
2
Hide whitespace changes
Inline
Side-by-side
sources/plugins/data_io/EXR_IO.h
View file @
55788034
/* ALTA --- Analysis of Bidirectional Reflectance Distribution Functions
Copyright (C) 2017 Unity Technologies
This file is part of ALTA.
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#pragma once
/* EXR_IO provides static method to either load an RGB EXR file into a floatting
* point array or save a RGB floatting point array to disk._data
*
* Original author: Cyril Soler
* Modified by: Laurent Belcour
*/
// STL includes
#include <stdexcept>
#include <cassert>
#ifdef USE_OPENEXR
#include <ImfRgbaFile.h>
#include <
ImfArray
.h>
// TinyEXR includes
#define TINYEXR_IMPLEMENTATION
#include <
tinyexr/tinyexr
.h>
// XXX: This header is not installed as of version 2.2.0 of OpenEXR, see
// <https://lists.nongnu.org/archive/html/openexr-devel/2016-06/msg00001.html>
// and <https://github.com/openexr/openexr/pull/184>.
#include <ImfStdIO.h>
#else
#define TINYEXR_IMPLEMENTATION
#include <tinyexr/tinyexr.h>
#endif
/*! \class EXR_IO
*
* \details
* EXR_IO provides static method to either load an RGB EXR file into a floatting
* point array or save a RGB floatting point array to disk._data
*
* \author Laurent Belcour
*/
template
<
typename
FType
>
class
t_EXR_IO
{
public:
/*! \brief Load an EXR file from an input file stream.
*/
static
bool
LoadEXR
(
std
::
istream
&
input
,
int
&
W
,
int
&
H
,
FType
*&
pix
,
int
nC
=
3
)
{
#ifdef USE_OPENEXR
/* XXX: OpenEXR implements its own IStream and OStream classes, but
* they are completely independent from those of libstdc++. The
* closest thing it has is 'StdIFStream', hence this hack.
*/
std
::
ifstream
*
ifstream
=
dynamic_cast
<
std
::
ifstream
*>
(
&
input
);
assert
(
ifstream
!=
NULL
);
Imf
::
StdIFStream
iifstream
(
*
ifstream
,
"unknown file name"
);
Imf
::
RgbaInputFile
file
(
iifstream
);
Imath
::
Box2i
dw
=
file
.
dataWindow
();
W
=
dw
.
max
.
x
-
dw
.
min
.
x
+
1
;
H
=
dw
.
max
.
y
-
dw
.
min
.
y
+
1
;
Imf
::
Array2D
<
Imf
::
Rgba
>
pixels
;
pixels
.
resizeErase
(
H
,
W
);
file
.
setFrameBuffer
(
&
pixels
[
0
][
0
]
-
dw
.
min
.
x
-
dw
.
min
.
y
*
W
,
1
,
W
);
file
.
readPixels
(
dw
.
min
.
y
,
dw
.
max
.
y
);
pix
=
new
FType
[
W
*
H
*
3
]
;
switch
(
nC
)
{
case
3
:
for
(
int
i
=
0
;
i
<
H
;
++
i
)
for
(
int
j
=
0
;
j
<
W
;
++
j
)
{
pix
[
3
*
(
j
+
i
*
W
)
+
0
]
=
pixels
[
H
-
i
-
1
][
j
].
r
;
pix
[
3
*
(
j
+
i
*
W
)
+
1
]
=
pixels
[
H
-
i
-
1
][
j
].
g
;
pix
[
3
*
(
j
+
i
*
W
)
+
2
]
=
pixels
[
H
-
i
-
1
][
j
].
b
;
}
break
;
case
1
:
for
(
int
i
=
0
;
i
<
H
;
++
i
)
for
(
int
j
=
0
;
j
<
W
;
++
j
)
pix
[
j
+
i
*
W
]
=
0.3
*
pixels
[
H
-
i
-
1
][
j
].
r
+
0.59
*
pixels
[
H
-
i
-
1
][
j
].
g
+
0.11
*
pixels
[
H
-
i
-
1
][
j
].
b
;
break
;
default:
throw
std
::
runtime_error
(
"Unexpected case in EXR_IO."
)
;
}
#else
/* Convert the input std::istream into an unsigned char array */
std
::
vector
<
unsigned
char
>
_memory
;
size_t
_n
=
0
,
_m
=
0
;
...
...
@@ -154,56 +117,18 @@ class t_EXR_IO
}
}
// Check: saver the file
SaveEXR
(
"dump.exr"
,
W
,
H
,
pix
);
/*! \todo Free TinyEXR memory : _image, _header and _version */
#endif
/* Free TinyEXR memory */
_r
=
FreeEXRHeader
(
&
_header
);
_r
=
FreeEXRImage
(
&
_image
);
return
true
;
}
/*! \brief Save a RGB image into and OpenEXR file using TinyEXR.
* This code uses TinyEXR's reference implementation of saving a file as
* we do not manipulate streams here.
*/
static
bool
SaveEXR
(
const
char
*
filename
,
int
W
,
int
H
,
const
FType
*
pix
,
int
nC
=
3
)
{
#ifdef USE_OPENEXR
Imf
::
Array2D
<
Imf
::
Rgba
>
pixels
(
H
,
W
);
/* Convert separated channel representation to per pixel representation */
switch
(
nC
)
{
case
3
:
for
(
int
row
=
0
;
row
<
H
;
row
++
)
for
(
int
i
=
0
;
i
<
W
;
i
++
)
{
Imf
::
Rgba
&
p
=
pixels
[
H
-
row
-
1
][
i
];
p
.
r
=
pix
[
3
*
(
i
+
row
*
W
)
+
0
]
;
p
.
g
=
pix
[
3
*
(
i
+
row
*
W
)
+
1
]
;
p
.
b
=
pix
[
3
*
(
i
+
row
*
W
)
+
2
]
;
p
.
a
=
1.0
;
}
break
;
case
1
:
for
(
int
row
=
0
;
row
<
H
;
row
++
)
for
(
int
i
=
0
;
i
<
W
;
i
++
)
{
Imf
::
Rgba
&
p
=
pixels
[
H
-
row
-
1
][
i
];
p
.
r
=
pix
[
i
+
row
*
W
]
;
p
.
g
=
pix
[
i
+
row
*
W
]
;
p
.
b
=
pix
[
i
+
row
*
W
]
;
p
.
a
=
FType
(
1.0
)
;
}
break
;
default:
throw
std
::
runtime_error
(
"Unexpected case in EXR_IO."
)
;
}
Imf
::
RgbaOutputFile
file
(
filename
,
W
,
H
,
Imf
::
WRITE_RGBA
);
file
.
setFrameBuffer
(
&
pixels
[
0
][
0
],
1
,
W
);
file
.
writePixels
(
H
);
#else
EXRHeader
header
;
InitEXRHeader
(
&
header
);
...
...
@@ -258,7 +183,6 @@ class t_EXR_IO
free
(
header
.
channels
);
free
(
header
.
pixel_types
);
free
(
header
.
requested_pixel_types
);
#endif
return
true
;
}
};
...
...
sources/plugins/data_io/SConscript
View file @
55788034
...
...
@@ -2,6 +2,10 @@ Import('env', 'openexr_available')
env
=
env
.
Clone
()
have_openexr
=
openexr_available
(
env
)
if
not
have_openexr
:
print
"<<ERROR>> Could not locate TinyEXR : EXR related plugins won't be built."
print
" Please use `git submodule init` and 'git submodule update` to get TinyEXR."
if
have_openexr
:
# Make sure we have the 'ImfStdIO.h' header, which OpenEXR 2.2.0
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment