Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

panda/src/pnmimagetypes/pnmFileTypeIMG.cxx

Go to the documentation of this file.
00001 // Filename: pnmFileTypeIMG.cxx
00002 // Created by:  drose (19Jun00)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) 2001, Disney Enterprises, Inc.  All rights reserved
00008 //
00009 // All use of this software is subject to the terms of the Panda 3d
00010 // Software license.  You should have received a copy of this license
00011 // along with this source code; you will also find a current copy of
00012 // the license at http://www.panda3d.org/license.txt .
00013 //
00014 // To contact the maintainers of this program write to
00015 // panda3d@yahoogroups.com .
00016 //
00017 ////////////////////////////////////////////////////////////////////
00018 
00019 #include "pnmFileTypeIMG.h"
00020 #include "config_pnmimagetypes.h"
00021 
00022 #include "pnmFileTypeRegistry.h"
00023 #include "bamReader.h"
00024 
00025 // Since raw image files don't have a magic number, we'll make a little
00026 // sanity check on the size of the image.  If either the width or height is
00027 // larger than this, it must be bogus.
00028 #define INSANE_SIZE 20000
00029 
00030 static const char * const extensions_img[] = {
00031   "img"
00032 };
00033 static const int num_extensions_img = sizeof(extensions_img) / sizeof(const char *);
00034 
00035 TypeHandle PNMFileTypeIMG::_type_handle;
00036 
00037 ////////////////////////////////////////////////////////////////////
00038 //     Function: PNMFileTypeIMG::Constructor
00039 //       Access: Public
00040 //  Description:
00041 ////////////////////////////////////////////////////////////////////
00042 PNMFileTypeIMG::
00043 PNMFileTypeIMG() {
00044 }
00045 
00046 ////////////////////////////////////////////////////////////////////
00047 //     Function: PNMFileTypeIMG::get_name
00048 //       Access: Public, Virtual
00049 //  Description: Returns a few words describing the file type.
00050 ////////////////////////////////////////////////////////////////////
00051 string PNMFileTypeIMG::
00052 get_name() const {
00053   return "Raw binary RGB";
00054 }
00055 
00056 ////////////////////////////////////////////////////////////////////
00057 //     Function: PNMFileTypeIMG::get_num_extensions
00058 //       Access: Public, Virtual
00059 //  Description: Returns the number of different possible filename
00060 //               extensions associated with this particular file type.
00061 ////////////////////////////////////////////////////////////////////
00062 int PNMFileTypeIMG::
00063 get_num_extensions() const {
00064   return num_extensions_img;
00065 }
00066 
00067 ////////////////////////////////////////////////////////////////////
00068 //     Function: PNMFileTypeIMG::get_extension
00069 //       Access: Public, Virtual
00070 //  Description: Returns the nth possible filename extension
00071 //               associated with this particular file type, without a
00072 //               leading dot.
00073 ////////////////////////////////////////////////////////////////////
00074 string PNMFileTypeIMG::
00075 get_extension(int n) const {
00076   nassertr(n >= 0 && n < num_extensions_img, string());
00077   return extensions_img[n];
00078 }
00079 
00080 ////////////////////////////////////////////////////////////////////
00081 //     Function: PNMFileTypeIMG::get_suggested_extension
00082 //       Access: Public, Virtual
00083 //  Description: Returns a suitable filename extension (without a
00084 //               leading dot) to suggest for files of this type, or
00085 //               empty string if no suggestions are available.
00086 ////////////////////////////////////////////////////////////////////
00087 string PNMFileTypeIMG::
00088 get_suggested_extension() const {
00089   return "img";
00090 }
00091 
00092 ////////////////////////////////////////////////////////////////////
00093 //     Function: PNMFileTypeIMG::make_reader
00094 //       Access: Public, Virtual
00095 //  Description: Allocates and returns a new PNMReader suitable for
00096 //               reading from this file type, if possible.  If reading
00097 //               from this file type is not supported, returns NULL.
00098 ////////////////////////////////////////////////////////////////////
00099 PNMReader *PNMFileTypeIMG::
00100 make_reader(istream *file, bool owns_file, const string &magic_number) {
00101   init_pnm();
00102   return new Reader(this, file, owns_file, magic_number);
00103 }
00104 
00105 ////////////////////////////////////////////////////////////////////
00106 //     Function: PNMFileTypeIMG::make_writer
00107 //       Access: Public, Virtual
00108 //  Description: Allocates and returns a new PNMWriter suitable for
00109 //               reading from this file type, if possible.  If writing
00110 //               files of this type is not supported, returns NULL.
00111 ////////////////////////////////////////////////////////////////////
00112 PNMWriter *PNMFileTypeIMG::
00113 make_writer(ostream *file, bool owns_file) {
00114   init_pnm();
00115   return new Writer(this, file, owns_file);
00116 }
00117 
00118 
00119 inline unsigned long
00120 read_ulong(istream *file) {
00121   unsigned long x;
00122   return pm_readbiglong(file, (long *)&x)==0 ? x : 0;
00123 }
00124 
00125 inline unsigned short
00126 read_ushort_IMG(istream *file) {
00127   unsigned short x;
00128   return pm_readbigshort(file, (short *)&x)==0 ? x : 0;
00129 }
00130 
00131 inline unsigned char
00132 read_uchar_IMG(istream *file) {
00133   int x;
00134   x = file->get();
00135   return (x!=EOF) ? (unsigned char)x : 0;
00136 }
00137 
00138 inline void
00139 write_ulong(ostream *file, unsigned long x) {
00140   pm_writebiglong(file, (long)x);
00141 }
00142 
00143 inline void
00144 write_ushort_IMG(ostream *file, unsigned long x) {
00145   pm_writebigshort(file, (short)(long)x);
00146 }
00147 
00148 inline void
00149 write_uchar_IMG(ostream *file, unsigned char x) {
00150   file->put(x);
00151 }
00152 
00153 ////////////////////////////////////////////////////////////////////
00154 //     Function: PNMFileTypeIMG::Reader::Constructor
00155 //       Access: Public
00156 //  Description:
00157 ////////////////////////////////////////////////////////////////////
00158 PNMFileTypeIMG::Reader::
00159 Reader(PNMFileType *type, istream *file, bool owns_file, string magic_number) :
00160   PNMReader(type, file, owns_file)
00161 {
00162   if (img_header_type == IHT_long) {
00163     if (!read_magic_number(_file, magic_number, 8)) {
00164       // Although raw IMG files have no magic number, they may have a
00165       // pair of ushorts or ulongs at the beginning to indicate the file
00166       // size.
00167       if (pnmimage_img_cat.is_debug()) {
00168         pnmimage_img_cat.debug()
00169           << "IMG image file appears to be empty.\n";
00170       }
00171       _is_valid = false;
00172       return;
00173     }
00174 
00175     _x_size =
00176       ((unsigned char)magic_number[0] << 24) |
00177       ((unsigned char)magic_number[1] << 16) |
00178       ((unsigned char)magic_number[2] << 8) |
00179       ((unsigned char)magic_number[3]);
00180 
00181     _y_size =
00182       ((unsigned char)magic_number[4] << 24) |
00183       ((unsigned char)magic_number[5] << 16) |
00184       ((unsigned char)magic_number[6] << 8) |
00185       ((unsigned char)magic_number[7]);
00186 
00187   } else if (img_header_type == IHT_short) {
00188     if (!read_magic_number(_file, magic_number, 4)) {
00189       if (pnmimage_img_cat.is_debug()) {
00190         pnmimage_img_cat.debug()
00191           << "IMG image file appears to be empty.\n";
00192       }
00193       _is_valid = false;
00194       return;
00195     }
00196 
00197     _x_size =
00198       ((unsigned char)magic_number[0] << 8) |
00199       ((unsigned char)magic_number[1]);
00200 
00201     _y_size =
00202       ((unsigned char)magic_number[2] << 8) |
00203       ((unsigned char)magic_number[3]);
00204 
00205   } else {
00206     _x_size = img_xsize;
00207     _y_size = img_ysize;
00208   }
00209 
00210   if (_x_size == 0 || _y_size == 0 ||
00211       _x_size > INSANE_SIZE || _y_size > INSANE_SIZE) {
00212     _is_valid = false;
00213     if (img_header_type == IHT_none) {
00214       pnmimage_img_cat.error()
00215         << "Must specify img-xsize and img-ysize to load headerless raw files.\n";
00216     } else {
00217       pnmimage_img_cat.debug()
00218         << "IMG file does not have a valid xsize,ysize header.\n";
00219     }
00220     return;
00221   }
00222 
00223   _maxval = 255;
00224   _num_channels = 3;
00225 
00226   if (pnmimage_img_cat.is_debug()) {
00227     pnmimage_img_cat.debug()
00228       << "Reading IMG " << *this << "\n";
00229   }
00230 }
00231 
00232 ////////////////////////////////////////////////////////////////////
00233 //     Function: PNMFileTypeIMG::Reader::supports_read_row
00234 //       Access: Public, Virtual
00235 //  Description: Returns true if this particular PNMReader supports a
00236 //               streaming interface to reading the data: that is, it
00237 //               is capable of returning the data one row at a time,
00238 //               via repeated calls to read_row().  Returns false if
00239 //               the only way to read from this file is all at once,
00240 //               via read_data().
00241 ////////////////////////////////////////////////////////////////////
00242 bool PNMFileTypeIMG::Reader::
00243 supports_read_row() const {
00244   return true;
00245 }
00246 
00247 ////////////////////////////////////////////////////////////////////
00248 //     Function: PNMFileTypeIMG::Reader::read_row
00249 //       Access: Public, Virtual
00250 //  Description: If supports_read_row(), above, returns true, this
00251 //               function may be called repeatedly to read the image,
00252 //               one horizontal row at a time, beginning from the top.
00253 //               Returns true if the row is successfully read, false
00254 //               if there is an error or end of file.
00255 ////////////////////////////////////////////////////////////////////
00256 bool PNMFileTypeIMG::Reader::
00257 read_row(xel *row_data, xelval *) {
00258   int x;
00259   xelval red, grn, blu;
00260   for (x = 0; x < _x_size; x++) {
00261     red = read_uchar_IMG(_file);
00262     grn = read_uchar_IMG(_file);
00263     blu = read_uchar_IMG(_file);
00264 
00265     PPM_ASSIGN(row_data[x], red, grn, blu);
00266   }
00267 
00268   return true;
00269 }
00270 
00271 ////////////////////////////////////////////////////////////////////
00272 //     Function: PNMFileTypeIMG::Writer::Constructor
00273 //       Access: Public
00274 //  Description:
00275 ////////////////////////////////////////////////////////////////////
00276 PNMFileTypeIMG::Writer::
00277 Writer(PNMFileType *type, ostream *file, bool owns_file) :
00278   PNMWriter(type, file, owns_file)
00279 {
00280 }
00281 
00282 ////////////////////////////////////////////////////////////////////
00283 //     Function: PNMFileTypeIMG::Writer::supports_write_row
00284 //       Access: Public, Virtual
00285 //  Description: Returns true if this particular PNMWriter supports a
00286 //               streaming interface to writing the data: that is, it
00287 //               is capable of writing the image one row at a time,
00288 //               via repeated calls to write_row().  Returns false if
00289 //               the only way to write from this file is all at once,
00290 //               via write_data().
00291 ////////////////////////////////////////////////////////////////////
00292 bool PNMFileTypeIMG::Writer::
00293 supports_write_row() const {
00294   return true;
00295 }
00296 
00297 ////////////////////////////////////////////////////////////////////
00298 //     Function: PNMFileTypeIMG::Writer::write_header
00299 //       Access: Public, Virtual
00300 //  Description: If supports_write_row(), above, returns true, this
00301 //               function may be called to write out the image header
00302 //               in preparation to writing out the image data one row
00303 //               at a time.  Returns true if the header is
00304 //               successfully written, false if there is an error.
00305 //
00306 //               It is the user's responsibility to fill in the header
00307 //               data via calls to set_x_size(), set_num_channels(),
00308 //               etc., or copy_header_from(), before calling
00309 //               write_header().
00310 ////////////////////////////////////////////////////////////////////
00311 bool PNMFileTypeIMG::Writer::
00312 write_header() {
00313   if (img_header_type == IHT_long) {
00314     write_ulong(_file, _x_size);
00315     write_ulong(_file, _y_size);
00316   } else if (img_header_type == IHT_short) {
00317     write_ushort_IMG(_file, _x_size);
00318     write_ushort_IMG(_file, _y_size);
00319   }
00320   return true;
00321 }
00322 
00323 ////////////////////////////////////////////////////////////////////
00324 //     Function: PNMFileTypeIMG::Writer::write_row
00325 //       Access: Public, Virtual
00326 //  Description: If supports_write_row(), above, returns true, this
00327 //               function may be called repeatedly to write the image,
00328 //               one horizontal row at a time, beginning from the top.
00329 //               Returns true if the row is successfully written,
00330 //               false if there is an error.
00331 //
00332 //               You must first call write_header() before writing the
00333 //               individual rows.  It is also important to delete the
00334 //               PNMWriter class after successfully writing the last
00335 //               row.  Failing to do this may result in some data not
00336 //               getting flushed!
00337 ////////////////////////////////////////////////////////////////////
00338 bool PNMFileTypeIMG::Writer::
00339 write_row(xel *row_data, xelval *) {
00340   int x;
00341   for (x = 0; x < _x_size; x++) {
00342     write_uchar_IMG(_file, (unsigned char)(255*PPM_GETR(row_data[x])/_maxval));
00343     write_uchar_IMG(_file, (unsigned char)(255*PPM_GETG(row_data[x])/_maxval));
00344     write_uchar_IMG(_file, (unsigned char)(255*PPM_GETB(row_data[x])/_maxval));
00345   }
00346 
00347   return true;
00348 }
00349 
00350 
00351 
00352 ////////////////////////////////////////////////////////////////////
00353 //     Function: PNMFileTypeIMG::register_with_read_factory
00354 //       Access: Public, Static
00355 //  Description: Registers the current object as something that can be
00356 //               read from a Bam file.
00357 ////////////////////////////////////////////////////////////////////
00358 void PNMFileTypeIMG::
00359 register_with_read_factory() {
00360   BamReader::get_factory()->
00361     register_factory(get_class_type(), make_PNMFileTypeIMG);
00362 }
00363 
00364 ////////////////////////////////////////////////////////////////////
00365 //     Function: PNMFileTypeIMG::make_PNMFileTypeIMG
00366 //       Access: Protected, Static
00367 //  Description: This method is called by the BamReader when an object
00368 //               of this type is encountered in a Bam file; it should
00369 //               allocate and return a new object with all the data
00370 //               read.
00371 //
00372 //               In the case of the PNMFileType objects, since these
00373 //               objects are all shared, we just pull the object from
00374 //               the registry.
00375 ////////////////////////////////////////////////////////////////////
00376 TypedWritable *PNMFileTypeIMG::
00377 make_PNMFileTypeIMG(const FactoryParams &params) {
00378   return PNMFileTypeRegistry::get_ptr()->get_type_by_handle(get_class_type());
00379 }

Generated on Fri May 2 00:43:16 2003 for Panda by doxygen1.3