00001
00002 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00003 #pragma implementation
00004 #endif
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "vil3d_meta_image_format.h"
00020 #include <vul/vul_file.h>
00021 #include <vil/vil_stream_fstream.h>
00022 #include <vil3d/vil3d_image_view.h>
00023 #include <vil3d/vil3d_property.h>
00024 #include <vil3d/vil3d_image_resource.h>
00025 #include <vil3d/vil3d_new.h>
00026 #include <vil3d/vil3d_copy.h>
00027 #include <vcl_algorithm.h>
00028 #include <vcl_cstring.h>
00029 #include <vcl_cstdlib.h>
00030 #include <vcl_cstddef.h>
00031 #include <vcl_iostream.h>
00032
00033
00034
00035
00036 inline void vil3d_meta_image_swap16(char *a, unsigned n)
00037 {
00038 for (unsigned i = 0; i < n * 2; i += 2)
00039 {
00040 char c = a[i]; a[i] = a[i+1]; a[i+1] = c;
00041 }
00042 }
00043
00044 inline void vil3d_meta_image_swap32(char *a, unsigned n)
00045 {
00046 for (unsigned i = 0; i < n * 4; i += 4)
00047 {
00048 char c= a[i]; a[i] = a[i+3]; a[i+3] = c;
00049 c = a[i+1]; a[i+1] = a[i+2]; a[i+2] = c;
00050 }
00051 }
00052
00053 inline void vil3d_meta_image_swap64(char *a, unsigned n)
00054 {
00055 for (unsigned i = 0; i < n * 2; i += 2)
00056 {
00057 char c = a[i]; a[i] = a[i+7]; a[i+7] = c;
00058 c = a[i+1]; a[i+1] = a[i+6]; a[i+6] = c;
00059 c = a[i+2]; a[i+2] = a[i+5]; a[i+5] = c;
00060 c = a[i+3]; a[i+3] = a[i+4]; a[i+4] = c;
00061 }
00062 }
00063
00064
00065
00066
00067
00068
00069
00070
00071 vil3d_meta_image_header::vil3d_meta_image_header(void) :
00072 header_valid_(false),
00073 byte_order_msb_(false),
00074 offset_i_(0.0), offset_j_(0.0), offset_k_(0.0),
00075 vox_size_i_(1.0), vox_size_j_(1.0), vox_size_k_(1.0),
00076 dim_size_i_(0), dim_size_j_(0), dim_size_k_(0), nplanes_(1),
00077 need_swap_(false)
00078 {
00079
00080 }
00081
00082
00083
00084
00085 vil3d_meta_image_header::~vil3d_meta_image_header(void)
00086 {
00087
00088 }
00089
00090
00091
00092
00093 void vil3d_meta_image_header::set_byte_order_msb(const bool is_msb)
00094 {
00095 byte_order_msb_ = is_msb;
00096 }
00097
00098 bool vil3d_meta_image_header::byte_order_is_msb(void) const
00099 {
00100 return byte_order_msb_;
00101 }
00102
00103
00104
00105
00106 void vil3d_meta_image_header::set_offset(const double off_i,
00107 const double off_j,
00108 const double off_k)
00109 {
00110 offset_i_ = off_i;
00111 offset_j_ = off_j;
00112 offset_k_ = off_k;
00113 }
00114
00115 double vil3d_meta_image_header::offset_i(void) const
00116 {
00117 return offset_i_;
00118 }
00119
00120 double vil3d_meta_image_header::offset_j(void) const
00121 {
00122 return offset_j_;
00123 }
00124
00125 double vil3d_meta_image_header::offset_k(void) const
00126 {
00127 return offset_k_;
00128 }
00129
00130
00131
00132
00133 void vil3d_meta_image_header::set_vox_size(const double vox_i,
00134 const double vox_j,
00135 const double vox_k)
00136 {
00137 vox_size_i_ = vox_i;
00138 vox_size_j_ = vox_j;
00139 vox_size_k_ = vox_k;
00140 }
00141
00142 double vil3d_meta_image_header::vox_size_i(void) const
00143 {
00144 return vox_size_i_;
00145 }
00146
00147 double vil3d_meta_image_header::vox_size_j(void) const
00148 {
00149 return vox_size_j_;
00150 }
00151
00152 double vil3d_meta_image_header::vox_size_k(void) const
00153 {
00154 return vox_size_k_;
00155 }
00156
00157
00158
00159
00160 void vil3d_meta_image_header::set_dim_size(const unsigned int ni,
00161 const unsigned int nj,
00162 const unsigned int nk,
00163 const unsigned int np)
00164 {
00165 dim_size_i_ = ni;
00166 dim_size_j_ = nj;
00167 dim_size_k_ = nk;
00168 nplanes_ = np;
00169 }
00170
00171 unsigned int vil3d_meta_image_header::ni(void) const
00172 {
00173 return dim_size_i_;
00174 }
00175
00176 unsigned int vil3d_meta_image_header::nj(void) const
00177 {
00178 return dim_size_j_;
00179 }
00180
00181 unsigned int vil3d_meta_image_header::nk(void) const
00182 {
00183 return dim_size_k_;
00184 }
00185
00186 unsigned int vil3d_meta_image_header::nplanes(void) const
00187 {
00188 return nplanes_;
00189 }
00190
00191
00192
00193
00194 void vil3d_meta_image_header::set_element_type(const vcl_string &elem_type)
00195 {
00196 elem_type_ = elem_type;
00197 }
00198
00199 const vcl_string &vil3d_meta_image_header::element_type(void) const
00200 {
00201 return elem_type_;
00202 }
00203
00204
00205
00206
00207 void vil3d_meta_image_header::set_image_fname(const vcl_string &image_fname)
00208 {
00209 im_file_ = image_fname;
00210 }
00211
00212 const vcl_string &vil3d_meta_image_header::image_fname(void) const
00213 {
00214 return im_file_;
00215 }
00216
00217
00218
00219
00220 void vil3d_meta_image_header::set_pixel_format(const vil_pixel_format format)
00221 {
00222 pformat_ = format;
00223 }
00224
00225 vil_pixel_format vil3d_meta_image_header::pixel_format(void) const
00226 {
00227 return pformat_;
00228 }
00229
00230
00231
00232
00233 void vil3d_meta_image_header::clear(void)
00234 {
00235 header_valid_ = false;
00236 byte_order_msb_ = false;
00237 offset_i_ = offset_j_ = offset_k_ = 0.0;
00238 vox_size_i_ = vox_size_j_ = vox_size_k_ = 1.0;
00239 dim_size_i_ = dim_size_j_ = dim_size_k_ = 0;
00240 elem_type_ = im_file_ = "";
00241 need_swap_ = false;
00242 }
00243
00244
00245
00246
00247 bool vil3d_meta_image_header::read_header(const vcl_string &header_fname)
00248 {
00249 vcl_ifstream hfs(header_fname.c_str());
00250
00251 if (!hfs)
00252 return false;
00253
00254 vcl_string nxt_line;
00255 vcl_getline(hfs,nxt_line);
00256 while (hfs.good() && !hfs.eof())
00257 {
00258 if (!check_next_header_line(nxt_line))
00259 {
00260 hfs.close();
00261 return false;
00262 }
00263 vcl_getline(hfs,nxt_line);
00264 }
00265 hfs.close();
00266 if (header_valid_)
00267 {
00268 vcl_string pth = vul_file::dirname(header_fname);
00269 pth += "/" + im_file_;
00270 im_file_ = pth;
00271 return true;
00272 }
00273 else
00274 return false;
00275 }
00276
00277
00278
00279
00280 bool vil3d_meta_image_header::write_header(const vcl_string &header_fname) const
00281 {
00282 vcl_ofstream ofs(header_fname.c_str());
00283 if (!ofs)
00284 return false;
00285
00286 ofs << "ObjectType = Image\n"
00287 << "NDims = 3\n"
00288 << "BinaryData = True\n"
00289 << "BinaryDataByteOrderMSB = " << ((byte_order_msb_) ? "True" : "False") << '\n'
00290 << "CompressedData = False\n"
00291 << "TransformMatrix = 1 0 0 0 1 0 0 0 1\n"
00292 << "Offset = " << offset_i_ << ' ' << offset_j_ << ' ' << offset_k_ << '\n'
00293 << "CenterOfRotation = 0 0 0\n"
00294 << "AnatomicalOrientation = RAI\n"
00295 << "ElementSpacing = " << vox_size_i_ << ' ' << vox_size_j_ << ' ' << vox_size_k_ << '\n'
00296 << "DimSize = " << dim_size_i_ << ' ' << dim_size_j_ << ' ' << dim_size_k_ << '\n'
00297 << "ElementType = " << elem_type_ << '\n'
00298 << "ElementDataFile = " << vul_file::strip_directory(im_file_) << vcl_endl;
00299
00300 ofs.close();
00301 return true;
00302 }
00303
00304
00305
00306
00307 void vil3d_meta_image_header::print_header(vcl_ostream &os) const
00308 {
00309 os << "\n============= Meta Image Header Summary Begin =============\n"
00310 << "vil3d_meta_image_header - byte order is msb: " << ((byte_order_msb_) ? "true" : "false") << '\n'
00311 << "vil3d_meta_image_header - offset " << offset_i_ << ", " << offset_j_ << ", " << offset_k_ << '\n'
00312 << "vil3d_meta_image_header - voxel size: " << vox_size_i_ << ", " << vox_size_j_ << ", " << vox_size_k_ << '\n'
00313 << "vil3d_meta_image_header - dimension size: " << dim_size_i_ << ", " << dim_size_j_ << ", " << dim_size_k_ << '\n'
00314 << "vil3d_meta_image_header - nplanes: " << nplanes_ << '\n'
00315 << "vil3d_meta_image_header - element type: " << elem_type_ << '\n'
00316 << "vil3d_meta_image_header - image file: " << im_file_ << '\n'
00317 << "============= Meta Image Header Summary End =============\n" << vcl_endl;
00318 }
00319
00320
00321
00322
00323 void vil3d_meta_image_header::check_need_swap(void)
00324 {
00325 union short_char
00326 {
00327 short short_val;
00328 char char_val[2];
00329 } test_swap;
00330
00331 test_swap.short_val = 1;
00332
00333 if (test_swap.char_val[0]==1 && byte_order_msb_)
00334 need_swap_ = true;
00335 else if (test_swap.char_val[1]==1 && (!byte_order_msb_))
00336 need_swap_ = true;
00337 else
00338 need_swap_ = false;
00339 }
00340
00341
00342
00343
00344 bool vil3d_meta_image_header::need_swap(void) const
00345 {
00346 return need_swap_;
00347 }
00348
00349
00350
00351
00352 bool vil3d_meta_image_header::check_next_header_line(const vcl_string &nxt_line)
00353 {
00354
00355 vcl_string val = get_header_value(nxt_line);
00356 if (val=="")
00357 return false;
00358
00359 if (nxt_line.find("ObjectType")!= vcl_string::npos)
00360 {
00361 if (val != "Image")
00362 {
00363 vcl_cerr << "Loader only handles Image Types.\n";
00364 return false;
00365 }
00366 }
00367 else if (nxt_line.find("NDims")!= vcl_string::npos)
00368 {
00369 unsigned int nd = vcl_atoi(val.c_str());
00370 if (nd != 3)
00371 {
00372 vcl_cerr << "Loader only handles 3D Images.\n";
00373 return false;
00374 }
00375 }
00376 else if (nxt_line.find("BinaryDataByteOrderMSB")!= vcl_string::npos)
00377 {
00378 byte_order_msb_ = (val=="True") ? true : false;
00379 header_valid_ = true;
00380 check_need_swap();
00381 }
00382 else if (nxt_line.find("CompressedData")!= vcl_string::npos)
00383 {
00384 if (val=="True")
00385 {
00386 vcl_cerr << "Loader does not handle compressed data\n";
00387 return false;
00388 }
00389 }
00390 else if (nxt_line.find("TransformMatrix")!= vcl_string::npos)
00391 {
00392 if (val != "1 0 0 0 1 0 0 0 1")
00393 {
00394 vcl_cout << "Loader only handles identity in TransformMatrix.\n"
00395 << "Transformation ignored." << vcl_endl;
00396 }
00397 }
00398 else if (nxt_line.find("Offset")!= vcl_string::npos)
00399 {
00400 return set_header_offset(val);
00401 }
00402 else if (nxt_line.find("DimSize")!= vcl_string::npos)
00403 {
00404 return set_header_dim_size(val);
00405 }
00406 else if (nxt_line.find("ElementSpacing")!= vcl_string::npos)
00407 {
00408 return set_header_voxel_size(val);
00409 }
00410 else if (nxt_line.find("ElementSize")!= vcl_string::npos)
00411 {
00412 return set_header_voxel_size(val);
00413 }
00414 else if (nxt_line.find("ElementType")!= vcl_string::npos)
00415 {
00416 elem_type_ = val;
00417 if (elem_type_ == "MET_SHORT")
00418 pformat_ = VIL_PIXEL_FORMAT_INT_16;
00419 else if (elem_type_ == "MET_UCHAR")
00420 pformat_ = VIL_PIXEL_FORMAT_BYTE;
00421 else if (elem_type_ == "MET_CHAR")
00422 pformat_ = VIL_PIXEL_FORMAT_SBYTE;
00423 else if (elem_type_ == "MET_DOUBLE")
00424 pformat_ = VIL_PIXEL_FORMAT_DOUBLE;
00425 else if (elem_type_ == "MET_FLOAT")
00426 pformat_ = VIL_PIXEL_FORMAT_FLOAT;
00427 else
00428 {
00429 vcl_cerr << "Unsupported element type specified: " << val << "\n";
00430 return false;
00431 }
00432 header_valid_ = true;
00433 }
00434 else if (nxt_line.find("ElementDataFile")!= vcl_string::npos)
00435 {
00436 im_file_ = val;
00437 header_valid_ = true;
00438 }
00439 return true;
00440 }
00441
00442
00443
00444
00445 vcl_string vil3d_meta_image_header::get_header_value(const vcl_string &nxt_line)
00446 {
00447 vcl_string::size_type pos, epos;
00448 pos = nxt_line.find("=");
00449 if (pos == vcl_string::npos || pos == nxt_line.size()-1)
00450 {
00451 return "";
00452 }
00453
00454 pos = nxt_line.find_first_not_of(" ", pos+1);
00455 epos = nxt_line.find_last_not_of(" ");
00456 if (pos == vcl_string::npos || epos == vcl_string::npos)
00457 {
00458 return "";
00459 }
00460
00461 return nxt_line.substr(pos, (epos-pos)+1);
00462 }
00463
00464
00465
00466
00467 bool vil3d_meta_image_header::set_header_offset(const vcl_string &offs)
00468 {
00469 vcl_string::size_type pos,epos;
00470 epos=offs.find_first_of(" ");
00471 if (epos==vcl_string::npos)
00472 {
00473 vcl_cerr << "Offset does not contain three values.\n";
00474 return false;
00475 }
00476
00477 offset_i_=vcl_atof(offs.substr(0,epos).c_str());
00478 pos=offs.find_first_not_of(" ",epos);
00479 epos=offs.find_first_of(" ",pos);
00480 if (pos==vcl_string::npos || epos==vcl_string::npos)
00481 {
00482 vcl_cerr << "Offset does not contain three values.\n";
00483 return false;
00484 }
00485
00486 offset_j_=vcl_atof(offs.substr(pos,epos).c_str());
00487 pos=offs.find_first_not_of(" ",epos);
00488 if (pos==vcl_string::npos)
00489 {
00490 vcl_cerr << "Offset does not contain three values.\n";
00491 return false;
00492 }
00493 offset_k_=vcl_atof(offs.substr(pos).c_str());
00494 epos = offs.find_first_of(" ",pos);
00495 pos=offs.find_first_not_of(" ",epos);
00496 if (pos != vcl_string::npos)
00497 {
00498 vcl_cerr << "Offset contains more than three values.\n";
00499 return false;
00500 }
00501 header_valid_ = true;
00502 return true;
00503 }
00504
00505
00506
00507
00508 bool vil3d_meta_image_header::set_header_dim_size(const vcl_string &dims)
00509 {
00510 vcl_string::size_type pos,epos;
00511 epos=dims.find_first_of(" ");
00512 if (epos==vcl_string::npos)
00513 {
00514 vcl_cerr << "Dim Size does not contain three values.\n";
00515 return false;
00516 }
00517 dim_size_i_=vcl_atoi(dims.substr(0,epos).c_str());
00518 pos=dims.find_first_not_of(" ",epos);
00519 epos=dims.find_first_of(" ",pos);
00520 if (pos==vcl_string::npos || epos==vcl_string::npos)
00521 {
00522 vcl_cerr << "Dim Size does not contain three values.\n";
00523 return false;
00524 }
00525 dim_size_j_=vcl_atoi(dims.substr(pos,epos).c_str());
00526 pos=dims.find_first_not_of(" ",epos);
00527 if (pos==vcl_string::npos)
00528 {
00529 vcl_cerr << "Dim Size does not contain three values.\n";
00530 return false;
00531 }
00532 dim_size_k_=vcl_atoi(dims.substr(pos).c_str());
00533 epos = dims.find_first_of(" ",pos);
00534 pos=dims.find_first_not_of(" ",epos);
00535 if (pos != vcl_string::npos)
00536 {
00537 vcl_cerr << "Dim Size contains more than three values.\n";
00538 return false;
00539 }
00540
00541 nplanes_=1;
00542 header_valid_=true;
00543 return true;
00544 }
00545
00546
00547
00548
00549 bool vil3d_meta_image_header::set_header_voxel_size(const vcl_string &vsize)
00550 {
00551 vcl_string::size_type pos,epos;
00552 epos=vsize.find_first_of(" ");
00553 if (epos==vcl_string::npos)
00554 {
00555 vcl_cerr << "Element Spacing/Size does not contain three values.\n";
00556 return false;
00557 }
00558 vox_size_i_=vcl_atof(vsize.substr(0,epos).c_str());
00559 pos=vsize.find_first_not_of(" ",epos);
00560 epos=vsize.find_first_of(" ",pos);
00561 if (pos==vcl_string::npos || epos==vcl_string::npos)
00562 {
00563 vcl_cerr << "Element Spacing/Size does not contain three values.\n";
00564 return false;
00565 }
00566 vox_size_j_=vcl_atof(vsize.substr(pos,epos).c_str());
00567 pos=vsize.find_first_not_of(" ",epos);
00568 if (pos==vcl_string::npos)
00569 {
00570 vcl_cerr << "Element Spacing/Size does not contain three values.\n";
00571 return false;
00572 }
00573 vox_size_k_=vcl_atof(vsize.substr(pos).c_str());
00574 epos = vsize.find_first_of(" ",pos);
00575 pos=vsize.find_first_not_of(" ",epos);
00576 if (pos != vcl_string::npos)
00577 {
00578 vcl_cerr << "Element Spacing/Size contains more than three values.\n";
00579 return false;
00580 }
00581 header_valid_ = true;
00582 return true;
00583 }
00584
00585
00586
00587
00588 vcl_ostream& operator<<(vcl_ostream& os, const vil3d_meta_image_header& header)
00589 {
00590 header.print_header(os);
00591 return os;
00592 }
00593
00594
00595
00596
00597
00598
00599
00600
00601 vil3d_meta_image_format::vil3d_meta_image_format()
00602 {
00603
00604 }
00605
00606
00607
00608
00609 vil3d_meta_image_format::~vil3d_meta_image_format()
00610 {
00611
00612 }
00613
00614
00615
00616
00617 vil3d_image_resource_sptr vil3d_meta_image_format::make_input_image(const char *fname) const
00618 {
00619 vil3d_meta_image_header header;
00620 vcl_string filename(fname);
00621
00622 if (!header.read_header(fname)) return 0;
00623
00624
00625 return new vil3d_meta_image(header,filename);
00626 }
00627
00628
00629
00630
00631 vil3d_image_resource_sptr vil3d_meta_image_format::make_output_image(const char *filename,
00632 unsigned int ni,
00633 unsigned int nj,
00634 unsigned int nk,
00635 unsigned int nplanes,
00636 vil_pixel_format format) const
00637 {
00638 if (format != VIL_PIXEL_FORMAT_BYTE &&
00639 format != VIL_PIXEL_FORMAT_SBYTE &&
00640 format != VIL_PIXEL_FORMAT_INT_16 &&
00641 format != VIL_PIXEL_FORMAT_DOUBLE &&
00642 format != VIL_PIXEL_FORMAT_FLOAT)
00643 {
00644 vcl_cerr << "vil3d_meta_image_format::make_output_image() WARNING\n"
00645 << " Unable to deal with pixel format : " << format << vcl_endl;
00646 return 0;
00647 }
00648
00649 vil3d_meta_image_header header;
00650 header.clear();
00651 header.set_dim_size(ni,nj,nk,nplanes);
00652 header.set_pixel_format(format);
00653
00654 switch (format)
00655 {
00656 case VIL_PIXEL_FORMAT_BYTE: header.set_element_type("MET_UCHAR");
00657 break;
00658 case VIL_PIXEL_FORMAT_SBYTE: header.set_element_type("MET_CHAR");
00659 break;
00660 case VIL_PIXEL_FORMAT_INT_16: header.set_element_type("MET_SHORT");
00661 break;
00662 case VIL_PIXEL_FORMAT_DOUBLE: header.set_element_type("MET_DOUBLE");
00663 break;
00664 case VIL_PIXEL_FORMAT_FLOAT: header.set_element_type("MET_FLOAT");
00665 break;
00666 default:
00667 vcl_cerr << "vil3d_meta_image_format::make_output_image() WARNING\n"
00668 << " Unable to deal with pixel format : " << format << vcl_endl;
00669 return 0;
00670 }
00671
00672 vcl_string str_fname(filename);
00673 vcl_string base_filename;
00674 vcl_size_t n=str_fname.size();
00675 if (n>=4 && (str_fname.substr(n-4,4)==".mhd" || str_fname.substr(n-4,4)==".raw"))
00676 base_filename = str_fname.substr(0,n-4);
00677 else
00678 base_filename = str_fname;
00679 vcl_string im_file = vul_file::strip_directory(base_filename);
00680 header.set_image_fname(im_file + ".raw");
00681 if (!header.write_header(base_filename+".mhd")) return 0;
00682 return new vil3d_meta_image(header,base_filename);
00683 }
00684
00685
00686
00687
00688
00689
00690
00691
00692 vil3d_meta_image::vil3d_meta_image(const vil3d_meta_image_header &header,
00693 const vcl_string &fname) :
00694 header_(header),
00695 fpath_(fname)
00696 {
00697
00698 }
00699
00700
00701
00702
00703 vil3d_meta_image::~vil3d_meta_image(void)
00704 {
00705
00706 }
00707
00708
00709
00710
00711 unsigned int vil3d_meta_image::nplanes(void) const
00712 {
00713 return header_.nplanes();
00714 }
00715
00716 unsigned int vil3d_meta_image::ni(void) const
00717 {
00718 return header_.ni();
00719 }
00720
00721 unsigned int vil3d_meta_image::nj(void) const
00722 {
00723 return header_.nj();
00724 }
00725
00726 unsigned int vil3d_meta_image::nk(void) const
00727 {
00728 return header_.nk();
00729 }
00730
00731
00732
00733
00734 const vil3d_meta_image_header &vil3d_meta_image::header(void) const
00735 {
00736 return header_;
00737 }
00738
00739
00740
00741
00742 vil_pixel_format vil3d_meta_image::pixel_format(void) const
00743 {
00744 return header_.pixel_format();
00745 }
00746
00747
00748
00749
00750 bool vil3d_meta_image::set_voxel_size(float vi, float vj, float vk)
00751 {
00752 header_.set_vox_size(vi,vj,vk);
00753 if (!header_.write_header(fpath_+".mhd")) return false;
00754 return true;
00755 }
00756
00757
00758
00759
00760 void vil3d_meta_image::set_offset(const double i, const double j, const double k,
00761 const double vx_i, const double vx_j, const double vx_k)
00762 {
00763 double os_i, os_j, os_k;
00764 os_i = (-(i*vx_i));
00765 os_j = (-(j*vx_j));
00766 os_k = (-(k*vx_k));
00767 header_.set_offset(os_i,os_j,os_k);
00768 header_.set_vox_size(vx_i,vx_j,vx_k);
00769 header_.write_header(fpath_+".mhd");
00770 }
00771
00772
00773
00774
00775 vil3d_image_view_base_sptr vil3d_meta_image::get_copy_view(unsigned int i0, unsigned int ni,
00776 unsigned int j0, unsigned int nj,
00777 unsigned int k0, unsigned int nk) const
00778 {
00779
00780 if (i0!=0 || ni!=header_.ni() ||
00781 j0!=0 || nj!=header_.nj() ||
00782 k0!=0 || nk!=header_.nk() )
00783 return 0;
00784
00785 vcl_string image_data_path=header_.image_fname();
00786 vil_smart_ptr<vil_stream> is = new vil_stream_fstream(image_data_path.c_str(),"r");
00787 if (!is->ok()) return 0;
00788
00789
00790 #define read_data_of_type(type) \
00791 vil3d_image_view< type > im = \
00792 vil3d_new_image_view_plane_k_j_i(ni, nj, nk, nplanes(), type()); \
00793 is->read(&im(0,0,0,0), ni * nj * nk * nplanes() * sizeof(type));
00794
00795 switch (pixel_format())
00796 {
00797 case VIL_PIXEL_FORMAT_BYTE:
00798 {
00799 read_data_of_type(vxl_byte);
00800 return new vil3d_image_view<vxl_byte>(im);
00801 }
00802 case VIL_PIXEL_FORMAT_SBYTE:
00803 {
00804 read_data_of_type(vxl_sbyte);
00805 return new vil3d_image_view<vxl_sbyte>(im);
00806 }
00807 case VIL_PIXEL_FORMAT_INT_16:
00808 {
00809 read_data_of_type(vxl_int_16);
00810 if (header_.need_swap())
00811 vil3d_meta_image_swap16((char *)(im.origin_ptr()), ni*nj*nk);
00812 return new vil3d_image_view<vxl_int_16>(im);
00813 }
00814 case VIL_PIXEL_FORMAT_DOUBLE:
00815 {
00816 read_data_of_type(double);
00817 if (header_.need_swap())
00818 vil3d_meta_image_swap64((char *)(im.origin_ptr()), ni*nj*nk);
00819 return new vil3d_image_view<double>(im);
00820 }
00821 case VIL_PIXEL_FORMAT_FLOAT:
00822 {
00823 read_data_of_type(float);
00824 if (header_.need_swap())
00825 vil3d_meta_image_swap32((char *)(im.origin_ptr()), ni*nj*nk);
00826 return new vil3d_image_view<float>(im);
00827 }
00828 default:
00829 vcl_cout<<"ERROR: vil3d_meta_image_format::get_copy_view()\n"
00830 <<"Can't deal with pixel type " << pixel_format() << vcl_endl;
00831 return 0;
00832 }
00833 }
00834
00835
00836
00837
00838 bool vil3d_meta_image::put_view(const vil3d_image_view_base &im,
00839 unsigned int i0,
00840 unsigned int j0,
00841 unsigned int k0)
00842 {
00843 if (!view_fits(im, i0, j0, k0))
00844 {
00845 vcl_cerr << "ERROR: " << __FILE__ << ":\n view does not fit\n";
00846 return false;
00847 }
00848 if (im.ni()!=ni() || im.nj()!=nj() || im.nk()!=nk())
00849 {
00850 vcl_cerr<<"Can only write whole image at once.\n";
00851 return false;
00852 }
00853
00854 vcl_string image_data_path=fpath_+".raw";
00855 vil_smart_ptr<vil_stream> os = new vil_stream_fstream(image_data_path.c_str(),"w");
00856 if (!os->ok()) return 0;
00857
00858 switch (pixel_format())
00859 {
00860 case VIL_PIXEL_FORMAT_BYTE:
00861 {
00862 vil3d_image_view<vxl_byte> view_copy(ni(),nj(),nk(),nplanes());
00863 vil3d_copy_reformat(static_cast<const vil3d_image_view<vxl_byte>&>(im),view_copy);
00864 os->write(view_copy.origin_ptr(),ni()*nj()*nk()*nplanes());
00865
00866 return true;
00867 }
00868 case VIL_PIXEL_FORMAT_SBYTE:
00869 {
00870 vil3d_image_view<vxl_sbyte> view_copy(ni(),nj(),nk(),nplanes());
00871 vil3d_copy_reformat(static_cast<const vil3d_image_view<vxl_sbyte>&>(im),view_copy);
00872 os->write(view_copy.origin_ptr(),ni()*nj()*nk()*nplanes());
00873
00874 return true;
00875 }
00876 case VIL_PIXEL_FORMAT_INT_16:
00877 {
00878 header_.check_need_swap();
00879 vil3d_image_view<vxl_int_16> view_copy(ni(),nj(),nk(),nplanes());
00880 vil3d_copy_reformat(static_cast<const vil3d_image_view<vxl_int_16>&>(im),view_copy);
00881 if (header_.need_swap())
00882 vil3d_meta_image_swap16((char *)(view_copy.origin_ptr()), ni()*nj()*nk()*nplanes());
00883 os->write(view_copy.origin_ptr(),ni()*nj()*nk()*nplanes()*sizeof(vxl_int_16));
00884
00885 return true;
00886 }
00887 case VIL_PIXEL_FORMAT_DOUBLE:
00888 {
00889 header_.check_need_swap();
00890 vil3d_image_view<double> view_copy(ni(),nj(),nk(),nplanes());
00891 vil3d_copy_reformat(static_cast<const vil3d_image_view<double>&>(im),view_copy);
00892 if (header_.need_swap())
00893 vil3d_meta_image_swap64((char *)(view_copy.origin_ptr()), ni()*nj()*nk()*nplanes());
00894 os->write(view_copy.origin_ptr(),ni()*nj()*nk()*nplanes()*sizeof(double));
00895
00896 return true;
00897 }
00898 case VIL_PIXEL_FORMAT_FLOAT:
00899 {
00900 header_.check_need_swap();
00901 vil3d_image_view<float> view_copy(ni(),nj(),nk(),nplanes());
00902 vil3d_copy_reformat(static_cast<const vil3d_image_view<float>&>(im),view_copy);
00903 if (header_.need_swap())
00904 vil3d_meta_image_swap32((char *)(view_copy.origin_ptr()), ni()*nj()*nk()*nplanes());
00905 os->write(view_copy.origin_ptr(),ni()*nj()*nk()*nplanes()*sizeof(float));
00906
00907 return true;
00908 }
00909 default:
00910 vcl_cout<<"ERROR: vil3d_analyze_format::put_view()\n"
00911 <<"Can't deal with pixel type " << pixel_format() << vcl_endl;
00912 }
00913
00914 return false;
00915 }
00916
00917
00918
00919
00920 bool vil3d_meta_image::get_property(const char *label, void *property_value) const
00921 {
00922 if (vcl_strcmp(vil3d_property_voxel_size, label)==0)
00923 {
00924 float* array = static_cast<float*>(property_value);
00925
00926 array[0] = static_cast<float>(header_.vox_size_i() / 1000.0);
00927 array[1] = static_cast<float>(header_.vox_size_j() / 1000.0);
00928 array[2] = static_cast<float>(header_.vox_size_k() / 1000.0);
00929 return true;
00930 }
00931
00932 if (vcl_strcmp(vil3d_property_origin_offset, label)==0)
00933 {
00934 float* array = static_cast<float*>(property_value);
00935 array[0] = static_cast<float>((-header_.offset_i())/header_.vox_size_i());
00936 array[1] = static_cast<float>((-header_.offset_j())/header_.vox_size_j());
00937 array[2] = static_cast<float>((-header_.offset_k())/header_.vox_size_k());
00938 return true;
00939 }
00940
00941 return false;
00942 }
00943