vil_save.cxx
Go to the documentation of this file.
1 // This is core/vil/vil_save.cxx
2 //:
3 // \file
4 //
5 // \verbatim
6 // Modifications
7 // 23 Oct.2003 - Peter Vanroose - Added support for 64-bit int pixels
8 // \endverbatim
9 
10 #include <cctype>
11 #include <cstring>
12 #include <string>
13 #include <iostream>
14 #include "vil_save.h"
15 
16 #ifdef _MSC_VER
17 # include <vcl_msvc_warnings.h>
18 #endif
19 #include <vxl_config.h> // for vxl_byte
20 
21 #include <vil/vil_open.h>
22 #include <vil/vil_new.h>
23 #include <vil/vil_copy.h>
24 #include <vil/vil_pixel_format.h>
25 #include <vil/vil_image_resource.h>
26 #include <vil/vil_image_view.h>
27 
28 
29 //: Send vil_image to disk.
30 bool vil_save(const vil_image_view_base &im, char const* filename, char const* file_format)
31 {
32  vil_stream* os = vil_open(filename, "w");
33  if (!os || !os->ok()) {
34  std::cerr << __FILE__ ": Invalid stream for \"" << filename << "\"\n";
35  return false;
36  }
40  if (!out) {
41  std::cerr << __FILE__ ": (vil_save) Cannot save to type [" << file_format << "]\n";
42  return false;
43  }
44 
45  // Use smart copy constructor to convert multi-component images
46  // into multi-plane ones.
48  {
50  return out->put_view(vil_image_view<vxl_byte>(im),0,0);
52  return out->put_view(vil_image_view<vxl_uint_16>(im),0,0);
54  return out->put_view(vil_image_view<vxl_int_16>(im),0,0);
56  return out->put_view(vil_image_view<vxl_uint_32>(im),0,0);
58  return out->put_view(vil_image_view<vxl_int_32>(im),0,0);
59 #if VXL_HAS_INT_64
60  case VIL_PIXEL_FORMAT_UINT_64:
61  return out->put_view(vil_image_view<vxl_uint_64>(im),0,0);
62  case VIL_PIXEL_FORMAT_INT_64:
63  return out->put_view(vil_image_view<vxl_int_64>(im),0,0);
64 #endif
66  return out->put_view(vil_image_view<float>(im),0,0);
68  return out->put_view(vil_image_view<bool>(im),0,0);
70  return out->put_view(vil_image_view<vxl_sbyte>(im),0,0);
72  return out->put_view(vil_image_view<double>(im),0,0);
73  default:
74  // In case any one has an odd pixel format that actually works with this file_format.
75  return out->put_view(im, 0, 0);
76  }
77 }
78 
79 
80 char const *vil_save_guess_file_format(char const* filename)
81 {
82  char const *file_format = "pnm"; // default file format
83 
84  // find last "."
85  char const *dot = std::strrchr(filename, '.');
86  if (!dot) {
87  // filename doesn't end in ".anything"
88  std::cerr << __FILE__ ": assuming pnm format for \'" << filename << "\'\n";
89  file_format = "pnm";
90  }
91  else {
92  std::string ext_lower_case(dot); // make a copy to convert the extension to lower case
93  for (char & i : ext_lower_case)
94  i = (char)std::tolower(i);
95  // translate common extensions into known file formats.
96  if (false) { }
97 #define macro(ext, fmt) else if ( ext_lower_case == "." #ext ) file_format = #fmt
98  macro(tiff, tiff);
99  macro(tif, tiff);
100  macro(png, png);
101  macro(bmp, bmp);
102  macro(pbm, pnm);
103  macro(pgm, pnm);
104  macro(ppm, pnm);
105  macro(pnm, pnm);
106  macro(jpg, jpeg);
107  macro(jpeg, jpeg);
108  macro(iris, iris);
109  macro(rgb, iris);
110  macro(viff, viff);
111  macro(mit, mit);
112  macro(v2i, v2i);
113  macro(sgi, sgi);
114 #undef macro
115  else
116  std::cerr << __FILE__ ": assuming pnm format for \'" << filename << "\'\n";
117  }
118 
119  return file_format;
120 }
121 
122 //: save to file, deducing format from filename.
123 bool vil_save(const vil_image_view_base & i, char const* filename)
124 {
125  return vil_save(i, filename, vil_save_guess_file_format(filename));
126 }
127 
128 //: Send vil_image to disk.
129 bool vil_save_image_resource(const vil_image_resource_sptr &ir, char const* filename,
130  char const* file_format)
131 {
132  vil_stream* os = vil_open(filename, "w");
133  if (!os || !os->ok()) {
134  std::cerr << __FILE__ ": Invalid stream for \"" << filename << "\"\n";
135  return false;
136  }
137  vil_image_resource_sptr out = vil_new_image_resource(os, ir->ni(), ir->nj(),
138  ir->nplanes(),
139  ir->pixel_format(), file_format);
140  if (!out) {
141  std::cerr << __FILE__ ": (vil_save) Cannot save to type [" << file_format << "]\n";
142  return false;
143  }
144  return vil_copy_deep(ir, out);
145 }
146 
147 //: save to file, deducing format from filename.
148 bool vil_save_image_resource(const vil_image_resource_sptr &ir, char const* filename)
149 {
150  return vil_save_image_resource(ir, filename, vil_save_guess_file_format(filename));
151 }
152 
153 
154 
155 #if defined(_WIN32) && VXL_USE_WIN_WCHAR_T
156 // --------------------------------------------------------------------------------
157 // Windows' wchar_t overloading version
158 //
159 //
160 
161 
162 //: Send vil_image to disk.
163 bool vil_save(const vil_image_view_base &im, wchar_t const* filename, wchar_t const* file_format)
164 {
165  vil_stream* os = vil_open(filename, "w");
166  if (!os || !os->ok()) {
167  std::wcerr << __FILE__ ": Invalid stream for \"" << filename << "\"\n";
168  return false;
169  }
173  if (!out) {
174  std::wcerr << __FILE__ ": (vil_save) Cannot save to type [" << file_format << "]\n";
175  return false;
176  }
177 
178  // Use smart copy constructor to convert multi-component images
179  // into multi-plane ones.
181  {
183  return out->put_view(vil_image_view<vxl_byte>(im),0,0);
185  return out->put_view(vil_image_view<vxl_uint_16>(im),0,0);
187  return out->put_view(vil_image_view<vxl_int_16>(im),0,0);
189  return out->put_view(vil_image_view<vxl_uint_32>(im),0,0);
191  return out->put_view(vil_image_view<vxl_int_32>(im),0,0);
192 #if VXL_HAS_INT_64
193  case VIL_PIXEL_FORMAT_UINT_64:
194  return out->put_view(vil_image_view<vxl_uint_64>(im),0,0);
195  case VIL_PIXEL_FORMAT_INT_64:
196  return out->put_view(vil_image_view<vxl_int_64>(im),0,0);
197 #endif
199  return out->put_view(vil_image_view<float>(im),0,0);
201  return out->put_view(vil_image_view<bool>(im),0,0);
203  return out->put_view(vil_image_view<vxl_sbyte>(im),0,0);
205  return out->put_view(vil_image_view<double>(im),0,0);
206  default:
207  // In case any one has an odd pixel format that actually works with this file_format.
208  return out->put_view(im, 0, 0);
209  }
210 }
211 
212 
213 wchar_t const *vil_save_guess_file_format(wchar_t const* filename)
214 {
215  wchar_t const *file_format = L"pnm"; // default file format
216 
217  // find last "."
218  wchar_t const *dot = wcsrchr(filename, L'.');
219  if (!dot) {
220  // filename doesn't end in ".anything"
221  std::wcerr << __FILE__ ": assuming pnm format for \'" << filename << "\'\n";
222  file_format = L"pnm";
223  }
224  else {
225  std::wstring ext_lower_case(dot); // make a copy to convert the extension to lower case
226  for(unsigned int i=0; i<ext_lower_case.size(); ++i)
227  ext_lower_case[i] = towlower(ext_lower_case[i]);
228  // translate common extensions into known file formats.
229  if (false) { }
230 #define macro(ext, fmt) else if ( ext_lower_case == L"." L#ext ) file_format = L#fmt
231  macro(tiff, tiff);
232  macro(tif, tiff);
233  macro(png, png);
234  macro(bmp, bmp);
235  macro(pbm, pnm);
236  macro(pgm, pnm);
237  macro(ppm, pnm);
238  macro(pnm, pnm);
239  macro(jpg, jpeg);
240  macro(jpeg, jpeg);
241  macro(iris, iris);
242  macro(rgb, iris);
243  macro(viff, viff);
244  macro(mit, mit);
245  macro(v2i, v2i);
246 #undef macro
247  else
248  std::wcerr << __FILE__ ": assuming pnm format for \'" << filename << "\'\n";
249  }
250 
251  return file_format;
252 }
253 
254 //: save to file, deducing format from filename.
255 bool vil_save(const vil_image_view_base & i, wchar_t const* filename)
256 {
257  return vil_save(i, filename, vil_save_guess_file_format(filename));
258 }
259 
260 //: Send vil_image to disk.
261 bool vil_save_image_resource(const vil_image_resource_sptr &ir, wchar_t const* filename,
262  wchar_t const* file_format)
263 {
264  vil_stream* os = vil_open(filename, "w");
265  if (!os || !os->ok()) {
266  std::wcerr << __FILE__ ": Invalid stream for \"" << filename << "\"\n";
267  return false;
268  }
269  vil_image_resource_sptr out = vil_new_image_resource(os, ir->ni(), ir->nj(),
270  ir->nplanes(),
271  ir->pixel_format(), file_format);
272  if (!out) {
273  std::wcerr << __FILE__ ": (vil_save) Cannot save to type [" << file_format << "]\n";
274  return false;
275  }
276  return vil_copy_deep(ir, out);
277 }
278 
279 //: save to file, deducing format from filename.
280 bool vil_save_image_resource(const vil_image_resource_sptr &ir, wchar_t const* filename)
281 {
282  return vil_save_image_resource(ir, filename, vil_save_guess_file_format(filename));
283 }
284 
285 #endif //defined(_WIN32) && VXL_USE_WIN_WCHAR_T
bool vil_save_image_resource(const vil_image_resource_sptr &ir, char const *filename, char const *file_format)
Send vil_image_resource to disk.
Definition: vil_save.cxx:129
An abstract base class of smart pointers to actual image data in memory.
vil_pixel_format vil_pixel_format_component_format(enum vil_pixel_format f)
Return the number of components in pixel format f.
Concrete view of image data of type T held in memory.
Definition: vil_fwd.h:13
vil_image_resource_sptr vil_new_image_resource(unsigned ni, unsigned nj, unsigned nplanes, vil_pixel_format format)
Make a new image of given format.
Definition: vil_new.cxx:32
char const * vil_save_guess_file_format(char const *filename)
Given a filename, guess the file format tag.
Definition: vil_save.cxx:80
unsigned ni() const
Width.
Stream interface for VIL image loaders.
Definition: vil_stream.h:21
unsigned nj() const
Height.
virtual enum vil_pixel_format pixel_format() const =0
Return a description of the concrete data pixel type.
unsigned vil_pixel_format_num_components(enum vil_pixel_format f)
Return the number of components in pixel format f.
double dot(const double *v1, const double *v2, unsigned n)
Various image copying functions.
A base class reference-counting view of some image data.
Make a new image.
virtual bool ok() const =0
Return false if the stream is broken.
unsigned nplanes() const
Number of planes.
make a vil_stream from a filename, an URL, etc.
bool vil_save(const vil_image_view_base &, char const *filename)
Send a vil_image_view to disk, deducing format from filename.
Definition: vil_save.cxx:123
Representation of a generic image source or destination.
bool vil_copy_deep(const vil_image_resource_sptr &src, vil_image_resource_sptr &dest)
Copy src to dest.
Definition: vil_copy.cxx:45
vil_stream * vil_open(char const *what, char const *how="r")
make a vil_stream from a filename, an URL, etc.
Definition: vil_open.cxx:18
#define macro(ext, fmt)