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.