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