00001
00002
00003
00004 #include "vimt_vil_v2i.h"
00005
00006 #include <vcl_cassert.h>
00007 #include <vcl_cstring.h>
00008 #include <vcl_typeinfo.h>
00009 #include <vcl_fstream.h>
00010
00011 #include <vxl_config.h>
00012
00013 #include <vgl/vgl_point_2d.h>
00014 #include <vgl/vgl_vector_2d.h>
00015 #include <vil/vil_exception.h>
00016 #include <vil/vil_property.h>
00017 #include <vil/vil_copy.h>
00018 #include <vil/vil_stream.h>
00019 #include <vil/vil_stream_fstream.h>
00020 #include <vil/vil_image_resource.h>
00021 #include <vil/vil_image_view.h>
00022 #include <vsl/vsl_binary_io.h>
00023 #include <vsl/vsl_binary_loader.h>
00024 #include <vimt/vimt_image_2d_of.h>
00025
00026
00027 const unsigned V2I_MAGIC = 987123872U;
00028
00029
00030 class vimt_vil_fstream: vil_stream_fstream
00031 {
00032 protected:
00033 vcl_fstream& underlying_stream() { return vil_stream_fstream::underlying_stream(); }
00034 friend class vimt_vil_v2i_format;
00035 friend class vimt_vil_v2i_image;
00036 private:
00037 vimt_vil_fstream(): vil_stream_fstream("", "") {}
00038 };
00039
00040
00041 vil_image_resource_sptr vimt_vil_v2i_format::make_input_image(vil_stream* vs)
00042 {
00043
00044
00045 if (typeid(*vs) != typeid(vil_stream_fstream))
00046 {
00047 vcl_cerr << "vimt_vil_v2i_format::make_input_image() WARNING\n"
00048 << " Unable to deal with stream type\n";
00049
00050 return 0;
00051 }
00052 vsl_b_istream vslstream( &reinterpret_cast<vimt_vil_fstream *>(vs)->underlying_stream() );
00053 if (!vslstream) return 0;
00054 unsigned magic;
00055 vil_streampos start = vs->tell();
00056 vsl_b_read(vslstream, magic);
00057 if (magic == V2I_MAGIC)
00058 return new vimt_vil_v2i_image(vs);
00059
00060
00061
00062 vs->seek(start);
00063 int v_i;
00064 bool v_b;
00065 vsl_b_read(vslstream, v_i);
00066 vsl_b_read(vslstream, v_i);
00067 if (v_i != 1) return 0;
00068 vsl_b_read(vslstream, v_i);
00069 if (v_i == 0) return 0;
00070 vsl_b_read(vslstream, v_i);
00071 if (v_i == 0) return 0;
00072 vsl_b_read(vslstream, v_i);
00073 if (v_i == 0) return 0;
00074 vsl_b_read(vslstream, v_i);
00075 vsl_b_read(vslstream, v_i);
00076 vsl_b_read(vslstream, v_i);
00077 vsl_b_read(vslstream, v_i);
00078 if (v_i != 2) return 0;
00079 vsl_b_read(vslstream, v_b);
00080 if (!v_b) return 0;
00081 vsl_b_read(vslstream, v_i);
00082 if (v_i != 1) return 0;
00083 vsl_b_read(vslstream, v_b);
00084 if (!v_b) return 0;
00085 vsl_b_read(vslstream, v_i);
00086 if (v_i != 2 && v_i != 3) return 0;
00087 vsl_b_read(vslstream, v_i);
00088
00089 vil_pixel_format f = static_cast<vil_pixel_format>(v_i);
00090 vs->seek(start);
00091 switch (f)
00092 {
00093 #define macro( F , T ) \
00094 case F : \
00095 { vimt_image_2d_of< T > im; vsl_b_read(vslstream, im); if (!vslstream) return 0; } \
00096 break;
00097
00098 macro(VIL_PIXEL_FORMAT_BYTE, vxl_byte )
00099
00100
00101 macro(VIL_PIXEL_FORMAT_UINT_16 , vxl_uint_16 )
00102 macro(VIL_PIXEL_FORMAT_INT_32 , vxl_int_32 )
00103
00104 macro(VIL_PIXEL_FORMAT_BOOL , bool )
00105 macro(VIL_PIXEL_FORMAT_FLOAT , float )
00106 macro(VIL_PIXEL_FORMAT_DOUBLE , double )
00107 #undef macro
00108 default: return 0;
00109 }
00110 vs->seek(start);
00111 return new vimt_vil_v2i_image(vs, f);
00112 }
00113
00114 vil_image_resource_sptr vimt_vil_v2i_format::make_output_image(vil_stream* vs,
00115 unsigned ni,
00116 unsigned nj,
00117 unsigned nplanes,
00118 vil_pixel_format format)
00119 {
00120
00121
00122 if (typeid(*vs) != typeid(vil_stream_fstream))
00123 {
00124 vcl_cerr << "vimt_vil_v2i_format::make_output_image() WARNING\n"
00125 << " Unable to deal with stream type\n";
00126
00127 return 0;
00128 }
00129 if ( format != VIL_PIXEL_FORMAT_BYTE && format != VIL_PIXEL_FORMAT_SBYTE &&
00130 format != VIL_PIXEL_FORMAT_UINT_32 && format != VIL_PIXEL_FORMAT_INT_32 &&
00131 format != VIL_PIXEL_FORMAT_UINT_16 && format != VIL_PIXEL_FORMAT_INT_16 &&
00132 format != VIL_PIXEL_FORMAT_FLOAT && format != VIL_PIXEL_FORMAT_DOUBLE &&
00133 format != VIL_PIXEL_FORMAT_BOOL)
00134 {
00135 vcl_cerr << "vimt_vil_v2i_format::make_output_image() WARNING\n"
00136 << " Unable to deal with file format : " << format << vcl_endl;
00137 return 0;
00138 }
00139 return new vimt_vil_v2i_image(vs, ni, nj, nplanes, format);
00140 }
00141
00142
00143
00144
00145 vimt_vil_v2i_image::vimt_vil_v2i_image(vil_stream* vs):
00146 vs_(vs), im_(0), dirty_(false)
00147 {
00148 vs_->ref();
00149 vs_->seek(0L);
00150 vsl_b_istream vslstream(& reinterpret_cast<vimt_vil_fstream *>(vs_)->underlying_stream());
00151
00152 unsigned magic;
00153 vsl_b_read(vslstream, magic);
00154 assert(magic == V2I_MAGIC);
00155
00156 short version;
00157 vsl_b_read(vslstream, version);
00158
00159 switch (version)
00160 {
00161 case 1: {
00162 vimt_image *p_im=0;
00163 vsl_b_read(vslstream, p_im);
00164 if (!vslstream)
00165 {
00166 delete p_im;
00167 vil_exception_warning(vil_exception_corrupt_image_file("Constructor", "v2i", "", "Failed to read file correctly"));
00168 im_=0;
00169 return;
00170 }
00171
00172 im_ = dynamic_cast<vimt_image_2d *>(p_im);
00173 break;
00174 }
00175 default:
00176 vcl_cerr << "I/O ERROR: vimt_vil_v2i_image::vimt_vil_v2i_image()\n"
00177 << " Unknown version number "<< version << '\n';
00178 return;
00179 }
00180 }
00181
00182
00183
00184 vimt_vil_v2i_image::vimt_vil_v2i_image(vil_stream* vs, vil_pixel_format f):
00185 vs_(vs), im_(0), dirty_(false)
00186 {
00187 vs_->ref();
00188 vs_->seek(0L);
00189 vsl_b_istream vslstream(& reinterpret_cast<vimt_vil_fstream *>(vs_)->underlying_stream());
00190
00191
00192 switch (f)
00193 {
00194 #define macro( F , T ) \
00195 case F : \
00196 im_ = new vimt_image_2d_of< T >(); \
00197 vsl_b_read(vslstream, *static_cast<vimt_image_2d_of< T >*>(im_)); \
00198 break;
00199
00200 macro(VIL_PIXEL_FORMAT_BYTE, vxl_byte )
00201
00202
00203 macro(VIL_PIXEL_FORMAT_UINT_16 , vxl_uint_16 )
00204 macro(VIL_PIXEL_FORMAT_INT_32 , vxl_int_32 )
00205
00206 macro(VIL_PIXEL_FORMAT_BOOL , bool )
00207 macro(VIL_PIXEL_FORMAT_FLOAT , float )
00208 macro(VIL_PIXEL_FORMAT_DOUBLE , double )
00209 #undef macro
00210 default: throw vil_exception_image_io("vimt_vil_v2i_image::vimt_vil_v2i_image",
00211 "v2i", "");
00212 }
00213
00214
00215 vimt_transform_2d tr;
00216 tr.set_zoom_only(1000.0, 0.0, 0.0);
00217 im_->world2im() = im_->world2im() * tr;
00218 assert(! !vslstream);
00219 }
00220
00221 bool vimt_vil_v2i_image::get_property(char const * key, void * value) const
00222 {
00223 const vimt_transform_2d &tr = im_->world2im();
00224
00225 if (vcl_strcmp(vil_property_pixel_size, key)==0)
00226 {
00227 vgl_vector_2d<double> p11 = tr.inverse()(1.0, 1.0) - tr.inverse().origin();
00228
00229
00230 float* array = static_cast<float*>(value);
00231 array[0] = (float) p11.x();
00232 array[1] = (float) p11.y();
00233 return true;
00234 }
00235
00236 if (vcl_strcmp(vil_property_offset, key)==0)
00237 {
00238 vgl_point_2d<double> origin = tr.origin();
00239 float* array = static_cast<float*>(value);
00240 array[0] = (float)(origin.x());
00241 array[1] = (float)(origin.y());
00242 return true;
00243 }
00244
00245 return false;
00246 }
00247
00248 vimt_vil_v2i_image::vimt_vil_v2i_image(vil_stream* vs, unsigned ni, unsigned nj,
00249 unsigned nplanes, vil_pixel_format format):
00250 vs_(vs), im_(0), dirty_(true)
00251 {
00252 vs_->ref();
00253 switch (format)
00254 {
00255 #define macro( F , T ) \
00256 case F : \
00257 im_ = new vimt_image_2d_of< T > (ni, nj, nplanes); \
00258 break;
00259
00260 macro(VIL_PIXEL_FORMAT_BYTE, vxl_byte )
00261
00262
00263 macro(VIL_PIXEL_FORMAT_UINT_16 , vxl_uint_16 )
00264 macro(VIL_PIXEL_FORMAT_INT_32 , vxl_int_32 )
00265
00266 macro(VIL_PIXEL_FORMAT_BOOL , bool )
00267 macro(VIL_PIXEL_FORMAT_FLOAT , float )
00268 macro(VIL_PIXEL_FORMAT_DOUBLE , double )
00269 #undef macro
00270 default:
00271 vcl_cerr << "I/O ERROR: vimt_vil_v2i_image::vimt_vil_v2i_image()\n"
00272 << " Unknown vil_pixel_format "<< format << '\n';
00273 vcl_abort();
00274 }
00275 }
00276
00277
00278 vimt_vil_v2i_image::~vimt_vil_v2i_image()
00279 {
00280 if (dirty_)
00281 {
00282 vs_->seek(0l);
00283 vsl_b_ostream vslstream(& reinterpret_cast<vimt_vil_fstream *>(vs_)->underlying_stream());
00284
00285 vsl_b_write(vslstream, V2I_MAGIC);
00286
00287 const short version = 1;
00288 vsl_b_write(vslstream, version);
00289
00290
00291 vimt_image *p_im=im_;
00292 vsl_b_write(vslstream, p_im);
00293 }
00294
00295 vs_->unref();
00296 delete im_;
00297 }
00298
00299
00300
00301 unsigned vimt_vil_v2i_image::nplanes() const
00302 {
00303 return im_->image_base().nplanes();
00304 }
00305
00306
00307
00308 unsigned vimt_vil_v2i_image::ni() const
00309 {
00310 return im_->image_base().ni();
00311 }
00312
00313
00314
00315 unsigned vimt_vil_v2i_image::nj() const
00316 {
00317 return im_->image_base().nj();
00318 }
00319
00320
00321 enum vil_pixel_format vimt_vil_v2i_image::pixel_format() const
00322 {
00323 return im_->image_base().pixel_format();
00324 }
00325
00326
00327 const vimt_transform_2d & vimt_vil_v2i_image::world2im() const
00328 {
00329 return im_->world2im();
00330 }
00331
00332 void vimt_vil_v2i_image::set_world2im(const vimt_transform_2d & tr)
00333 {
00334 im_->set_world2im(tr);
00335 dirty_ = true;
00336 }
00337
00338
00339 void vimt_vil_v2i_image::set_pixel_size(float si, float sj)
00340 {
00341 const vimt_transform_2d &tr = im_->world2im();
00342
00343
00344 vgl_vector_2d<double> w11 = tr(1.0, 1.0) - tr.origin();
00345
00346 vimt_transform_2d zoom;
00347 zoom.set_zoom_only (w11.x()/si, w11.y()/sj, 0.0, 0.0);
00348
00349 im_->set_world2im(tr*zoom);
00350 }
00351
00352
00353
00354
00355
00356 vil_image_view_base_sptr vimt_vil_v2i_image::get_copy_view(unsigned i0, unsigned ni,
00357 unsigned j0, unsigned nj) const
00358 {
00359 const vil_image_view_base &view = im_->image_base();
00360
00361 if (i0 + ni > view.ni() || j0 + nj > view.nj() ) return 0;
00362
00363 switch (view.pixel_format())
00364 {
00365 #define macro( F , T ) \
00366 case F : { \
00367 const vil_image_view< T > &v = \
00368 static_cast<const vil_image_view< T > &>(view); \
00369 vil_image_view< T > w(v.memory_chunk(), &v(i0,j0), \
00370 ni, nj, v.nplanes(), \
00371 v.istep(), v.jstep(), v.planestep()); \
00372 return new vil_image_view< T >(vil_copy_deep(w)); }
00373
00374 macro(VIL_PIXEL_FORMAT_BYTE, vxl_byte )
00375
00376
00377 macro(VIL_PIXEL_FORMAT_UINT_16 , vxl_uint_16 )
00378 macro(VIL_PIXEL_FORMAT_INT_32 , vxl_int_32 )
00379
00380 macro(VIL_PIXEL_FORMAT_BOOL , bool )
00381 macro(VIL_PIXEL_FORMAT_FLOAT , float )
00382 macro(VIL_PIXEL_FORMAT_DOUBLE , double )
00383 #undef macro
00384 default:
00385 return 0;
00386 }
00387 }
00388
00389
00390
00391 vil_image_view_base_sptr vimt_vil_v2i_image::get_view(unsigned i0, unsigned ni,
00392 unsigned j0, unsigned nj) const
00393 {
00394 const vil_image_view_base &view = im_->image_base();
00395
00396
00397 if (i0 + ni > view.ni() || j0 + nj > view.nj()) return 0;
00398
00399 switch (view.pixel_format())
00400 {
00401 #define macro( F , T ) \
00402 case F : { \
00403 const vil_image_view< T > &v = \
00404 static_cast<const vil_image_view< T > &>(view); \
00405 return new vil_image_view< T >(v.memory_chunk(), &v(i0,j0), \
00406 ni, nj, v.nplanes(), \
00407 v.istep(), v.jstep(), v.planestep()); }
00408
00409 macro(VIL_PIXEL_FORMAT_BYTE , vxl_byte )
00410
00411
00412
00413 macro(VIL_PIXEL_FORMAT_INT_32 , vxl_int_32 )
00414 macro(VIL_PIXEL_FORMAT_INT_16 , vxl_int_16 )
00415
00416 macro(VIL_PIXEL_FORMAT_FLOAT , float )
00417
00418 #undef macro
00419 default:
00420 return 0;
00421 }
00422 }
00423
00424
00425
00426 bool vimt_vil_v2i_image::put_view(const vil_image_view_base& vv,
00427 unsigned i0, unsigned j0)
00428 {
00429 if (!view_fits(vv, i0, j0))
00430 {
00431 vcl_cerr << "ERROR: " << __FILE__ << ":\n view does not fit\n";
00432 return false;
00433 }
00434
00435 if (vv.pixel_format() != im_->image_base().pixel_format())
00436 {
00437 vcl_cerr << "ERROR: vimt_vil_v2i_image::put_view(). Pixel formats do not match\n";
00438 return false;
00439 }
00440
00441
00442 dirty_ = true;
00443
00444 switch (vv.pixel_format())
00445 {
00446 #define macro( F , T ) \
00447 case F : \
00448 vil_copy_to_window(static_cast<vil_image_view< T >const&>(vv), \
00449 static_cast<vimt_image_2d_of< T >&>(*im_).image(), i0, j0); \
00450 return true;
00451
00452
00453 macro(VIL_PIXEL_FORMAT_BYTE , vxl_byte )
00454
00455
00456
00457 macro(VIL_PIXEL_FORMAT_INT_32 , vxl_int_32 )
00458 macro(VIL_PIXEL_FORMAT_INT_16 , vxl_int_16 )
00459
00460 macro(VIL_PIXEL_FORMAT_FLOAT , float )
00461
00462 #undef macro
00463 default:
00464 return false;
00465 }
00466 }