core/vil/vil_save.cxx
Go to the documentation of this file.
00001 // This is core/vil/vil_save.cxx
00002 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00003 #pragma implementation
00004 #endif
00005 //:
00006 // \file
00007 //
00008 // \verbatim
00009 //  Modifications
00010 //   23 Oct.2003 - Peter Vanroose - Added support for 64-bit int pixels
00011 // \endverbatim
00012 
00013 #include "vil_save.h"
00014 
00015 #include <vcl_cctype.h>
00016 #include <vcl_cstring.h>
00017 #include <vcl_string.h>
00018 #include <vcl_iostream.h>
00019 #include <vxl_config.h> // for vxl_byte
00020 
00021 #include <vil/vil_open.h>
00022 #include <vil/vil_new.h>
00023 #include <vil/vil_copy.h>
00024 #include <vil/vil_pixel_format.h>
00025 #include <vil/vil_image_resource.h>
00026 #include <vil/vil_image_view.h>
00027 
00028 
00029 //: Send vil_image to disk.
00030 bool vil_save(const vil_image_view_base &im, char const* filename, char const* file_format)
00031 {
00032   vil_stream* os = vil_open(filename, "w");
00033   if (!os || !os->ok()) {
00034     vcl_cerr << __FILE__ ": Invalid stream for \"" << filename << "\"\n";
00035     return false;
00036   }
00037   vil_image_resource_sptr out = vil_new_image_resource(os, im.ni(), im.nj(),
00038                                                        im.nplanes() * vil_pixel_format_num_components(im.pixel_format()),
00039                                                        vil_pixel_format_component_format(im.pixel_format()), file_format);
00040   if (!out) {
00041     vcl_cerr << __FILE__ ": (vil_save) Cannot save to type [" << file_format << "]\n";
00042     return false;
00043   }
00044 
00045   // Use smart copy constructor to convert multi-component images
00046   // into multi-plane ones.
00047   switch (vil_pixel_format_component_format(im.pixel_format()))
00048   {
00049   case VIL_PIXEL_FORMAT_BYTE:
00050     return out->put_view(vil_image_view<vxl_byte>(im),0,0);
00051   case VIL_PIXEL_FORMAT_UINT_16:
00052     return out->put_view(vil_image_view<vxl_uint_16>(im),0,0);
00053   case VIL_PIXEL_FORMAT_INT_16:
00054     return out->put_view(vil_image_view<vxl_int_16>(im),0,0);
00055   case VIL_PIXEL_FORMAT_UINT_32:
00056     return out->put_view(vil_image_view<vxl_uint_32>(im),0,0);
00057   case VIL_PIXEL_FORMAT_INT_32:
00058     return out->put_view(vil_image_view<vxl_int_32>(im),0,0);
00059 #if VXL_HAS_INT_64
00060   case VIL_PIXEL_FORMAT_UINT_64:
00061     return out->put_view(vil_image_view<vxl_uint_64>(im),0,0);
00062   case VIL_PIXEL_FORMAT_INT_64:
00063     return out->put_view(vil_image_view<vxl_int_64>(im),0,0);
00064 #endif
00065   case VIL_PIXEL_FORMAT_FLOAT:
00066     return out->put_view(vil_image_view<float>(im),0,0);
00067   case VIL_PIXEL_FORMAT_BOOL:
00068     return out->put_view(vil_image_view<bool>(im),0,0);
00069   case VIL_PIXEL_FORMAT_SBYTE:
00070     return out->put_view(vil_image_view<vxl_sbyte>(im),0,0);
00071   case VIL_PIXEL_FORMAT_DOUBLE:
00072     return out->put_view(vil_image_view<double>(im),0,0);
00073   default:
00074     // In case any one has an odd pixel format that actually works with this file_format.
00075     return out->put_view(im, 0, 0);
00076   }
00077 }
00078 
00079 
00080 char const *vil_save_guess_file_format(char const* filename)
00081 {
00082   char const *file_format = "pnm"; // default file format
00083 
00084   // find last "."
00085   char const *dot = vcl_strrchr(filename, '.');
00086   if (!dot) {
00087     // filename doesn't end in ".anything"
00088     vcl_cerr << __FILE__ ": assuming pnm format for \'" << filename << "\'\n";
00089     file_format = "pnm";
00090   }
00091   else {
00092     vcl_string ext_lower_case(dot);  // make a copy to convert the extension to lower case
00093     for (unsigned int i=0; i<ext_lower_case.size(); ++i)
00094       ext_lower_case[i] = (char)vcl_tolower(ext_lower_case[i]);
00095     // translate common extensions into known file formats.
00096     if (false) { }
00097 #define macro(ext, fmt) else if ( ext_lower_case == "." #ext ) file_format = #fmt
00098     macro(tiff, tiff);
00099     macro(tif, tiff);
00100     macro(png, png);
00101     macro(bmp, bmp);
00102     macro(pbm, pnm);
00103     macro(pgm, pnm);
00104     macro(ppm, pnm);
00105     macro(pnm, pnm);
00106     macro(jpg, jpeg);
00107     macro(jpeg, jpeg);
00108     macro(iris, iris);
00109     macro(rgb, iris);
00110     macro(viff, viff);
00111     macro(mit, mit);
00112     macro(v2i, v2i);
00113 #undef macro
00114     else
00115       vcl_cerr << __FILE__ ": assuming pnm format for \'" << filename << "\'\n";
00116   }
00117 
00118   return file_format;
00119 }
00120 
00121 //: save to file, deducing format from filename.
00122 bool vil_save(const vil_image_view_base & i, char const* filename)
00123 {
00124   return vil_save(i, filename, vil_save_guess_file_format(filename));
00125 }
00126 
00127 //: Send vil_image to disk.
00128 bool vil_save_image_resource(const vil_image_resource_sptr &ir, char const* filename,
00129                              char const* file_format)
00130 {
00131   vil_stream* os = vil_open(filename, "w");
00132   if (!os || !os->ok()) {
00133     vcl_cerr << __FILE__ ": Invalid stream for \"" << filename << "\"\n";
00134     return false;
00135   }
00136   vil_image_resource_sptr out = vil_new_image_resource(os, ir->ni(), ir->nj(),
00137                                                        ir->nplanes(),
00138                                                       ir->pixel_format(), file_format);
00139   if (!out) {
00140     vcl_cerr << __FILE__ ": (vil_save) Cannot save to type [" << file_format << "]\n";
00141     return false;
00142   }
00143   return vil_copy_deep(ir, out);
00144 }
00145 
00146 //: save to file, deducing format from filename.
00147 bool vil_save_image_resource(const vil_image_resource_sptr &ir, char const* filename)
00148 {
00149   return vil_save_image_resource(ir, filename, vil_save_guess_file_format(filename));
00150 }
00151 
00152 
00153 
00154 #if defined(VCL_WIN32) && VXL_USE_WIN_WCHAR_T
00155 //  --------------------------------------------------------------------------------
00156 //  Windows' wchar_t overloading version
00157 //
00158 //
00159 
00160 
00161 //: Send vil_image to disk.
00162 bool vil_save(const vil_image_view_base &im, wchar_t const* filename, wchar_t const* file_format)
00163 {
00164   vil_stream* os = vil_open(filename, "w");
00165   if (!os || !os->ok()) {
00166     std::wcerr << __FILE__ ": Invalid stream for \"" << filename << "\"\n";
00167     return false;
00168   }
00169   vil_image_resource_sptr out = vil_new_image_resource(os, im.ni(), im.nj(),
00170                                                        im.nplanes() * vil_pixel_format_num_components(im.pixel_format()),
00171                                                        vil_pixel_format_component_format(im.pixel_format()), file_format);
00172   if (!out) {
00173     std::wcerr << __FILE__ ": (vil_save) Cannot save to type [" << file_format << "]\n";
00174     return false;
00175   }
00176 
00177   // Use smart copy constructor to convert multi-component images
00178   // into multi-plane ones.
00179   switch (vil_pixel_format_component_format(im.pixel_format()))
00180   {
00181   case VIL_PIXEL_FORMAT_BYTE:
00182     return out->put_view(vil_image_view<vxl_byte>(im),0,0);
00183   case VIL_PIXEL_FORMAT_UINT_16:
00184     return out->put_view(vil_image_view<vxl_uint_16>(im),0,0);
00185   case VIL_PIXEL_FORMAT_INT_16:
00186     return out->put_view(vil_image_view<vxl_int_16>(im),0,0);
00187   case VIL_PIXEL_FORMAT_UINT_32:
00188     return out->put_view(vil_image_view<vxl_uint_32>(im),0,0);
00189   case VIL_PIXEL_FORMAT_INT_32:
00190     return out->put_view(vil_image_view<vxl_int_32>(im),0,0);
00191 #if VXL_HAS_INT_64
00192   case VIL_PIXEL_FORMAT_UINT_64:
00193     return out->put_view(vil_image_view<vxl_uint_64>(im),0,0);
00194   case VIL_PIXEL_FORMAT_INT_64:
00195     return out->put_view(vil_image_view<vxl_int_64>(im),0,0);
00196 #endif
00197   case VIL_PIXEL_FORMAT_FLOAT:
00198     return out->put_view(vil_image_view<float>(im),0,0);
00199   case VIL_PIXEL_FORMAT_BOOL:
00200     return out->put_view(vil_image_view<bool>(im),0,0);
00201   case VIL_PIXEL_FORMAT_SBYTE:
00202     return out->put_view(vil_image_view<vxl_sbyte>(im),0,0);
00203   case VIL_PIXEL_FORMAT_DOUBLE:
00204     return out->put_view(vil_image_view<double>(im),0,0);
00205   default:
00206     // In case any one has an odd pixel format that actually works with this file_format.
00207     return out->put_view(im, 0, 0);
00208   }
00209 }
00210 
00211 
00212 wchar_t const *vil_save_guess_file_format(wchar_t const* filename)
00213 {
00214   wchar_t const *file_format = L"pnm"; // default file format
00215 
00216   // find last "."
00217   wchar_t const *dot = wcsrchr(filename, L'.');
00218   if (!dot) {
00219     // filename doesn't end in ".anything"
00220     std::wcerr << __FILE__ ": assuming pnm format for \'" << filename << "\'\n";
00221     file_format = L"pnm";
00222   }
00223   else {
00224     std::wstring ext_lower_case(dot);  // make a copy to convert the extension to lower case
00225     for(unsigned int i=0; i<ext_lower_case.size(); ++i)
00226       ext_lower_case[i] = towlower(ext_lower_case[i]);
00227     // translate common extensions into known file formats.
00228     if (false) { }
00229 #define macro(ext, fmt) else if ( ext_lower_case == L"." L#ext ) file_format = L#fmt
00230     macro(tiff, tiff);
00231     macro(tif, tiff);
00232     macro(png, png);
00233     macro(bmp, bmp);
00234     macro(pbm, pnm);
00235     macro(pgm, pnm);
00236     macro(ppm, pnm);
00237     macro(pnm, pnm);
00238     macro(jpg, jpeg);
00239     macro(jpeg, jpeg);
00240     macro(iris, iris);
00241     macro(rgb, iris);
00242     macro(viff, viff);
00243     macro(mit, mit);
00244     macro(v2i, v2i);
00245 #undef macro
00246     else
00247       std::wcerr << __FILE__ ": assuming pnm format for \'" << filename << "\'\n";
00248   }
00249 
00250   return file_format;
00251 }
00252 
00253 //: save to file, deducing format from filename.
00254 bool vil_save(const vil_image_view_base & i, wchar_t const* filename)
00255 {
00256   return vil_save(i, filename, vil_save_guess_file_format(filename));
00257 }
00258 
00259 //: Send vil_image to disk.
00260 bool vil_save_image_resource(const vil_image_resource_sptr &ir, wchar_t const* filename,
00261                              wchar_t const* file_format)
00262 {
00263   vil_stream* os = vil_open(filename, "w");
00264   if (!os || !os->ok()) {
00265     std::wcerr << __FILE__ ": Invalid stream for \"" << filename << "\"\n";
00266     return false;
00267   }
00268   vil_image_resource_sptr out = vil_new_image_resource(os, ir->ni(), ir->nj(),
00269                                                        ir->nplanes(),
00270                                                        ir->pixel_format(), file_format);
00271   if (!out) {
00272     std::wcerr << __FILE__ ": (vil_save) Cannot save to type [" << file_format << "]\n";
00273     return false;
00274   }
00275   return vil_copy_deep(ir, out);
00276 }
00277 
00278 //: save to file, deducing format from filename.
00279 bool vil_save_image_resource(const vil_image_resource_sptr &ir, wchar_t const* filename)
00280 {
00281   return vil_save_image_resource(ir, filename, vil_save_guess_file_format(filename));
00282 }
00283 
00284 #endif //defined(VCL_WIN32) && VXL_USE_WIN_WCHAR_T
00285