///////////////////////////////////////////////////////////////////////////// // Copyright: (C) 2008-19 Cesar Mauri Loba - CREA Software Systems // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program 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 General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see . ///////////////////////////////////////////////////////////////////////////// #include "crvimage.h" #include #include #include // Construction CIplImage::CIplImage () { Init(); } CIplImage::CIplImage (IplImage *pImg) { Init(); Import (pImg); } CIplImage::CIplImage (int width, int height, int depth, const char *pColorOrder) { Init(); bool retval= Create (width, height, depth, pColorOrder); #ifndef NDEBUG assert (retval); #else (void) (retval); #endif } CIplImage::~CIplImage () { Free (); } void CIplImage::Init() { m_pIplImage= NULL; m_importedImage= false; m_importedROI= NULL; m_roiStackPtr= 0; } void CIplImage::InitROIStack (int width, int height) { m_roiStack[0].coi= 0; m_roiStack[0].xOffset= 0; m_roiStack[0].yOffset= 0; m_roiStack[0].width= width; m_roiStack[0].height= height; m_roiStackPtr= 0; } // Creation bool CIplImage::Create (int width, int height, unsigned int depth, const char *pColorOrder, int origin, int align) { int nChannels= 0; const char *pColorModel= NULL; bool alphaChannel= false; assert (width> 0 && width< 4000); assert (height> 0 && height< 4000); assert (pColorOrder); assert (depth== IPL_DEPTH_1U || depth== IPL_DEPTH_8U || depth== IPL_DEPTH_8S || depth== IPL_DEPTH_16U || depth== IPL_DEPTH_16S || depth== IPL_DEPTH_32S || depth== IPL_DEPTH_32F); Free (); InitROIStack (width, height); if ( !strcmp (pColorOrder, "GRAY") || !strcmp (pColorOrder, "G") ) { nChannels= 1; pColorModel= "GRAY"; } else if ( !strcmp (pColorOrder, "BGR") || !strcmp (pColorOrder, "RGB") ) { nChannels= 3; pColorModel= "RGB"; } else if ( !strcmp (pColorOrder, "RGBA") || !strcmp (pColorOrder, "BGRA") ) { nChannels= 4; pColorModel= "RGB"; alphaChannel= true; } else if ( !strcmp (pColorOrder, "YUV") ) { nChannels= 3; pColorModel= "YUV"; } else assert (0); m_pIplImage= cvCreateImageHeader( cvSize(width,height), depth, nChannels ); if (!m_pIplImage) { assert (0); return false; } m_pIplImage->alphaChannel= (alphaChannel? 1 : 0); strncpy (m_pIplImage->colorModel, pColorModel, 4); strncpy (m_pIplImage->channelSeq, pColorOrder, 4); m_pIplImage->dataOrder= IPL_DATA_ORDER_PIXEL; m_pIplImage->origin= origin; m_pIplImage->align= align; //m_pIplImage->widthStep= m_pIplImage->roi= &m_roiStack[0]; //assert (m_pIplImage->roi== &m_roiStack[0]); assert (m_pIplImage->imageData== NULL); cvCreateData( m_pIplImage ); if (CV_StsOk != cvGetErrStatus()) { assert (0); m_pIplImage->roi= NULL; cvReleaseImageHeader( &m_pIplImage ); m_pIplImage= NULL; return false; } return true; } bool CIplImage::Import (IplImage *pImage) { assert (pImage); // Cannot import the same image assert (pImage!= this->m_pIplImage); if (pImage== this->m_pIplImage) return false; Free (); m_pIplImage= pImage; m_importedImage= true; InitROIStack (pImage->width, pImage->height); m_importedROI= pImage->roi; if (pImage->roi) m_roiStack[m_roiStackPtr]= *pImage->roi; pImage->roi= &m_roiStack[m_roiStackPtr]; return true; } void CIplImage::Free () { bool wasImported= m_importedImage; IplImage* retval= this->Detach(); if (retval && !wasImported) cvReleaseImage( &retval ); } IplImage* CIplImage::Detach() { if (!m_pIplImage) return NULL; if (m_importedImage) m_pIplImage->roi= m_importedROI; else m_pIplImage->roi= NULL; IplImage* retval= m_pIplImage; Init (); return retval; } void CIplImage::Swap (CIplImage *pOtherImg) { int i; if (this== pOtherImg) return; // Nothing to do // Copy other image to tmp IplImage *tmp_pIplImage= pOtherImg->m_pIplImage; bool tmp_importedImage= pOtherImg->m_importedImage; IplROI *tmp_importedROI= pOtherImg->m_importedROI; IplROI tmp_roiStack[ROI_STACK_SIZE]; int tmp_roiStackPtr= pOtherImg->m_roiStackPtr; for (i= 0; i<= tmp_roiStackPtr; i++) { tmp_roiStack[i]= pOtherImg->m_roiStack[i]; } // 'Copy' current to other pOtherImg->m_pIplImage= m_pIplImage; pOtherImg->m_importedImage= m_importedImage; pOtherImg->m_importedROI= m_importedROI; pOtherImg->m_roiStackPtr= m_roiStackPtr; for (i= 0; i<= pOtherImg->m_roiStackPtr; i++) { pOtherImg->m_roiStack[i]= m_roiStack[i]; } if (pOtherImg->m_pIplImage) { pOtherImg->m_pIplImage->roi= &pOtherImg->m_roiStack[pOtherImg->m_roiStackPtr]; } // 'Copy' tmp to current m_pIplImage= tmp_pIplImage; m_importedImage= tmp_importedImage; m_importedROI= tmp_importedROI; m_roiStackPtr= tmp_roiStackPtr; for (i= 0; i<= m_roiStackPtr; i++) { m_roiStack[i]= tmp_roiStack[i]; } if (m_pIplImage) { m_pIplImage->roi= &m_roiStack[m_roiStackPtr]; } } void CIplImage::Reset () { assert (m_pIplImage); if (m_pIplImage== NULL) return; cvSetZero(m_pIplImage); } bool CIplImage::SetROI (int x, int y, int width, int height, unsigned int coi) { assert (m_pIplImage); assert (m_pIplImage->roi== &m_roiStack[m_roiStackPtr]); assert (x>= 0 && y>= 0 && width> 0 && height> 0); // Check limits for the ROI if (x< 0 || (x + width > m_pIplImage->width)) { assert (false); return false; } if (y< 0 || (y + height > m_pIplImage->height)) { assert (false); return false; } // ROI Ok m_roiStack[m_roiStackPtr].coi= coi; m_roiStack[m_roiStackPtr].xOffset= x; m_roiStack[m_roiStackPtr].yOffset= y; m_roiStack[m_roiStackPtr].width= width; m_roiStack[m_roiStackPtr].height= height; return true; } void CIplImage::GetROI (IplROI &roi) { assert (m_pIplImage); assert (m_pIplImage->roi== &m_roiStack[m_roiStackPtr]); roi= m_roiStack[m_roiStackPtr]; } void CIplImage::ResetROI () { assert (m_pIplImage); assert (m_pIplImage->roi== &m_roiStack[m_roiStackPtr]); m_pIplImage->roi->coi= 0; m_pIplImage->roi->xOffset= 0; m_pIplImage->roi->yOffset= 0; m_pIplImage->roi->width= m_pIplImage->width; m_pIplImage->roi->height= m_pIplImage->height; } void CIplImage::PushROI () { assert (m_pIplImage); assert (m_pIplImage->roi== &m_roiStack[m_roiStackPtr]); assert (m_roiStackPtr< ROI_STACK_SIZE - 1); m_roiStack[m_roiStackPtr + 1]= m_roiStack[m_roiStackPtr]; m_roiStackPtr++; m_pIplImage->roi= &m_roiStack[m_roiStackPtr]; } void CIplImage::PopROI () { assert (m_pIplImage); assert (m_roiStackPtr> 0); m_roiStackPtr--; m_pIplImage->roi= &m_roiStack[m_roiStackPtr]; }