From fe7d1dc64dfd5338baed4c667f9a2866f36fe573 Mon Sep 17 00:00:00 2001 From: Andreas Schenk <andreas_schenk@hms.harvard.edu> Date: Thu, 8 Sep 2011 18:14:57 -0400 Subject: [PATCH] added support for Ditabis Micron image plate image format --- modules/io/pymod/export_map_io.cc | 13 +- modules/io/src/img/CMakeLists.txt | 2 + modules/io/src/img/map_io_ipl_handler.cc | 415 +++++++++++++++++++++++ modules/io/src/img/map_io_ipl_handler.hh | 78 +++++ modules/io/src/io_manager.cc | 4 +- modules/io/tests/test_io_img.cc | 27 ++ 6 files changed, 535 insertions(+), 4 deletions(-) create mode 100644 modules/io/src/img/map_io_ipl_handler.cc create mode 100644 modules/io/src/img/map_io_ipl_handler.hh diff --git a/modules/io/pymod/export_map_io.cc b/modules/io/pymod/export_map_io.cc index beb7601bc..afe494d19 100644 --- a/modules/io/pymod/export_map_io.cc +++ b/modules/io/pymod/export_map_io.cc @@ -27,6 +27,7 @@ #include <ost/io/img/map_io_dat_handler.hh> #include <ost/io/img/map_io_jpk_handler.hh> #include <ost/io/img/map_io_nanoscope_handler.hh> +#include <ost/io/img/map_io_ipl_handler.hh> #include <ost/io/img/image_format.hh> #include <ost/io/img/load_map.hh> @@ -79,18 +80,17 @@ void export_map_io() .export_values() ; - enum_<Subformat>("Format") + enum_<Subformat>("Subformat") .value("MRC_NEW_FORMAT", MRC_NEW_FORMAT) .value("MRC_OLD_FORMAT", MRC_OLD_FORMAT) .value("MRC_AUTO_FORMAT", MRC_AUTO_FORMAT) .export_values() ; + class_<ImageFormatBase>("ImageFormatBase",no_init) .def("GetMaximum", &ImageFormatBase::GetMaximum) - .def("SetMaximum", &ImageFormatBase::GetMaximum) .def("GetMinimum", &ImageFormatBase::GetMinimum) - .def("SetMinimum", &ImageFormatBase::GetMinimum) ; class_<DX, bases<ImageFormatBase> >("DX", init<bool>(arg("normalize_on_save") = false)) @@ -154,6 +154,13 @@ void export_map_io() .def("GetBitDepth", &DAT::GetBitDepth) ; + class_<IPL, bases<ImageFormatBase> >("IPL", init<bool,Format>((arg("normalize_on_save") = true,arg("format")=OST_DEFAULT_FORMAT))) + .def("SetNormalizeOnSave", &IPL::SetNormalizeOnSave) + .def("GetNormalizeOnSave", &IPL::GetNormalizeOnSave) + .def("SetBitDepth", &IPL::SetBitDepth) + .def("GetBitDepth", &IPL::GetBitDepth) + ; + class_<JPK, bases<TIF> >("JPK", init<boost::logic::tribool,Format,bool,bool,int> ((arg("normalize_on_save") = boost::logic::tribool(boost::logic::indeterminate),arg("format")=OST_DEFAULT_FORMAT,arg("signed")=false,arg("phasecolor")=false,arg("subimage") = -1))) ; diff --git a/modules/io/src/img/CMakeLists.txt b/modules/io/src/img/CMakeLists.txt index 8fa9a30ff..d17f46e8e 100644 --- a/modules/io/src/img/CMakeLists.txt +++ b/modules/io/src/img/CMakeLists.txt @@ -7,6 +7,7 @@ map_io_mrc_handler.cc map_io_dm3_handler.cc map_io_tiff_handler.cc map_io_dat_handler.cc +map_io_ipl_handler.cc map_io_jpk_handler.cc map_io_nanoscope_handler.cc map_io_png_handler.cc @@ -28,6 +29,7 @@ map_io_situs_handler.hh map_io_handler.hh map_io_mrc_handler.hh map_io_dat_handler.hh +map_io_ipl_handler.hh map_io_jpk_handler.hh map_io_nanoscope_handler.hh map_io_png_handler.hh diff --git a/modules/io/src/img/map_io_ipl_handler.cc b/modules/io/src/img/map_io_ipl_handler.cc new file mode 100644 index 000000000..61274b0cf --- /dev/null +++ b/modules/io/src/img/map_io_ipl_handler.cc @@ -0,0 +1,415 @@ +//------------------------------------------------------------------------------ +// This file is part of the OpenStructure project <www.openstructure.org> +// +// Copyright (C) 2008-2011 by the OpenStructure authors +// Copyright (C) 2003-2010 by the IPLT authors +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License as published by the Free +// Software FounIPLion; either version 3.0 of the License, or (at your option) +// any later version. +// This library is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more +// details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this library; if not, write to the Free Software FounIPLion, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110String::npos301 USA +//------------------------------------------------------------------------------ +#include <cassert> +#include <ctime> +#include <iomanip> + +#include <boost/shared_array.hpp> +#include <boost/filesystem/operations.hpp> +#include <boost/filesystem/fstream.hpp> +#include <ost/stdint.hh> +#include <ost/units.hh> +#include <ost/log.hh> +#include <ost/img/image.hh> +#include <ost/img/alg/normalizer_factory.hh> +#include <ost/img/progress.hh> +#include <ost/io/io_exception.hh> +#include <ost/io/convert.hh> +#include <ost/io/converting_streams.hh> +#include <ost/img/alg/discrete_shrink.hh> + +#include "map_io_ipl_handler.hh" + +namespace ost { namespace io { + +String IPL::FORMAT_STRING = "defined_ipl"; + +IPL::IPL(bool normalize_on_save, Format bit_depth): + ImageFormatBase(FORMAT_STRING), + normalize_on_save_(normalize_on_save), + bit_depth_(OST_DEFAULT_FORMAT) +{ + this->SetBitDepth(bit_depth); +} + +Format IPL::GetBitDepth() const +{ + return bit_depth_; +} + +void IPL::SetBitDepth (Format bitdepth) +{ + if( ! (bitdepth==OST_BIT16_FORMAT || bitdepth==OST_BIT32_FORMAT || bitdepth==OST_DEFAULT_FORMAT)) + { + throw IOException("Unsupported bit depth for IPL file format."); + } + + bit_depth_ = bitdepth; +} + +bool IPL::GetNormalizeOnSave() const +{ + return normalize_on_save_; +} + +void IPL::SetNormalizeOnSave(bool normalize_on_save) +{ + normalize_on_save_ = normalize_on_save; +} + +Real IPL::GetMaximum() const +{ + switch(bit_depth_){ + case OST_BIT32_FORMAT: + return 4294967295.0; + default: + return 65535.0; + } +} + +Real IPL::GetMinimum() const +{ + return 0.0; +} + +bool MapIOIPLHandler::MatchContent(unsigned char* header) +{ + String magic_token("DITABIS micron Data File"); + if(magic_token.compare(0,magic_token.size(),reinterpret_cast<char*>(header),magic_token.size())==0) + { + return true; + } + return false; +} + +namespace detail{ + +class IPLHeader{ +public: + IPLHeader(): + date(), + header_length(2048), + size_x(), + size_y(), + bit_depth(), + resolution_x(), + resolution_y(), + magnification(1), + thumb_nail_zoom(10), + channel("PMT LOWSENS"), + params("dummy.set"), + format("2 2 2 2 Standard.fmt"), + laser(30), + gain(20000), + offset_correction(true), + offset(0), + comment() + {} + IPLHeader(const img::ConstImageHandle& im,Format bit_depth): + date(), + header_length(2048), + size_x(im.GetSize()[0]), + size_y(im.GetSize()[1]), + bit_depth(bit_depth==OST_BIT32_FORMAT ? 4: 2), + resolution_x(im.GetSpatialSampling()[0]), + resolution_y(im.GetSpatialSampling()[1]), + magnification(1), + thumb_nail_zoom(10), + channel("PMT LOWSENS"), + params("dummy.set"), + format("2 2 2 2 Standard.fmt"), + laser(30), + gain(20000), + offset_correction(true), + offset(0), + comment() + {} + String date; + int header_length; + int size_x; + int size_y; + int bit_depth; + Real resolution_x; + Real resolution_y; + int magnification; + int thumb_nail_zoom; + String channel; + String params; + String format; + int laser; + int gain; + bool offset_correction; + int offset; + String comment; +}; + +std::ostream& operator<< (std::ostream& out, const IPLHeader& h ) +{ + uint start_pos = out.tellp(); + out << "DITABIS micron Data File\r\n"; + time_t rawtime=time(NULL); + char * timestr = asctime(localtime(&rawtime)); + timestr[strlen(timestr)-1] = '\0'; + out << "CREATED = "<< timestr <<" \r\n"; + out << "HEADER = "<< h.header_length <<" \r\n"; + // x and y get swapped here (follows the behaviour of the original conversion software) + out << "YPIXEL = "<< h.size_x <<" \r\n"; + out << "XPIXEL = "<< h.size_y <<" \r\n"; + out << "BYTE PER PIXEL = "<< h.bit_depth <<" \r\n"; + // x and y get swapped here (follows the behaviour of the original conversion software) + out << "XRESOLUTION = "<< std::setprecision(0)<< h.resolution_y/Units::nm <<" (" << std::setprecision(2)<< h.resolution_y/Units::nm<<") \r\n"; + out << "YRESOLUTION = "<< std::setprecision(0)<< h.resolution_x/Units::nm <<" (" << std::setprecision(2)<< h.resolution_x/Units::nm<<") \r\n"; + out << "MAGNIFICATION = "<< h.magnification <<" \r\n"; + out << "THUMB-NAIL-ZOOM = "<< h.thumb_nail_zoom <<" \r\n"; + out << "CHANNEL = "<< h.channel <<" \r\n"; + out << "PARAMS = "<< h.params <<" \r\n"; + out << "FORMAT = "<< h.format <<" \r\n"; + out << "LASER = "<< h.laser <<" \r\n"; + out << "GAIN = "<< h.gain <<" \r\n"; + if(h.offset_correction){ + out << "OFFSET CORRECTION = YES \r\n"; + }else{ + out << "OFFSET CORRECTION = NO \r\n"; + } + out << "OFFSET = "<< h.offset <<" \r\n"; + out << "COMMENT = Created by OpenStructure \r\n"; + out << " \r\n"; + uint fillsize=h.header_length-out.tellp()+start_pos; + char empty[fillsize]; + std::fill_n(empty,fillsize,0); + out.write(empty,fillsize); + return out; +} + +std::istream& operator>> (std::istream& in, IPLHeader& h) +{ + String line; + uint start_pos = in.tellg(); + do{ + std::getline(in,line); + if(line.find("DITABIS micron Data File")!=String::npos){ + //ignore + }else if(line.find("CREATED")!=String::npos){ + h.date=line.substr(line.find("=")+2); + }else if(line.find("HEADER")!=String::npos){ + std::istringstream ( line.substr(line.find("=")+2) ) >> h.header_length; + // x and y get swapped here (follows the behaviour of the original conversion software) + }else if(line.find("XPIXEL")!=String::npos){ + std::istringstream ( line.substr(line.find("=")+2) ) >> h.size_y; + }else if(line.find("YPIXEL")!=String::npos){ + std::istringstream ( line.substr(line.find("=")+2) ) >> h.size_x; + }else if(line.find("BYTE PER PIXEL")!=String::npos){ + std::istringstream ( line.substr(line.find("=")+2) ) >> h.bit_depth; + // x and y get swapped here (follows the behaviour of the original conversion software) + }else if(line.find("XRESOLUTION")!=String::npos){ + std::istringstream ( line.substr(line.find("(")+1) ) >> h.resolution_y; + h.resolution_y*=Units::nm; + }else if(line.find("YRESOLUTION")!=String::npos){ + std::istringstream ( line.substr(line.find("(")+1) ) >> h.resolution_x; + h.resolution_x*=Units::nm; + }else if(line.find("MAGNIFICATION")!=String::npos){ + std::istringstream ( line.substr(line.find("=")+2) ) >> h.magnification; + }else if(line.find("THUMB-NAIL-ZOOM")!=String::npos){ + std::istringstream ( line.substr(line.find("=")+2) ) >> h.thumb_nail_zoom; + }else if(line.find("CHANNEL")!=String::npos){ + h.channel=line.substr(line.find("=")+2); + }else if(line.find("PARAMS")!=String::npos){ + h.params=line.substr(line.find("=")+2); + }else if(line.find("FORMAT")!=String::npos){ + h.format=line.substr(line.find("=")+2); + }else if(line.find("LASER")!=String::npos){ + std::istringstream ( line.substr(line.find("=")+2) ) >> h.laser; + }else if(line.find("GAIN")!=String::npos){ + std::istringstream ( line.substr(line.find("=")+2) ) >> h.gain; + }else if(line.find("OFFSET CORRECTION")!=String::npos){ + if(line.substr(line.find("=")+2).find("YES")!=String::npos){ + h.offset_correction=true; + }else{ + h.offset_correction=false; + } + }else if(line.find("OFFSET")!=String::npos){ + std::istringstream ( line.substr(line.find("=")+2) ) >> h.offset; + }else if(line.find("COMMENT")!=String::npos){ + h.comment=line.substr(line.find("=")+2); + }else if(line.find(" ")!=String::npos){ + //ignore + }else{ + LOG_ERROR("IPL import: unknown header line: " << line); + } + }while(in.peek()!=0); + uint fillsize=h.header_length-in.tellg()+start_pos; + char empty[h.header_length]; + std::fill_n(empty,fillsize,0); + in.read(empty,fillsize); + return in; +} + +}//ns + +bool MapIOIPLHandler::MatchType(const ImageFormatBase& type) +{ + if(type.GetFormatString()==IPL::FORMAT_STRING) { + return true; + } + return false; +} + +bool MapIOIPLHandler::MatchSuffix(const String& loc) +{ + if(detail::FilenameEndsWith(loc,".IPL") || detail::FilenameEndsWith(loc,".ipl") ) { + return true; + } + return false; +} + +void MapIOIPLHandler::Import(img::MapHandle& sh, const boost::filesystem::path& loc,const ImageFormatBase& formatstruct ) +{ + boost::filesystem::ifstream infile(loc, std::ios::binary); + if(!infile) { + throw IOException("could not open "+loc.string()); + } + this->Import(sh,infile,formatstruct); + infile.close(); +} + +template <typename DATATYPE> +void real_filler(img::image_state::RealSpatialImageState& isi, std::istream& file) +{ + BinaryIStream<OST_LITTLE_ENDIAN> file_bin(file); + img::Size size = isi.GetSize(); + char this_dummy; //create dummy variable to give to img::Progress as this + img::Progress::Instance().Register(&this_dummy,size[1],100); + for(unsigned int row=0;row<size[1];row++) { + for(unsigned int column=0;column<size[0];column++) { + DATATYPE value; + file_bin >> value; + isi.Value(img::Point(column,row))=static_cast<Real>(value); + } + img::Progress::Instance().AdvanceProgress(&this_dummy); + } + img::Progress::Instance().DeRegister(&this_dummy); +} + +template <typename DATATYPE> +void real_dumper( const img::ConstImageHandle& sh, std::ostream& file, const IPL& formatIPL, int shrinksize) +{ + img::image_state::RealSpatialImageState *isi=dynamic_cast<img::image_state::RealSpatialImageState*>(sh.ImageStatePtr().get()); + if(! isi){ + throw(IOException("IPL export: dynamic cast failed in real dumper.")); + } + BinaryOStream<OST_LITTLE_ENDIAN> file_bin(file); + img::alg::Normalizer norm = img::alg::CreateNoOpNormalizer(); + if (formatIPL.GetNormalizeOnSave() == true) { + norm = img::alg::CreateLinearRangeNormalizer(sh,formatIPL.GetMinimum(),formatIPL.GetMaximum()); + } + img::Size size = isi->GetSize(); + img::ImageHandle thumbnail=sh.Apply(img::alg::DiscreteShrink(img::Size(shrinksize,shrinksize,1))); + img::image_state::RealSpatialImageState *thumb_isi=dynamic_cast<img::image_state::RealSpatialImageState*>(thumbnail.ImageStatePtr().get()); + if(! thumb_isi){ + throw(IOException("IPL export: dynamic cast failed in real dumper.")); + } + + char this_dummy; //create dummy variable to give to img::Progress as this + img::Progress::Instance().Register(&this_dummy,size[1]+1,100); + for(unsigned int row=0;row<size[1];row++) { + for(unsigned int column=0;column<size[0];column++) + { + file_bin << static_cast<DATATYPE>(norm.Convert(isi->Value(ost::img::Point(column,row,0)))); + } + img::Progress::Instance().AdvanceProgress(&this_dummy); + } + img::Progress::Instance().AdvanceProgress(&this_dummy); + img::Size thumb_size = thumb_isi->GetSize(); + for(unsigned int row=0;row<thumb_size[1];row++) { + for(unsigned int column=0;column<thumb_size[0];column++) + { + file_bin << static_cast<DATATYPE>(norm.Convert(thumb_isi->Value(ost::img::Point(column,row,0)))); + } + img::Progress::Instance().AdvanceProgress(&this_dummy); + } + img::Progress::Instance().DeRegister(&this_dummy); +} + + +void MapIOIPLHandler::Import(img::MapHandle& sh, std::istream& file, const ImageFormatBase& formatstruct) +{ + + IPL form; + IPL& formatIPL = form; + if (formatstruct.GetFormatString()==IPL::FORMAT_STRING) { + formatIPL = formatstruct.As<IPL>(); + } else { + assert (formatstruct.GetFormatString()==UndefinedImageFormat::FORMAT_STRING); + } + + detail::IPLHeader header; + file >> header; + + sh.Reset(img::Extent(img::Point(0,0),img::Size(header.size_x,header.size_y)), img::REAL, img::SPATIAL); + sh.SetSpatialSampling(geom::Vec3(header.resolution_x,header.resolution_y,1.0)); + img::image_state::RealSpatialImageState * isi; + if(! (isi=dynamic_cast<img::image_state::RealSpatialImageState*>(sh.ImageStatePtr().get()))) { + throw IOException("internal error in IPL io: expected RealSpatialImageState"); + } + + if(header.bit_depth==4){ + real_filler<uint32_t>(*isi,file); + }else{ + real_filler<uint16_t>(*isi,file); + } +} + +void MapIOIPLHandler::Export(const img::MapHandle& mh2, + const boost::filesystem::path& loc,const ImageFormatBase& formatstruct) const +{ + boost::filesystem::ofstream outfile(loc, std::ios::binary); + if(!outfile) + { + throw IOException("could not open "+loc.string()); + } + this->Export(mh2,outfile,formatstruct); + outfile.close(); +} + +void MapIOIPLHandler::Export(const img::MapHandle& sh, std::ostream& file,const ImageFormatBase& formatstruct) const +{ + + IPL form; + IPL& formatIPL = form; + if (formatstruct.GetFormatString()==IPL::FORMAT_STRING) { + formatIPL = formatstruct.As<IPL>(); + } else { + assert (formatstruct.GetFormatString()==UndefinedImageFormat::FORMAT_STRING); + } + if (sh.GetSize()[2]!=1 || sh.GetDomain()!=img::SPATIAL || sh.GetType()!=img::REAL) { + throw IOException("IPL IO: IPL format only supports spatial 2D images."); + } + detail::IPLHeader header(sh,formatIPL.GetBitDepth()); + file << header; + if(header.bit_depth==4){ + real_dumper<uint32_t>(sh,file,formatIPL,header.thumb_nail_zoom); + }else{ + real_dumper<uint16_t>(sh,file,formatIPL,header.thumb_nail_zoom); + } +} + +}} // namespaces + + diff --git a/modules/io/src/img/map_io_ipl_handler.hh b/modules/io/src/img/map_io_ipl_handler.hh new file mode 100644 index 000000000..3e76ac989 --- /dev/null +++ b/modules/io/src/img/map_io_ipl_handler.hh @@ -0,0 +1,78 @@ +//------------------------------------------------------------------------------ +// This file is part of the OpenStructure project <www.openstructure.org> +// +// Copyright (C) 2008-2011 by the OpenStructure authors +// Copyright (C) 2003-2010 by the IPLT authors +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License as published by the Free +// Software Foundation; either version 3.0 of the License, or (at your option) +// any later version. +// This library is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more +// details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this library; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +//------------------------------------------------------------------------------ +#ifndef OST_IO_MAP_IO_IPL_HANDLER_HH +#define OST_IO_MAP_IO_IPL_HANDLER_HH + + +/* +Andreas Schenk +*/ + +#include "map_io_handler.hh" + +namespace ost { namespace io { + +class DLLEXPORT_OST_IO IPL: public ImageFormatBase +{ + + public: + + IPL(bool normalize_on_save = true, Format bit_depth = OST_DEFAULT_FORMAT); + + Format GetBitDepth() const; + void SetBitDepth ( Format bitdepth); + + + bool GetNormalizeOnSave() const; + void SetNormalizeOnSave(bool normalize_on_save=true); + Real GetMaximum() const; + Real GetMinimum() const; + static String FORMAT_STRING; + + private: + bool normalize_on_save_; + Format bit_depth_; + +}; + +class DLLEXPORT_OST_IO MapIOIPLHandler: public MapIOHandler +{ + public: + /// \brief Map IO handler to read/write Ipl map files + /// + /// This map IO handler reads and writes Ipl formatted map files. + virtual void Import(img::MapHandle& sh, const boost::filesystem::path& loc,const ImageFormatBase& formatstruct ); + virtual void Import(img::MapHandle& sh, std::istream& loc, const ImageFormatBase& formatstruct); + virtual void Export(const img::MapHandle& sh, const boost::filesystem::path& loc, const ImageFormatBase& formatstruct) const; + virtual void Export(const img::MapHandle& sh, std::ostream& loc,const ImageFormatBase& formatstruct) const; + static bool MatchContent(unsigned char* header); + static bool MatchType(const ImageFormatBase& type); + static bool MatchSuffix(const String& loc); + static bool ProvidesImport() { return true; } + static bool ProvidesExport() { return true; } + static String GetFormatName() { return String("IPL"); } + static String GetFormatDescription() {return String("Ditabis Micron Image Plate Scanner Format");} +}; + +typedef MapIOHandlerFactory<MapIOIPLHandler> MapIOIPLHandlerFactory; + +}} // ns + +#endif diff --git a/modules/io/src/io_manager.cc b/modules/io/src/io_manager.cc index 12e714fd6..071be5c11 100644 --- a/modules/io/src/io_manager.cc +++ b/modules/io/src/io_manager.cc @@ -38,6 +38,7 @@ # include <ost/io/img/map_io_jpk_handler.hh> # include <ost/io/img/map_io_nanoscope_handler.hh> # include <ost/io/img/map_io_df3_handler.hh> +# include <ost/io/img/map_io_ipl_handler.hh> #endif namespace ost { namespace io { @@ -63,7 +64,8 @@ IOManager::IOManager() RegisterFactory(MapIOHandlerFactoryBasePtr(new MapIOJpkHandlerFactory)); RegisterFactory(MapIOHandlerFactoryBasePtr(new MapIODatHandlerFactory)); RegisterFactory(MapIOHandlerFactoryBasePtr(new MapIONanoscopeHandlerFactory)); - RegisterFactory(MapIOHandlerFactoryBasePtr(new MapIODF3HandlerFactory)); + RegisterFactory(MapIOHandlerFactoryBasePtr(new MapIODF3HandlerFactory)); + RegisterFactory(MapIOHandlerFactoryBasePtr(new MapIOIPLHandlerFactory)); #endif } diff --git a/modules/io/tests/test_io_img.cc b/modules/io/tests/test_io_img.cc index d8165dd76..9f21257d3 100644 --- a/modules/io/tests/test_io_img.cc +++ b/modules/io/tests/test_io_img.cc @@ -34,6 +34,7 @@ #include <ost/io/img/map_io_dat_handler.hh> #include <ost/io/img/map_io_jpk_handler.hh> #include <ost/io/img/map_io_nanoscope_handler.hh> +#include <ost/io/img/map_io_ipl_handler.hh> #include <ost/img/alg/normalizer_factory.hh> using namespace ost; @@ -82,6 +83,7 @@ BOOST_AUTO_TEST_CASE(test_io_img) } //int 16 formats std::map<String,ImageFormatBase*> int_formats; + int_formats["IPL (16 bit)"]=new IPL(true,OST_BIT16_FORMAT); int_formats["DAT (16 bit)"]=new DAT(true,OST_BIT16_FORMAT); int_formats["TIF (16 bit)"]=new TIF; int_formats["JPK (16 bit)"]=new JPK; @@ -108,6 +110,31 @@ BOOST_AUTO_TEST_CASE(test_io_img) delete it->second; } + //int 32 formats + std::map<String,ImageFormatBase*> int32_formats; + int32_formats["IPL (16 bit)"]=new IPL(true,OST_BIT32_FORMAT); + for(std::map<String,ImageFormatBase*>::iterator it=int32_formats.begin();it!=int32_formats.end();++it){ + ost::io::SaveImage(testimage,fname,*(it->second)); + ost::img::ImageHandle loadedimage=ost::io::LoadImage(fname,*(it->second)); + ost::img::alg::Normalizer norm=ost::img::alg::CreateLinearRangeNormalizer(testimage,0.0,4294967295.0); + ost::img::ImageHandle scaled_image=testimage.Apply(norm); + bool failed=false; + ost::img::ExtentIterator eit(scaled_image.GetExtent()); + for(;!eit.AtEnd();++eit) { + if( static_cast<int>(scaled_image.GetReal(eit))!=static_cast<int>(loadedimage.GetReal(eit))){ + failed=true; + break; + } + } + if(failed){ + BOOST_ERROR("Image IO failed for plugin " << it->first << " at point " + << ost::img::Point(eit)<< ". Should be " + << static_cast<int>(scaled_image.GetReal(eit)) << ", but " + << static_cast<int>(loadedimage.GetReal(eit)) << " found."); + } + delete it->second; + } + //byte formats std::map<String,ImageFormatBase*> byte_formats; byte_formats["DAT (byte)"]=new DAT(true,OST_BIT8_FORMAT); -- GitLab