/******************************************************************** ** Image Component Library (ICL) ** ** ** ** Copyright (C) 2006-2010 CITEC, University of Bielefeld ** ** Neuroinformatics Group ** ** Website: www.iclcv.org and ** ** http://opensource.cit-ec.de/projects/icl ** ** ** ** File : ICLIO/src/FileGrabberPluginPNM.cpp ** ** Module : ICLIO ** ** Authors: Christof Elbrechter, Michael Götting ** ** ** ** ** ** Commercial License ** ** ICL can be used commercially, please refer to our website ** ** www.iclcv.org for more details. ** ** ** ** GNU General Public License Usage ** ** Alternatively, this file may be used under the terms of the ** ** GNU General Public License version 3.0 as published by the ** ** Free Software Foundation and appearing in the file LICENSE.GPL ** ** included in the packaging of this file. Please review the ** ** following information to ensure the GNU General Public License ** ** version 3.0 requirements will be met: ** ** http://www.gnu.org/copyleft/gpl.html. ** ** ** ** The development of this software was supported by the ** ** Excellence Cluster EXC 277 Cognitive Interaction Technology. ** ** The Excellence Cluster EXC 277 is a grant of the Deutsche ** ** Forschungsgemeinschaft (DFG) in the context of the German ** ** Excellence Initiative. ** ** ** *********************************************************************/ #include <ICLIO/FileGrabberPluginPNM.h> #include <ICLUtils/Exception.h> #include <ICLUtils/StringUtils.h> #include <ICLCC/CCFunctions.h> #include <ICLIO/IOUtils.h> using namespace std; using namespace icl::ioutils; namespace icl{ void FileGrabberPluginPNM::grab(File &file, ImgBase **dest){ ICLASSERT_RETURN(dest); file.open(File::readBinary); string nextLine; bool bIsICL = file.getSuffix() == ".icl" || file.getSuffix() == ".icl.gz"; ////////////////////////////////////////////////////////////////////// /// READ HEADER INFORMATION FROM THE FILE /////////////////////////// ////////////////////////////////////////////////////////////////////// FileGrabberPlugin::HeaderInfo oInfo; oInfo.imageFormat = formatGray; oInfo.imageDepth = depth8u; oInfo.channelCount = 0; oInfo.imageCount = 1; if(!bIsICL){ string l = file.readLine(); if(l.length() < 2 || l[0] != 'P') throw InvalidFileFormatException(); switch (l[1]) { case '6': oInfo.imageFormat = formatRGB; break; case '5': oInfo.imageFormat = formatGray; break; default: throw InvalidFileFormatException(); } } oInfo.channelCount = getChannelsOfFormat(oInfo.imageFormat); // {{{ Read special header info do { nextLine = ioutils::skipWhitespaces(file.readLine()); vector<string> ts = tok(nextLine," "); if(ts.size() < 3) continue; string sKey = ts[1]; if (sKey == "NumFeatures" || sKey == "NumImages") { oInfo.imageCount = parse<int>(ts[2]); if(!oInfo.imageCount) throw InvalidFileFormatException(); oInfo.channelCount *= oInfo.imageCount; } else if (sKey == "ROI") { oInfo.roi = Rect(ti(ts[2]),ti(ts[3]),ti(ts[4]),ti(ts[5])); continue; } else if (sKey == "ImageDepth") { if (!bIsICL) continue; // ignore image depth for all formats but ICL oInfo.imageDepth = parse<depth>( ts[2] ); continue; } else if (sKey == "Format") { oInfo.imageFormat = parse<format>(ts[2]); } else if (sKey == "TimeStamp") { oInfo.time = parse<Time>(ts[2]); continue; } if(getChannelsOfFormat(oInfo.imageFormat) != oInfo.channelCount){ oInfo.imageFormat = formatMatrix; } } while (nextLine.length()==0 || nextLine[0]=='#'); // }}} // read image size vector<string> ts = tok(nextLine," "); if(ts.size() != 2) throw InvalidFileFormatException(); if(bIsICL){ oInfo.size = Size(ti(ts[0]),ti(ts[1])); }else{ oInfo.size = Size(ti(ts[0]),ti(ts[1])/oInfo.imageCount); } // the next line shows the maximal pixel value -> skip if(file.readLine().size() == 0) throw InvalidFileFormatException(); ////////////////////////////////////////////////////////////////////// /// ADAPT THE DESTINATION IMAGE ////////////////////////////////////// ////////////////////////////////////////////////////////////////////// //printf("destination roi = %s \n",translateRect(oInfo.roi).c_str()); //printf("destination size = %s \n",translateSize(oInfo.size).c_str()); ensureCompatible (dest, oInfo.imageDepth, oInfo.size, oInfo.channelCount,oInfo.imageFormat, oInfo.roi); ImgBase *poImg = *dest; poImg->setTime(oInfo.time); ////////////////////////////////////////////////////////////////////// /// READ THE DATA //////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// if (oInfo.imageCount == oInfo.channelCount || bIsICL) { // file format is non-interleaved, i.e. grayscale or icl proprietary int iDim = poImg->getDim () * getSizeOf (poImg->getDepth ()); for (int i=0;i<oInfo.channelCount;i++){ if(file.read(iDim,poImg->getDataPtr(i)) != iDim){ throw InvalidFileFormatException(); } } } else if (poImg->getDepth() == depth8u) { /// interleaved channels image by image int iImageStep = poImg->getDim()*(poImg->getChannels()/oInfo.imageCount)*sizeof(icl8u); if(file.bytesAvailable() < oInfo.imageCount*iImageStep){ throw InvalidFileFormatException(); } Img8u buf; for(int i=0;i<oInfo.imageCount;i++){ poImg->asImg<icl8u>()->selectChannels(vec3(3*i,3*i+1,3*i+2),&buf); buf.setFullROI(); interleavedToPlanar(file.getCurrentDataPointer()+i*iImageStep,&buf); } } else { ERROR_LOG ("This should not happen!"); } } }