core/vil/vil_new.cxx
Go to the documentation of this file.
00001 // This is core/vil/vil_new.cxx
00002 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00003 #pragma implementation
00004 #endif
00005 //:
00006 // \file
00007 // \author Andrew W. Fitzgibbon, Oxford RRG
00008 // \date   16 Feb 00
00009 
00010 #include "vil_new.h"
00011 
00012 #include <vcl_cstring.h>
00013 #include <vcl_cassert.h>
00014 #include <vil/vil_save.h>
00015 #include <vil/vil_file_format.h>
00016 #include <vil/vil_stream_fstream.h>
00017 #include <vil/vil_image_resource.h>
00018 #include <vil/vil_memory_image.h>
00019 #include <vil/vil_blocked_image_facade.h>
00020 #include <vil/vil_cached_image_resource.h>
00021 #include <vil/vil_pyramid_image_resource.h>
00022 #include <vil/file_formats/vil_pyramid_image_list.h>
00023 // The first two functions really should be upgraded to create an image in
00024 // a temporary file on disk if the sizes are large. - TODO
00025 
00026 //: Make a new image of given format.
00027 // If the format is not scalar, the number of planes must be 1. When you create
00028 // a multi-component image in this way, the vil_image_resource API will treat
00029 // it as a scalar pixel image with multiple planes. (This doesn't affect the
00030 // underlying data storage.)
00031 // \relatesalso vil_image_resource
00032 vil_image_resource_sptr vil_new_image_resource(unsigned ni, unsigned nj, unsigned nplanes,
00033                                                vil_pixel_format format)
00034 {
00035   assert(nplanes == 1 || vil_pixel_format_num_components(format) == 1);
00036 
00037   return new vil_memory_image(ni, nj, nplanes, format);
00038 }
00039 
00040 
00041 //: Make a new image of given format with interleaved planes.
00042 // The format must be scalar.
00043 // \relatesalso vil_image_resource
00044 vil_image_resource_sptr vil_new_image_resource_interleaved(unsigned ni, unsigned nj,
00045                                                            unsigned nplanes,
00046                                                            vil_pixel_format format)
00047 {
00048   assert(vil_pixel_format_num_components(format) == 1);
00049 
00050   return new vil_memory_image(ni, nj, 1, format, nplanes);
00051 }
00052 
00053 
00054 //: Make a new image resource that is a wrapper on an existing view's data.
00055 // \note The output will be a shallow copy of the input, so changing the pixel values
00056 // of one may change the pixel value of the other. Thanks to the magic of smart pointers,
00057 // the output will remain valid even if you destroy the input. When you wrap
00058 // a multi-component image in this way, the vil_image_resource API will treat
00059 // it as a scalar pixel image with multiple planes. (This doesn't affect the
00060 // underlying data storage.)
00061 // \relatesalso vil_image_resource
00062 vil_image_resource_sptr vil_new_image_resource_of_view(vil_image_view_base const& view)
00063 {
00064   return new vil_memory_image(view);
00065 }
00066 
00067 //: Make a new image, similar format to the prototype.
00068 // \relatesalso vil_image_resource
00069 vil_image_resource_sptr vil_new_image_resource(unsigned ni, unsigned nj, vil_image_resource_sptr const& prototype)
00070 {
00071   return vil_new_image_resource(ni, nj, prototype->nplanes(),
00072                                 prototype->pixel_format());
00073 }
00074 
00075 //: Make a new image.
00076 // \relatesalso vil_image_resource
00077 vil_image_resource_sptr vil_new_image_resource(vil_stream* os,
00078                                                unsigned ni, unsigned nj,
00079                                                unsigned nplanes,
00080                                                vil_pixel_format format,
00081                                                char const* file_format)
00082 {
00083   if (!file_format) // avoid segfault in strcmp()
00084     file_format = "pnm";
00085 
00086   vil_image_resource_sptr outimage = 0;
00087   for (vil_file_format** p = vil_file_format::all(); *p; ++p)
00088   {
00089     vil_file_format* fmt = *p;
00090     if (vcl_strcmp(fmt->tag(), file_format) == 0) {
00091       outimage = fmt->make_output_image(os, ni, nj, nplanes, format);
00092       if (!outimage)
00093         vcl_cerr << "vil_new: Cannot new to type [" << file_format << "]\n";
00094       return outimage;
00095     }
00096   }
00097 
00098   vcl_cerr << "vil_new: Unknown file type [" << file_format << "]\n";
00099   return 0;
00100 }
00101 
00102 //: Make a new vil_image_resource, writing to file "filename", size ni x nj, copying pixel format etc from "prototype".
00103 // \relatesalso vil_image_resource
00104 vil_image_resource_sptr vil_new_image_resource(char const* filename,
00105                                                unsigned ni, unsigned nj,
00106                                                vil_image_resource_sptr const& prototype,
00107                                                char const* file_format)
00108 {
00109 #ifdef VIL_USE_FSTREAM64
00110   vil_stream_fstream64* os = new vil_stream_fstream64(filename, "w");
00111 #else //VIL_USE_FSTREAM64
00112   vil_stream_fstream* os = new vil_stream_fstream(filename, "w");
00113 #endif //VIL_USE_FSTREAM64
00114   return vil_new_image_resource(os,
00115                                 ni, nj,
00116                                 prototype->nplanes(),
00117                                 prototype->pixel_format(),
00118                                 file_format ? file_format : prototype->file_format());
00119 }
00120 
00121 //: Make a new image.
00122 // \relatesalso vil_image_resource
00123 vil_image_resource_sptr vil_new_image_resource(char const* filename,
00124                                                unsigned ni, unsigned nj,
00125                                                unsigned nplanes,
00126                                                vil_pixel_format format,
00127                                                char const* file_format)
00128 {
00129 #ifdef VIL_USE_FSTREAM64
00130   vil_stream_fstream64* os = new vil_stream_fstream64(filename, "w");
00131 #else //VIL_USE_FSTREAM64
00132   vil_stream_fstream* os = new vil_stream_fstream(filename, "w");
00133 #endif //VIL_USE_FSTREAM64
00134 
00135   if (!file_format || !*file_format)
00136     file_format = vil_save_guess_file_format(filename);
00137   return vil_new_image_resource(os, ni, nj, nplanes, format, file_format);
00138 }
00139 
00140 
00141 //: Make a new vil_image_resource, writing to stream "os", size ni x nj, copying pixel format etc from "prototype".
00142 // \relatesalso vil_image_resource
00143 vil_image_resource_sptr vil_new_image_resource(vil_stream* os,
00144                                                unsigned ni, unsigned nj,
00145                                                vil_image_resource_sptr const& prototype,
00146                                                char const* file_format)
00147 {
00148   return vil_new_image_resource(os,
00149                                 prototype->nplanes(),
00150                                 ni, nj,
00151                                 prototype->pixel_format(),
00152                                 file_format ? file_format : prototype->file_format());
00153 }
00154 
00155 vil_blocked_image_resource_sptr
00156 vil_new_blocked_image_resource(vil_stream* os, unsigned ni, unsigned nj,
00157                                unsigned nplanes, vil_pixel_format format,
00158                                unsigned size_block_i, unsigned size_block_j,
00159                                char const* file_format)
00160 {
00161   if (!file_format) // avoid segfault in strcmp()
00162     file_format = "pnm";
00163 
00164   vil_blocked_image_resource_sptr outimage = 0;
00165   for (vil_file_format** p = vil_file_format::all(); *p; ++p)
00166   {
00167     vil_file_format* fmt = *p;
00168     if (vcl_strcmp(fmt->tag(), file_format) == 0) {
00169       outimage = fmt->make_blocked_output_image(os, ni, nj, nplanes,
00170                                                 size_block_i, size_block_j, format);
00171       if (!outimage)
00172         vcl_cerr << "vil_new: Cannot new a blocked resource to type [" << file_format << "]\n";
00173       return outimage;
00174     }
00175   }
00176 
00177   vcl_cerr << "vil_new: Unknown file type [" << file_format << "]\n";
00178   return 0;
00179 }
00180 
00181 vil_blocked_image_resource_sptr
00182 vil_new_blocked_image_resource(char const* filename, unsigned ni, unsigned nj,
00183                                unsigned nplanes, vil_pixel_format format,
00184                                unsigned size_block_i, unsigned size_block_j,
00185                                char const* file_format)
00186 {
00187 #ifdef VIL_USE_FSTREAM64
00188   vil_stream_fstream64* os = new vil_stream_fstream64(filename, "w");
00189 #else //VIL_USE_FSTREAM64
00190   vil_stream_fstream* os = new vil_stream_fstream(filename, "w");
00191 #endif //VIL_USE_FSTREAM64
00192   return vil_new_blocked_image_resource(os, ni, nj, nplanes, format,
00193                                         size_block_i, size_block_j,
00194                                         file_format);
00195 }
00196 
00197 vil_blocked_image_resource_sptr
00198 vil_new_blocked_image_facade(const vil_image_resource_sptr& src,
00199                              unsigned size_block_i, unsigned size_block_j)
00200 {
00201   return new vil_blocked_image_facade(src, size_block_i, size_block_j);
00202 }
00203 
00204 
00205 vil_blocked_image_resource_sptr
00206 vil_new_cached_image_resource(const vil_blocked_image_resource_sptr& bir,
00207                               const unsigned cache_size)
00208 {
00209   return new vil_cached_image_resource(bir, cache_size);
00210 }
00211 
00212 vil_pyramid_image_resource_sptr
00213 vil_new_pyramid_image_resource(char const* file_or_directory,
00214                                char const* file_format)
00215 {
00216   if (!file_format) // avoid segfault in strcmp()
00217     file_format = "tiff";
00218   vil_pyramid_image_resource_sptr outimage = 0;
00219   for (vil_file_format** p = vil_file_format::all(); *p; ++p)
00220   {
00221     vil_file_format* fmt = *p;
00222     if (vcl_strcmp(fmt->tag(), file_format) == 0) {
00223       outimage = fmt->make_pyramid_output_image(file_or_directory);
00224       if (!outimage)
00225         vcl_cerr << "vil_new: Cannot new a pyramid resource to type [" << file_format << "]\n";
00226       return outimage;
00227     }
00228   }
00229   vcl_cerr << "vil_new: Unknown file type [" << file_format << "]\n";
00230   return 0;
00231 }
00232 
00233 vil_pyramid_image_resource_sptr
00234   vil_new_pyramid_image_from_base(char const* filename,
00235                                   vil_image_resource_sptr const& base_image,
00236                                   unsigned nlevels,
00237                                   char const* file_format,
00238                                   char const* temp_dir)
00239 {
00240   if (!file_format) // avoid segfault in strcmp()
00241     file_format = "tiff";
00242   vil_pyramid_image_resource_sptr outimage = 0;
00243   for (vil_file_format** p = vil_file_format::all(); *p; ++p)
00244   {
00245     vil_file_format* fmt = *p;
00246     if (vcl_strcmp(fmt->tag(), file_format) == 0) {
00247       outimage = fmt->make_pyramid_image_from_base(filename,
00248                                                    base_image,
00249                                                    nlevels,
00250                                                    temp_dir);
00251       if (!outimage)
00252         vcl_cerr << "vil_new: Cannot new a pyramid resource to type [" << file_format << "]\n";
00253       return outimage;
00254     }
00255   }
00256   vcl_cerr << "vil_new: Unknown file type [" << file_format << "]\n";
00257   return 0;
00258 }
00259 
00260 //for now there is only one directory based pyramid format
00261 vil_pyramid_image_resource_sptr
00262   vil_new_pyramid_image_list_from_base(char const* directory,
00263                                        vil_image_resource_sptr const& base_image,
00264                                        unsigned nlevels,
00265                                        bool copy_base,
00266                                        char const* level_file_format,
00267                                        char const* filename)
00268 {
00269   vil_pyramid_image_list_format vpilf;
00270   return vpilf.make_pyramid_image_from_base(directory, base_image, nlevels,
00271                                             copy_base, level_file_format,
00272                                             filename);
00273 }
00274 
00275 //: Create a shallow copy of an image and wrap it in a vil_image_view_base_sptr
00276 // \note vil_image_view_base_sptr almost certainly doesn't behave as
00277 // you would expect, and this function should really only be used by experts.
00278 vil_image_view_base_sptr vil_new_image_view_base_sptr(const vil_image_view_base& src)
00279 {
00280   vil_image_view_base_sptr dest;
00281   switch (vil_pixel_format_component_format(src.pixel_format()))
00282   {
00283 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00284 #define macro( F , T ) \
00285    case F: { \
00286       dest = new vil_image_view<T>(src); \
00287     break; }
00288    macro(VIL_PIXEL_FORMAT_BYTE, vxl_byte )
00289    macro(VIL_PIXEL_FORMAT_SBYTE , vxl_sbyte )
00290 #if VXL_HAS_INT_64 && !defined(VCL_VC_6)
00291    macro(VIL_PIXEL_FORMAT_UINT_64 , vxl_uint_64 )
00292    macro(VIL_PIXEL_FORMAT_INT_64 , vxl_int_64 )
00293 #endif
00294    macro(VIL_PIXEL_FORMAT_UINT_32 , vxl_uint_32 )
00295    macro(VIL_PIXEL_FORMAT_INT_32 , vxl_int_32 )
00296    macro(VIL_PIXEL_FORMAT_UINT_16 , vxl_uint_16 )
00297    macro(VIL_PIXEL_FORMAT_INT_16 , vxl_int_16 )
00298    macro(VIL_PIXEL_FORMAT_FLOAT , float )
00299    macro(VIL_PIXEL_FORMAT_DOUBLE , double )
00300    macro(VIL_PIXEL_FORMAT_BOOL , bool )
00301 #undef macro
00302 #endif // DOXYGEN_SHOULD_SKIP_THIS
00303    default: /* do nothing */;
00304   }
00305   return dest;
00306 }
00307 
00308 #if defined(VCL_WIN32) && VXL_USE_WIN_WCHAR_T
00309 #include <windows.h>
00310 
00311 //: Make a new image.
00312 // \relatesalso vil_image_resource
00313 vil_image_resource_sptr vil_new_image_resource(vil_stream* os,
00314                                                unsigned ni, unsigned nj,
00315                                                unsigned nplanes,
00316                                                vil_pixel_format format,
00317                                                wchar_t const* file_format)
00318 {
00319   if (!file_format) // avoid segfault in strcmp()
00320     file_format = L"pnm";
00321 
00322   const unsigned int size = 200;
00323   char fmt_buffer[size];  // should be enough
00324   BOOL useless;
00325   // ret indicates the number of characters successfully converted
00326   const int ret = WideCharToMultiByte(CP_ACP, 0, file_format, int(wcslen(file_format)), fmt_buffer, size, 0, &useless );
00327   fmt_buffer[ret] = '\0';
00328   if (!ret)   return 0;
00329 
00330   return vil_new_image_resource(os, ni, nj, nplanes, format, fmt_buffer);
00331 }
00332 
00333 //: Make a new vil_image_resource, writing to file "filename", size ni x nj, copying pixel format etc from "prototype".
00334 // \relatesalso vil_image_resource
00335 vil_image_resource_sptr vil_new_image_resource(wchar_t const* filename,
00336                                                unsigned ni, unsigned nj,
00337                                                vil_image_resource_sptr const& prototype,
00338                                                wchar_t const* file_format)
00339 {
00340 #ifdef VIL_USE_FSTREAM64
00341   vil_stream_fstream64* os = new vil_stream_fstream64(filename, "w");
00342 #else //VIL_USE_FSTREAM64
00343   vil_stream_fstream* os = new vil_stream_fstream(filename, "w");
00344 #endif //VIL_USE_FSTREAM64
00345 
00346   const unsigned int size = 200;  // should be enough
00347   wchar_t tag_buffer[size];
00348   if ( !file_format )
00349   {
00350     char const* tag = prototype->file_format();
00351     const int ret = MultiByteToWideChar(CP_ACP, 0, tag, vcl_strlen(tag), tag_buffer, size);
00352     assert(ret);
00353     file_format = tag_buffer;  // use the file format of the given resource
00354   }
00355 
00356   return vil_new_image_resource(os,
00357                                 ni, nj,
00358                                 prototype->nplanes(),
00359                                 prototype->pixel_format(),
00360                                 file_format );
00361 }
00362 
00363 //: Make a new image.
00364 // \relatesalso vil_image_resource
00365 vil_image_resource_sptr vil_new_image_resource(wchar_t const* filename,
00366                                                unsigned ni, unsigned nj,
00367                                                unsigned nplanes,
00368                                                vil_pixel_format format,
00369                                                wchar_t const* file_format)
00370 {
00371 #ifdef VIL_USE_FSTREAM64
00372   vil_stream_fstream64* os = new vil_stream_fstream64(filename, "w");
00373 #else //VIL_USE_FSTREAM64
00374   vil_stream_fstream* os = new vil_stream_fstream(filename, "w");
00375 #endif //VIL_USE_FSTREAM64
00376 
00377   if (!file_format || !*file_format)
00378     file_format = vil_save_guess_file_format(filename);
00379   return vil_new_image_resource(os, ni, nj, nplanes, format, file_format);
00380 }
00381 
00382 #endif //defined(VCL_WIN32) && VXL_USE_WIN_WCHAR_T