24 #include <ImfOutputFile.h> 25 #include <ImfChannelList.h> 26 #include <ImfVersion.h> 29 #ifndef IMATH_NAMESPACE 30 #define IMATH_NAMESPACE Imath 39 static const char *
const extensions_exr[] = {
42 static const int num_extensions_exr =
sizeof(extensions_exr) /
sizeof(
const char *);
45 class ImfStdOstream :
public IMF::OStream {
47 ImfStdOstream(std::ostream &strm) : IMF::OStream(
"ostream"), _strm(strm) {}
49 virtual void write(
const char c[],
int n) {
53 virtual IMF::Int64 tellp() {
57 virtual void seekp(IMF::Int64 pos) {
66 class ImfStdIstream :
public IMF::IStream {
68 ImfStdIstream(std::istream &strm,
const std::string &magic_number) : IMF::IStream(
"istream"), _strm(strm) {
70 for (std::string::const_reverse_iterator mi = magic_number.rbegin();
71 mi != magic_number.rend();
77 virtual bool isMemoryMapped ()
const {
81 virtual bool read (
char c[],
int n) {
83 if (_strm.gcount() != n) {
84 throw std::exception();
87 bool not_eof = !_strm.eof();
91 virtual IMF::Int64 tellg() {
95 virtual void seekg(IMF::Int64 pos) {
99 virtual void clear() {
114 string PNMFileTypeEXR::
124 get_num_extensions()
const {
125 return num_extensions_exr;
132 string PNMFileTypeEXR::
133 get_extension(
int n)
const {
134 nassertr(n >= 0 && n < num_extensions_exr,
string());
135 return extensions_exr[n];
142 string PNMFileTypeEXR::
143 get_suggested_extension()
const {
151 bool PNMFileTypeEXR::
152 has_magic_number()
const {
161 bool PNMFileTypeEXR::
162 matches_magic_number(
const string &magic_number)
const {
163 nassertr(magic_number.size() >= 2,
false);
165 if (magic_number.size() >= 4) {
168 return IMF::isImfMagic(magic_number.data());
171 return magic_number[0] == ((IMF::MAGIC >> 0) & 0x00ff) &&
172 magic_number[1] == ((IMF::MAGIC >> 8) & 0x00ff);
182 make_reader(istream *file,
bool owns_file,
const string &magic_number) {
184 return new Reader(
this, file, owns_file, magic_number);
193 make_writer(ostream *file,
bool owns_file) {
195 return new Writer(
this, file, owns_file);
201 PNMFileTypeEXR::Reader::
202 Reader(
PNMFileType *type, istream *file,
bool owns_file,
string magic_number) :
204 _strm(new ImfStdIstream(*_file, magic_number)),
207 const IMF::Header &header = _imf_file.header();
209 IMATH_NAMESPACE::Box2i dw = header.dataWindow();
210 _x_size = dw.max.x - dw.min.x + 1;
211 _y_size = dw.max.y - dw.min.y + 1;
215 _channel_names.clear();
217 const IMF::ChannelList &channels = header.channels();
223 const char *possible_channel_names[] = {
"R",
"G",
"B",
"Y",
"A",
nullptr };
224 for (
const char **pni = possible_channel_names; *pni !=
nullptr; ++pni) {
225 std::string name = *pni;
226 IMF::ChannelList::ConstIterator ci = channels.find(name.c_str());
227 if (ci != channels.end()) {
229 if (name ==
"Y" && !_channel_names.empty()) {
233 _channel_names.push_back(name);
238 if (_channel_names.empty()) {
243 _channel_names.push_back(
"R");
244 _channel_names.push_back(
"G");
245 _channel_names.push_back(
"B");
248 _num_channels = (int)_channel_names.size();
249 if (_num_channels == 0 || _num_channels > 4) {
263 PNMFileTypeEXR::Reader::
273 bool PNMFileTypeEXR::Reader::
274 is_floating_point() {
285 bool PNMFileTypeEXR::Reader::
287 pfm.
clear(_x_size, _y_size, _num_channels);
291 PN_float32 *table_data = table.data();
293 size_t y_stride = x_stride * pfm.
get_x_size();
294 nassertr(y_stride * pfm.
get_y_size() <= table.size() *
sizeof(PN_float32),
false);
296 const IMF::Header &header = _imf_file.header();
297 IMATH_NAMESPACE::Box2i dw = header.dataWindow();
299 IMF::FrameBuffer frameBuffer;
302 frameBuffer.insert(_channel_names[ci].c_str(),
303 IMF::Slice(IMF::FLOAT, base, x_stride, y_stride,
307 _imf_file.setFrameBuffer(frameBuffer);
310 _imf_file.readPixels(dw.min.y, dw.max.y);
311 }
catch (
const std::exception &exc) {
312 pnmimage_exr_cat.error()
313 << exc.what() <<
"\n";
330 int PNMFileTypeEXR::Reader::
331 read_data(
xel *array, xelval *alpha) {
341 PNMFileTypeEXR::Writer::
342 Writer(
PNMFileType *type, ostream *file,
bool owns_file) :
352 bool PNMFileTypeEXR::Writer::
353 supports_floating_point() {
362 bool PNMFileTypeEXR::Writer::
371 bool PNMFileTypeEXR::Writer::
372 write_pfm(
const PfmFile &pfm) {
373 const vector_float &table = pfm.
get_table();
374 const PN_float32 *table_data = table.data();
376 size_t y_stride = x_stride * pfm.
get_x_size();
377 nassertr(y_stride * pfm.
get_y_size() <= table.size() *
sizeof(PN_float32),
false);
379 const char *channel_names_1[] = {
"G" };
380 const char *channel_names_2[] = {
"G",
"A" };
381 const char *channel_names_3[] = {
"R",
"G",
"B" };
382 const char *channel_names_4[] = {
"R",
"G",
"B",
"A" };
383 const char **channel_names =
nullptr;
387 channel_names = channel_names_1;
391 channel_names = channel_names_2;
395 channel_names = channel_names_3;
399 channel_names = channel_names_4;
408 header.channels().insert(channel_names[ci], IMF::Channel(IMF::FLOAT));
411 IMF::FrameBuffer frameBuffer;
413 const char *base = (
const char *)(table_data + ci);
414 frameBuffer.insert(channel_names[ci],
415 IMF::Slice(IMF::FLOAT, (
char *)base, x_stride, y_stride));
418 ImfStdOstream strm(*_file);
419 IMF::OutputFile file(strm, header);
420 file.setFrameBuffer(frameBuffer);
424 }
catch (
const std::exception &exc) {
425 pnmimage_exr_cat.error()
426 << exc.what() <<
"\n";
449 int PNMFileTypeEXR::Writer::
450 write_data(
xel *array, xelval *alpha) {
460 void PNMFileTypeEXR::
461 register_with_read_factory() {
463 register_factory(get_class_type(), make_PNMFileTypeEXR);
479 #endif // HAVE_OPENEXR PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
Base class for objects that can be written to and read from Bam files.
This is the base class of a family of classes that represent particular image file types that PNMImag...
static PNMFileTypeRegistry * get_global_ptr()
Returns a pointer to the global PNMFileTypeRegistry object.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void swap_table(vector_float &table)
This is a very low-level function that completely exchanges the PfmFile's internal table of floating-...
Defines a pfm file, a 2-d table of floating-point numbers, either 3-component or 1-component,...
An instance of this class is passed to the Factory when requesting it to do its business and construc...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
const vector_float & get_table() const
This is a very low-level function that returns a read-only reference to the internal table of floatin...
PNMFileType * get_type_by_handle(TypeHandle handle) const
Returns the PNMFileType instance stored in the registry for the given TypeHandle, e....
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This is an abstract base class that defines the interface for reading image files of various types.
This is an abstract base class that defines the interface for writing image files of various types.
static WritableFactory * get_factory()
Returns the global WritableFactory for generating TypedWritable objects.
TypeHandle is the identifier used to differentiate C++ class types.
void clear()
Eliminates all data in the file.