#include "StenoseInterface.h" #include "StenoseBase.h" #include "StenoseNBBase.h" #include "scale.h" #include "../Container/extendedimage.h" #include "../IO/DicomIO.h" #include "../Mouchard/Mouchard.h" #include const CScale *g_pCurrentScale; #define SQR( x ) ( ( x ) * ( x ) ) StenoseInterface::StenoseInterface() : Singleton< StenoseInterface >() { } bool StenoseInterface::initialize( std::string fileName, double pixelSizeX, double pixelSizeY ) { bool status = false; if ( Mouchard::getInstance().IsDLLValid() ) { m_image.Destroy(); double m_pixelSizeX = pixelSizeX; double m_pixelSizeY = pixelSizeY; if (0)// DicomIO::getInstance().read( fileName, m_image ) ) { if ( ( pixelSizeX < 0.0 ) && ( pixelSizeY < 0.0 ) ) { m_pixelSizeX = m_image.GetResolutionX(); m_pixelSizeY = m_image.GetResolutionY(); } status = true; } else { status = false; } if ( status && ( m_pixelSizeX > 0.0 ) && ( m_pixelSizeY > 0.0 ) ) { double pixelSize = m_pixelSizeX < m_pixelSizeY ? m_pixelSizeX : m_pixelSizeY; g_pCurrentScale = new CScale("DLL scale", pixelSize, pixelSize); } } return status; } bool StenoseInterface::initialize( const char* buffer, int width, int height, int bpp, bool upsideDown, double pixelSizeX, double pixelSizeY ) { if ( Mouchard::getInstance().IsDLLValid() && buffer && ( pixelSizeX > 0.0 ) && ( pixelSizeY > 0.0 ) && ( ( bpp == 8 ) || ( bpp == 24 ) || ( bpp == 32 ) ) ) { bool padding = false; const unsigned long destWidth = 3 * width; const long nextRow = upsideDown ? -2 * width * bpp / 8 : 0; register const char* p = buffer + ( upsideDown ? ( height - 1 ) * width * bpp / 8 : 0 ); const int gap = padding ? ( 4 - destWidth & 0x3 ) & 0x3 : 0; //const unsigned long count = ( destWidth + gap ) * height; m_image.Destroy(); if ( m_image.Create( width, height, 24 ) ) { if ( bpp == 8 ) { register char* q = (char*)m_image.GetBits(); register int x; register int y; register char value; for ( y = height; y--; p += nextRow, q += gap ) { x = width; while ( x-- ) { value = *p++; *q++ = value; *q++ = value; *q++ = value; } } } else if ( bpp == 24 ) { register char* q = (char*)m_image.GetBits(); register int x; register int y; for ( y = height; y--; p += nextRow, q += gap ) { x = destWidth; while ( x-- ) { *q++ = *p++; } } } else if ( bpp == 32 ) { register char* q = (char*)m_image.GetBits(); register int x; register int y; for ( y = height; y--; p += nextRow, q += gap ) { x = width; while ( x-- ) { // Pour version Flex / Alchemy /* *q++ = *( p + 1 ); *q++ = *( p + 2 ); *q++ = *( p + 3 ); p += 4; */ *q++ = *( p + 0 ); *q++ = *( p + 1 ); *q++ = *( p + 2 ); p += 4; } } } double pixelSize = ( pixelSizeX < pixelSizeY ) ? pixelSizeX : pixelSizeY; g_pCurrentScale = new CScale("DLL scale", pixelSize, pixelSize); return true; } } return false; } bool StenoseInterface::Threshold_2(int iMax, int left, int top, int right, int bottom, int ptx, int pty, CStenoseResult* result ) { int retour; int i; Rect rcEllipse; retour = 0; if ( !m_image.IsNull() && result ) { CStenoseNBBase cstenose; rcEllipse.left = left; rcEllipse.top = top; // Le top doit être inférieur au bottom rcEllipse.right = right; rcEllipse.bottom = bottom; retour = cstenose.Threshold_2(&m_image, iMax, rcEllipse, ptx, pty); // Remplissage des valeurs dans result result->resultNB->code_retour = retour; result->resultNB->code_debug1 = cstenose.m_debug1; result->resultNB->code_debug2 = cstenose.m_debug2; result->resultNB->code_debug3 = cstenose.m_debug3; result->resultNB->code_debug4 = cstenose.m_debug4; result->resultNB->code_debug5 = cstenose.m_debug5; result->resultNB->m_dblSurface = cstenose.Surface(); result->resultNB->m_dblVesselArea = cstenose.m_dblVesselArea; result->resultNB->m_dblRatio = cstenose.Ratio(); result->resultNB->m_dblDensity = cstenose.Density(); result->resultNB->m_dwMean = cstenose.m_dwMean; if ( result->resultNB->m_dwPoints ) { delete[] result->resultNB->m_pPoints; } result->resultNB->m_pPoints = new stenose::Point[ cstenose.m_dwPoints ]; result->resultNB->m_dwPoints = cstenose.m_dwPoints; for ( i = 0; i < cstenose.m_dwPoints; i++ ) { result->resultNB->m_pPoints[ i ].x = cstenose.m_pPoints[ i ].x; result->resultNB->m_pPoints[ i ].y = cstenose.m_pPoints[ i ].y; } return 1; } else { result->resultNB->code_retour = -1; } return 0; } bool StenoseInterface::Measure( int left, int top, int right, int bottom, CStenoseResult* result ) { bool retour; int i; Rect rcEllipse; retour = false; if ( !m_image.IsNull() && result ) { CStenoseBase cstenose; rcEllipse.left = left; rcEllipse.top = top; // Le top doit être inférieur au bottom rcEllipse.right = right; rcEllipse.bottom = bottom; retour = cstenose.Measure(&m_image, rcEllipse); // Remplissage des valeurs dans result result->result->code_retour = retour; result->result->code_debug1 = cstenose.m_debug1; result->result->code_debug2 = cstenose.m_debug2; result->result->code_debug3 = cstenose.m_debug3; result->result->code_debug4 = cstenose.m_debug4; result->result->code_debug5 = cstenose.m_debug5; result->result->m_dblEllipse = cstenose.SurfaceEllipse(); result->result->m_dblStenose = cstenose.SurfaceStenose(); result->result->m_dblRatio = cstenose.Ratio(); if ( result->result->m_dwPoints ) { delete[] result->result->m_pPoints; } result->result->m_pPoints = new stenose::Point[ cstenose.m_dwPoints ]; result->result->m_dwPoints = cstenose.m_dwPoints; for ( i = 0; i < cstenose.m_dwPoints; i++ ) { result->result->m_pPoints[ i ].x = cstenose.m_pPoints[ i ].x; result->result->m_pPoints[ i ].y = cstenose.m_pPoints[ i ].y; } return retour; } else { result->result->code_retour = -1; } return retour; } int StenoseInterface::getImageWidth() { return m_image.GetWidth(); } int StenoseInterface::getImageHeight() { return m_image.GetHeight(); } int StenoseInterface::getImageBitsPerPixel() { return m_image.GetBPP(); } char* StenoseInterface::getPixelArray() { return (char*)m_image.GetBits(); }