imgfile.cc

Go to the documentation of this file.
00001 
00003 
00004 //
00005 // Copyright (c) 2002-2004 California Institute of Technology
00006 // Copyright (c) 2004-2007 University of Southern California
00007 // Rob Peters <rjpeters at usc dot edu>
00008 //
00009 // created: Thu Apr 25 09:06:51 2002
00010 // commit: $Id: imgfile.cc 10065 2007-04-12 05:54:56Z rjpeters $
00011 // $HeadURL: file:///lab/rjpeters/svnrepo/code/trunk/groovx/src/media/imgfile.cc $
00012 //
00013 // --------------------------------------------------------------------
00014 //
00015 // This file is part of GroovX.
00016 //   [http://ilab.usc.edu/rjpeters/groovx/]
00017 //
00018 // GroovX is free software; you can redistribute it and/or modify it
00019 // under the terms of the GNU General Public License as published by
00020 // the Free Software Foundation; either version 2 of the License, or
00021 // (at your option) any later version.
00022 //
00023 // GroovX is distributed in the hope that it will be useful, but
00024 // WITHOUT ANY WARRANTY; without even the implied warranty of
00025 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00026 // General Public License for more details.
00027 //
00028 // You should have received a copy of the GNU General Public License
00029 // along with GroovX; if not, write to the Free Software Foundation,
00030 // Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
00031 //
00033 
00034 #ifndef GROOVX_MEDIA_IMGFILE_CC_UTC20050626084018_DEFINED
00035 #define GROOVX_MEDIA_IMGFILE_CC_UTC20050626084018_DEFINED
00036 
00037 #include "imgfile.h"
00038 
00039 #include "media/jpegparser.h"
00040 #include "media/pngparser.h"
00041 #include "media/pnmparser.h"
00042 
00043 #include "nub/log.h"
00044 
00045 #include "rutz/error.h"
00046 #include "rutz/pipe.h"
00047 #include "rutz/sfmt.h"
00048 
00049 #include <cctype>
00050 #include <iterator>
00051 #include <vector>
00052 
00053 #include "rutz/trace.h"
00054 
00055 using rutz::fstring;
00056 
00057 namespace
00058 {
00059   fstring tolower(const char* inp)
00060   {
00061     std::vector<char> result;
00062 
00063     while (*inp != '\0')
00064       {
00065         result.push_back(char(std::tolower(*inp++)));
00066       }
00067 
00068     result.push_back('\0');
00069 
00070     return fstring(&result[0]);
00071   }
00072 
00073   enum image_file_type
00074     {
00075       UNKNOWN,
00076       JPEG,
00077       PNM,
00078       PNG,
00079       GIF
00080     };
00081 
00082   image_file_type get_image_file_type(const char* filename)
00083   {
00084     // Conver to lowercase so we can do case-insensitive tests of the
00085     // filename extension.
00086     fstring lowername(tolower(filename));
00087 
00088     if (lowername.ends_with(".pbm")
00089         || lowername.ends_with(".pgm")
00090         || lowername.ends_with(".ppm")
00091         || lowername.ends_with(".pnm")
00092         || lowername.ends_with(".pbm.gz")
00093         || lowername.ends_with(".pgm.gz")
00094         || lowername.ends_with(".ppm.gz")
00095         || lowername.ends_with(".pnm.gz"))
00096       {
00097         return PNM;
00098       }
00099     else if (lowername.ends_with(".png"))
00100       {
00101         return PNG;
00102       }
00103     else if (lowername.ends_with(".jpg")
00104              || lowername.ends_with(".jpeg"))
00105       {
00106         return JPEG;
00107       }
00108     else if (lowername.ends_with(".gif"))
00109       {
00110         return GIF;
00111       }
00112     // else...
00113     return UNKNOWN;
00114   }
00115 
00116   // A fallback function to try to read an image by filtering it
00117   // through a pipe that will convert it to PNM format.
00118   void pipe_load(const char* progname,
00119                  const char* filename, media::bmap_data& data)
00120   {
00121   GVX_TRACE("<imgfile.cc>::pipe_load");
00122 
00123     if (access(progname, R_OK|X_OK) != 0)
00124       throw rutz::error(rutz::sfmt("couldn't access program '%s'", progname), SRC_POS);
00125     if (access(filename, R_OK)      != 0)
00126       throw rutz::error(rutz::sfmt("couldn't read file '%s'", filename), SRC_POS);
00127 
00128     std::vector<char> nm_copy;
00129     std::copy(filename, filename+strlen(filename)+1,
00130               std::back_inserter(nm_copy));
00131     char* const argv[] = { (char*) progname, &nm_copy[0], (char*) 0 };
00132 
00133     rutz::exec_pipe p("r", argv);
00134 
00135     media::load_pnm(p.stream(), data);
00136 
00137     if (p.exit_status() != 0)
00138       throw rutz::error("child process exited abnormally", SRC_POS);
00139   }
00140 }
00141 
00142 void media::load_image(const char* filename, media::bmap_data& data)
00143 {
00144 GVX_TRACE("media::load_image");
00145 
00146   switch (get_image_file_type(filename))
00147     {
00148     case PNM:  media::load_pnm(filename, data); break;
00149     case PNG:  media::load_png(filename, data); break;
00150     case JPEG: media::load_jpeg(filename, data); break;
00151 #ifdef GVX_GIFTOPNM_PROG
00152     case GIF:  pipe_load(GVX_GIFTOPNM_PROG, filename, data); break;
00153 #endif
00154 #ifdef GVX_ANYTOPNM_PROG
00155       // A fallback to try to read just about any image type, given
00156       // that the program "anytopnm" is installed on the host
00157       // machine. In that case, we can process the image file with
00158       // anytopnm, and pipe the output via a stream into a pnm parser.
00159     default:   pipe_load(GVX_ANYTOPNM_PROG, filename, data); break;
00160 #else
00161     default:   throw rutz::error(rutz::sfmt("unknown image file format: %s",
00162                                             filename), SRC_POS);
00163       break;
00164 #endif
00165     }
00166 
00167   nub::log(rutz::sfmt("loaded image file %s", filename));
00168 }
00169 
00170 void media::save_image(const char* filename,
00171                        const media::bmap_data& data)
00172 {
00173   switch (get_image_file_type(filename))
00174     {
00175     case PNM:  media::save_pnm(filename, data); break;
00176     case PNG:  media::save_png(filename, data); break;
00177     default:
00178       throw rutz::error(rutz::sfmt("unknown file format: %s", filename),
00179                         SRC_POS);
00180     }
00181 
00182   nub::log(rutz::sfmt("saved image file %s", filename));
00183 }
00184 
00185 static const char __attribute__((used)) vcid_groovx_media_imgfile_cc_utc20050626084018[] = "$Id: imgfile.cc 10065 2007-04-12 05:54:56Z rjpeters $ $HeadURL: file:
00186 #endif // !GROOVX_MEDIA_IMGFILE_CC_UTC20050626084018_DEFINED

The software described here is Copyright (c) 1998-2005, Rob Peters.
This page was generated Wed Dec 3 06:49:39 2008 by Doxygen version 1.5.5.