#include "iclFileWriterPluginPNM.h" #include #include #include #include #include "iclIOUtils.h" #include "iclStringUtils.h" using namespace std; using namespace icl::ioutils; namespace icl{ namespace{ void pnm_write_gray2rgb(File &file, const ImgBase *poSrc, vector &buffer){ int dim = poSrc->getDim(); buffer.resize(3*dim); switch(poSrc->getDepth()){ #define ICL_INSTANTIATE_DEPTH(D) \ case depth##D:{ \ const icl##D *src = poSrc->asImg()->getData(0); \ icl8u *dst = &buffer[0]; \ for(int i=0;i(src[i]); \ } \ break;} ICL_INSTANTIATE_ALL_DEPTHS; #undef ICL_INSTANTIATE_DEPTH } file.write(&buffer[0],buffer.size()); } void pnm_write_2channels2rgb(File &file, const ImgBase *poSrc, vector &buffer){ int dim = poSrc->getDim(); buffer.resize(3*dim); switch(poSrc->getDepth()){ #define ICL_INSTANTIATE_DEPTH(D) \ case depth##D:{ \ const icl##D *src1 = poSrc->asImg()->getData(0); \ const icl##D *src2 = poSrc->asImg()->getData(1); \ icl8u *dst = &buffer[0]; \ for(int i=0;i(src1[i]); \ dst[3*i+1]=clipped_cast(src2[i]); \ dst[3*i+2]=0; \ } \ break;} ICL_INSTANTIATE_ALL_DEPTHS; #undef ICL_INSTANTIATE_DEPTH } file.write(&buffer[0],buffer.size()); } void pnm_write3(File &file,const ImgBase *image, int channeloffs, vector &buffer){ Rect fullROI(Point::null,image->getSize()); format fmt = image->getFormat(); const ImgBase *img = image->shallowCopy(fullROI,ioutils::vec3(channeloffs,channeloffs+1,channeloffs+2),fmt); buffer.resize(3*image->getDim()); switch(img->getDepth()){ #define ICL_INSTANTIATE_DEPTH(D) case depth##D: planarToInterleaved(img->asImg(),&buffer[0]); break; ICL_INSTANTIATE_ALL_DEPTHS; #undef ICL_INSTANTIATE_DEPTH } file.write(&buffer[0],buffer.size()); delete img; } void pgm_write(File &file,const ImgBase *image, int channel, vector &buffer){ buffer.resize(image->getDim()); switch(image->getDepth()){ #define ICL_INSTANTIATE_DEPTH(D) \ case depth##D: \ convert(image->asImg()->getData(channel), \ image->asImg()->getData(channel)+image->getDim(), \ &buffer[0]); \ break; ICL_INSTANTIATE_ALL_DEPTHS; #undef ICL_INSTANTIATE_DEPTH } file.write(&buffer[0],buffer.size()); } } void FileWriterPluginPNM::write(File &file, const ImgBase *poSrc){ ICLASSERT_RETURN(poSrc); file.open(File::writeText); string suffix = toLower( file.getSuffix() ); bool bPPM=false; bool bICL = suffix == ".icl" || suffix == ".icl.gz"; int iNumImages = poSrc->getChannels (); if(suffix == ".ppm" || suffix == ".ppm.gz") { bPPM = true; if( (poSrc->getChannels() % 3) && poSrc->getChannels() > 2 ){ throw ICLException ("Image cannot be written as \".ppm\" channel count must be 1, 2 or a multiple of 3!"); } }else if (suffix == ".pnm" || suffix == ".pnm.gz") { bPPM = (poSrc->getChannels () == 3 && getChannelsOfFormat(poSrc->getFormat()) == 3); } if(bPPM){ if(poSrc->getChannels() % 3){ iNumImages = 1; }else{ iNumImages /= 3; } } bool bPGM = !bICL && !bPPM; /////////////////////////////////////////////////////////////////////////////////////////////////// //// WRITE HEADER INFORMATION //////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////// string endl = "\n"; if(!bICL){ file << string(bPPM ? "P6" :"P5") << endl; } file << "# Format " << translateFormat(poSrc->getFormat()) << endl; file << "# TimeStamp " << ioutils::time2str( poSrc->getTime().toMicroSeconds() ) << endl; file << "# NumFeatures " << iNumImages << endl; file << "# ImageDepth " << translateDepth(poSrc->getDepth()) << endl; file << "# ROI " << poSrc->getROI().x << " " << poSrc->getROI().y << " " << poSrc->getROI().width << " " << poSrc->getROI().height << endl; file << poSrc->getWidth() << " " << poSrc->getHeight()*(bICL ? 1 : iNumImages) << endl << 255 << endl; /////////////////////////////////////////////////////////////////////////////////////////////////// //// WRITE IMAGE DATA //////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////// if (bPPM) { // file format is interleaved, i.e. RGB or something similar if(!(poSrc->getChannels() % 3)){ for(int i=0;igetChannels() == 1){ pnm_write_gray2rgb(file, poSrc,m_vecBuffer); }else if(poSrc->getChannels() == 2){ pnm_write_2channels2rgb(file, poSrc,m_vecBuffer); }else{ throw ICLException ("Error writing file as .ppm! (This case may not occur)!"); } m_oBufferMutex.unlock(); } }else if(bPGM){ m_oBufferMutex.lock(); for (int i=0;igetDataPtr(i),poSrc->getDim () * getSizeOf(poSrc->getDepth())); } } } } /* void FileWriterPluginPNM::write(File &file, const ImgBase *poSrc){ ICLASSERT_RETURN(poSrc); file.open(File::writeText); ICLASSERT_RETURN(file.isOpen()); string suffix = toLower( file.getSuffix() ); bool bPPM=false; bool bICL = suffix == ".icl" || suffix == ".icl.gz"; int iNumImages = poSrc->getChannels (); if(suffix == ".ppm" || suffix == ".ppm.gz") { bPPM = !(poSrc->getChannels() % 3); if (!bPPM) throw ICLException ("Image cannot be written as \".ppm\" channel count must be a multiple of 3!"); }else if (suffix == ".pnm" || suffix == ".pnm.gz") { bPPM = (poSrc->getChannels () == 3 && getChannelsOfFormat(poSrc->getFormat()) == 3); } if(bPPM){ iNumImages/=3; } bool bPGM = !bICL && !bPPM; /////////////////////////////////////////////////////////////////////////////////////////////////// //// WRITE HEADER INFORMATION //////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////// string endl = "\n"; if(!bICL){ file << string(bPPM ? "P6" :"P5") << endl; } file << "# Format " << translateFormat(poSrc->getFormat()) << endl; file << "# TimeStamp " << ioutils::time2str( poSrc->getTime().toMicroSeconds() ) << endl; file << "# NumFeatures " << iNumImages << endl; file << "# ImageDepth " << translateDepth(poSrc->getDepth()) << endl; file << "# ROI " << poSrc->getROI().x << " " << poSrc->getROI().y << " " << poSrc->getROI().width << " " << poSrc->getROI().height << endl; file << poSrc->getWidth() << " " << poSrc->getHeight()*(bICL ? 1 : iNumImages) << endl << 255 << endl; /////////////////////////////////////////////////////////////////////////////////////////////////// //// WRITE IMAGE DATA //////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////// if (bPPM) { // file format is interleaved, i.e. RGB or something similar ICLASSERT_RETURN(poSrc->getChannels() > 2); for(int i=0;igetDataPtr(i),poSrc->getDim () * getSizeOf(poSrc->getDepth())); } } } */