<commit_before>#include "pch.h"
#include "axl_io_Serial.h"
#include "axl_sys_Event.h"

namespace axl {
namespace io {

//.............................................................................

#if (_AXL_ENV == AXL_ENV_WIN)

bool
Serial::setSettings (
	const SerialSettings* settings,
	uint_t mask
	)
{
	DCB dcb;
	dcb.DCBlength = sizeof (dcb);

	bool result = m_serial.getSettings (&dcb);
	if (!result)
		return false;

	dcb.fBinary = TRUE;
	dcb.fDsrSensitivity = FALSE;
	dcb.fDtrControl = DTR_CONTROL_DISABLE;

	if (mask & SerialSettingId_BaudRate)
		dcb.BaudRate = settings->m_baudRate;

	if (mask & SerialSettingId_DataBits)
		dcb.ByteSize = settings->m_dataBits;

	if (mask & SerialSettingId_StopBits)
		dcb.StopBits = settings->m_stopBits;

	if (mask & SerialSettingId_Parity)
		dcb.fParity = settings->m_parity;

	if (mask & SerialSettingId_FlowControl)
		switch (settings->m_flowControl)
		{
		case SerialFlowControl_None:
			dcb.fOutxCtsFlow = FALSE;
			dcb.fRtsControl = RTS_CONTROL_DISABLE;
			break;

		case SerialFlowControl_RtsCts:
			dcb.fOutxCtsFlow = TRUE;
			dcb.fRtsControl = RTS_CONTROL_HANDSHAKE;
			break;

		case SerialFlowControl_XonXoff:
			dcb.fOutX = TRUE;
			dcb.fInX = TRUE;
			break;
		}

	if (!(mask & SerialSettingId_ReadInterval))
		return m_serial.setSettings (&dcb);

	COMMTIMEOUTS timeouts = { 0 };
	timeouts.ReadIntervalTimeout =
		settings->m_readInterval == 0 ? -1 :
		settings->m_readInterval == -1 ? 0 :
		settings->m_readInterval;

	return
		m_serial.setSettings (&dcb) &&
		m_serial.setTimeouts (&timeouts);
}

bool
Serial::getSettings (SerialSettings* settings)
{
	DCB dcb;
	dcb.DCBlength = sizeof (dcb);

	bool result = m_serial.getSettings (&dcb);
	if (!result)
		return false;

	settings->m_baudRate = dcb.BaudRate;
	settings->m_dataBits = dcb.ByteSize;
	settings->m_stopBits = (SerialStopBits) dcb.StopBits;
	settings->m_parity   = (SerialParity) dcb.Parity;

	settings->m_flowControl =
		dcb.fOutxCtsFlow && dcb.fRtsControl == RTS_CONTROL_HANDSHAKE ? SerialFlowControl_RtsCts :
		dcb.fOutX && dcb.fInX ? SerialFlowControl_XonXoff : SerialFlowControl_None;

	return true;
}

uint_t
Serial::getStatusLines ()
{
	uint_t lines = m_serial.getStatusLines ();
	return lines != -1 ? (lines & 0xf0) >> 4 : -1;
}

size_t
Serial::read (
	void* p,
	size_t size
	)
{
	sys::Event completionEvent;

	OVERLAPPED overlapped = { 0 };
	overlapped.hEvent = completionEvent.m_event;

	bool_t result = m_serial.read (p, (dword_t) size, NULL, &overlapped);
	if (!result)
		return -1;

	dword_t actualSize;
	result = ::GetOverlappedResult (m_serial, &overlapped, &actualSize, true);
	if (!result)
	{
		err::setLastSystemError ();
		return -1;
	}

	return actualSize;
}

size_t
Serial::write (
	const void* p,
	size_t size
	)
{
	sys::Event completionEvent;

	OVERLAPPED overlapped = { 0 };
	overlapped.hEvent = completionEvent.m_event;

	bool_t result = m_serial.write (p, (dword_t) size, NULL, &overlapped);
	if (!result)
		return -1;

	dword_t actualSize;
	result = ::GetOverlappedResult (m_serial, &overlapped, &actualSize, true);
	if (!result)
	{
		err::setLastSystemError ();
		return -1;
	}

	return actualSize;
}

#elif (_AXL_ENV == AXL_ENV_POSIX)

bool
Serial::setSettings (
	const SerialSettings* settings,
	uint_t mask
	)
{
	termios attr;
	bool result = m_serial.getAttr (&attr);
	if (!result)
		return false;

	if (mask & SerialSettingId_BaudRate)
	{
		speed_t speed;

		switch (settings->m_baudRate)
		{
		case 110:
			speed = B110;
			break;

		case 300:
			speed = B300;
			break;

		case 600:
			speed = B600;
			break;

		case 1200:
			speed = B1200;
			break;

		case 2400:
			speed = B2400;
			break;

		case 4800:
			speed = B4800;
			break;

		case 9600:
			speed = B9600;
			break;

		case 19200:
			speed = B19200;
			break;

		case 38400:
			speed = B38400;
			break;

		case 57600:
			speed = B57600;
			break;

		case 115200:
			speed = B115200;
			break;

		default:
			// TODO: custom baud rate (currently fall back to 38400)
			speed = B38400;
		}

		cfsetispeed (&attr, speed);
		cfsetospeed (&attr, speed);
	}

	if (mask & SerialSettingId_DataBits)
	{
		attr.c_cflag &= ~CSIZE;

		switch (settings->m_dataBits)
		{
		case 5:
			attr.c_cflag |= CS5;
			break;

		case 6:
			attr.c_cflag |= CS6;
			break;

		case 7:
			attr.c_cflag |= CS7;
			break;

		case 8:
		default:
			attr.c_cflag |= CS8;
			break;
		}
	}

	if (mask & SerialSettingId_StopBits)
	{
		if (settings->m_stopBits == SerialStopBits_2)
			attr.c_cflag |= CSTOPB;
		else
			attr.c_cflag &= ~CSTOPB;
	}

	if (mask & SerialSettingId_Parity)
	{
		attr.c_iflag &= ~(PARMRK | INPCK);
		attr.c_iflag |= IGNPAR;

		switch (settings->m_parity)
		{
		case SerialParity_None:
			attr.c_cflag &= ~PARENB;
			break;

		case SerialParity_Odd:
			attr.c_cflag |= PARENB | PARODD;
			break;

		case SerialParity_Even:
			attr.c_cflag &= ~PARODD;
			attr.c_cflag |= PARENB;
			break;

#ifdef CMSPAR
		case SerialParity_Mark:
			attr.c_cflag |= PARENB | CMSPAR | PARODD;
			break;

		case SerialParity_Space:
			attr.c_cflag &= ~PARODD;
			attr.c_cflag |= PARENB | CMSPAR;
			break;
#endif

		default:
			attr.c_cflag |= PARENB;
			attr.c_iflag |= PARMRK | INPCK;
			attr.c_iflag &= ~IGNPAR;
		}
	}

	if (mask & SerialSettingId_FlowControl)
		switch (settings->m_flowControl)
		{
		case SerialFlowControl_RtsCts:
			attr.c_cflag |= CRTSCTS;
			attr.c_iflag &= ~(IXON | IXOFF | IXANY);
			break;

		case SerialFlowControl_XonXoff:
			attr.c_cflag &= ~CRTSCTS;
			attr.c_iflag |= IXON | IXOFF | IXANY;
			break;

		case SerialFlowControl_None:
		default:
			attr.c_cflag &= ~CRTSCTS;
			attr.c_iflag &= ~(IXON | IXOFF | IXANY);
		}

	// ensure some extra default flags

	attr.c_cflag |= CREAD | CLOCAL;
	attr.c_lflag = 0;
	attr.c_oflag = 0;
	attr.c_cc [VTIME] = 0;
	attr.c_cc [VMIN]  = 1;

	return m_serial.setAttr (&attr);
}

bool
Serial::getSettings (SerialSettings* settings)
{
	termios attr;
	bool result = m_serial.getAttr (&attr);
	if (!result)
		return false;

	speed_t speed = cfgetispeed (&attr);
	switch (speed)
	{
	case B110:
		settings->m_baudRate = 110;
		break;

	case B300:
		settings->m_baudRate = 300;
		break;

	case B600:
		settings->m_baudRate = 600;
		break;

	case B1200:
		settings->m_baudRate = 1200;
		break;

	case B2400:
		settings->m_baudRate = 2400;
		break;

	case B4800:
		settings->m_baudRate = 4800;
		break;

	case B9600:
		settings->m_baudRate = 9600;
		break;

	case B19200:
		settings->m_baudRate = 19200;
		break;

	case B38400:
		settings->m_baudRate = 38400;
		break;

	case B57600:
		settings->m_baudRate = 57600;
		break;

	case B115200:
		settings->m_baudRate = 115200;
		break;

	default:
		// TODO: custom baud rate (currently fall back to 38400)
		settings->m_baudRate = 38400;
	}

	uint_t byteSize = attr.c_cflag & CSIZE;
	switch (byteSize)
	{
	case CS5:
		settings->m_dataBits = 5;
		break;

	case CS6:
		settings->m_dataBits = 6;
		break;

	case CS7:
		settings->m_dataBits = 7;
		break;

	case CS8:
	default:
		settings->m_dataBits = 8;
		break;
	}

	settings->m_stopBits = (attr.c_cflag & CSTOPB) ?
		SerialStopBits_2 :
		SerialStopBits_1;

#ifdef CMSPAR
	settings->m_parity =
		(attr.c_cflag & PARENB) ?
			(attr.c_cflag & CMSPAR)  ?
				(attr.c_cflag & PARODD) ? SerialParity_Mark : SerialParity_Space :
				(attr.c_cflag & PARODD) ? SerialParity_Odd : SerialParity_Even :
		SerialParity_None;
#else
	settings->m_parity = (attr.c_cflag & PARENB) ? (attr.c_cflag & PARODD) ?
		SerialParity_Odd :
		SerialParity_Even :
		SerialParity_None;
#endif

	settings->m_flowControl =
		(attr.c_cflag & CRTSCTS) ? SerialFlowControl_RtsCts :
		(attr.c_iflag & (IXON | IXOFF)) ? SerialFlowControl_XonXoff : SerialFlowControl_None;

	return true;
}

uint_t
Serial::getStatusLines ()
{
	uint_t result = m_serial.getStatusLines ();
	if (result == -1)
		return -1;

	uint_t lines = 0;
	if (result & TIOCM_CTS)
		lines |= SerialStatusLine_Cts;

	if (result & TIOCM_DSR)
		lines |= SerialStatusLine_Dsr;

	if (result & TIOCM_RNG)
		lines |= SerialStatusLine_Ring;

	if (result & TIOCM_CAR)
		lines |= SerialStatusLine_Dcd;

	return lines;
}

#endif

//.............................................................................

} // namespace io
} // namespace axl
<commit_msg>[axl] critical bugfix: io::Serial did not handle parity setting properly<commit_after>#include "pch.h"
#include "axl_io_Serial.h"
#include "axl_sys_Event.h"

namespace axl {
namespace io {

//.............................................................................

#if (_AXL_ENV == AXL_ENV_WIN)

bool
Serial::setSettings (
	const SerialSettings* settings,
	uint_t mask
	)
{
	DCB dcb;
	dcb.DCBlength = sizeof (dcb);

	bool result = m_serial.getSettings (&dcb);
	if (!result)
		return false;

	dcb.fBinary = TRUE;
	dcb.fDsrSensitivity = FALSE;
	dcb.fDtrControl = DTR_CONTROL_DISABLE;

	if (mask & SerialSettingId_BaudRate)
		dcb.BaudRate = settings->m_baudRate;

	if (mask & SerialSettingId_DataBits)
		dcb.ByteSize = settings->m_dataBits;

	if (mask & SerialSettingId_StopBits)
		dcb.StopBits = settings->m_stopBits;

	if (mask & SerialSettingId_Parity)
	{
		dcb.fParity = settings->m_parity != SerialParity_None;
		dcb.Parity = settings->m_parity;
	}

	if (mask & SerialSettingId_FlowControl)
		switch (settings->m_flowControl)
		{
		case SerialFlowControl_None:
			dcb.fOutxCtsFlow = FALSE;
			dcb.fRtsControl = RTS_CONTROL_DISABLE;
			break;

		case SerialFlowControl_RtsCts:
			dcb.fOutxCtsFlow = TRUE;
			dcb.fRtsControl = RTS_CONTROL_HANDSHAKE;
			break;

		case SerialFlowControl_XonXoff:
			dcb.fOutX = TRUE;
			dcb.fInX = TRUE;
			break;
		}

	if (!(mask & SerialSettingId_ReadInterval))
		return m_serial.setSettings (&dcb);

	COMMTIMEOUTS timeouts = { 0 };
	timeouts.ReadIntervalTimeout =
		settings->m_readInterval == 0 ? -1 :
		settings->m_readInterval == -1 ? 0 :
		settings->m_readInterval;

	return
		m_serial.setSettings (&dcb) &&
		m_serial.setTimeouts (&timeouts);
}

bool
Serial::getSettings (SerialSettings* settings)
{
	DCB dcb;
	dcb.DCBlength = sizeof (dcb);

	bool result = m_serial.getSettings (&dcb);
	if (!result)
		return false;

	settings->m_baudRate = dcb.BaudRate;
	settings->m_dataBits = dcb.ByteSize;
	settings->m_stopBits = (SerialStopBits) dcb.StopBits;
	settings->m_parity   = (SerialParity) dcb.Parity;

	settings->m_flowControl =
		dcb.fOutxCtsFlow && dcb.fRtsControl == RTS_CONTROL_HANDSHAKE ? SerialFlowControl_RtsCts :
		dcb.fOutX && dcb.fInX ? SerialFlowControl_XonXoff : SerialFlowControl_None;

	return true;
}

uint_t
Serial::getStatusLines ()
{
	uint_t lines = m_serial.getStatusLines ();
	return lines != -1 ? (lines & 0xf0) >> 4 : -1;
}

size_t
Serial::read (
	void* p,
	size_t size
	)
{
	sys::Event completionEvent;

	OVERLAPPED overlapped = { 0 };
	overlapped.hEvent = completionEvent.m_event;

	bool_t result = m_serial.read (p, (dword_t) size, NULL, &overlapped);
	if (!result)
		return -1;

	dword_t actualSize;
	result = ::GetOverlappedResult (m_serial, &overlapped, &actualSize, true);
	if (!result)
	{
		err::setLastSystemError ();
		return -1;
	}

	return actualSize;
}

size_t
Serial::write (
	const void* p,
	size_t size
	)
{
	sys::Event completionEvent;

	OVERLAPPED overlapped = { 0 };
	overlapped.hEvent = completionEvent.m_event;

	bool_t result = m_serial.write (p, (dword_t) size, NULL, &overlapped);
	if (!result)
		return -1;

	dword_t actualSize;
	result = ::GetOverlappedResult (m_serial, &overlapped, &actualSize, true);
	if (!result)
	{
		err::setLastSystemError ();
		return -1;
	}

	return actualSize;
}

#elif (_AXL_ENV == AXL_ENV_POSIX)

bool
Serial::setSettings (
	const SerialSettings* settings,
	uint_t mask
	)
{
	termios attr;
	bool result = m_serial.getAttr (&attr);
	if (!result)
		return false;

	if (mask & SerialSettingId_BaudRate)
	{
		speed_t speed;

		switch (settings->m_baudRate)
		{
		case 110:
			speed = B110;
			break;

		case 300:
			speed = B300;
			break;

		case 600:
			speed = B600;
			break;

		case 1200:
			speed = B1200;
			break;

		case 2400:
			speed = B2400;
			break;

		case 4800:
			speed = B4800;
			break;

		case 9600:
			speed = B9600;
			break;

		case 19200:
			speed = B19200;
			break;

		case 38400:
			speed = B38400;
			break;

		case 57600:
			speed = B57600;
			break;

		case 115200:
			speed = B115200;
			break;

		default:
			// TODO: custom baud rate (currently fall back to 38400)
			speed = B38400;
		}

		cfsetispeed (&attr, speed);
		cfsetospeed (&attr, speed);
	}

	if (mask & SerialSettingId_DataBits)
	{
		attr.c_cflag &= ~CSIZE;

		switch (settings->m_dataBits)
		{
		case 5:
			attr.c_cflag |= CS5;
			break;

		case 6:
			attr.c_cflag |= CS6;
			break;

		case 7:
			attr.c_cflag |= CS7;
			break;

		case 8:
		default:
			attr.c_cflag |= CS8;
			break;
		}
	}

	if (mask & SerialSettingId_StopBits)
	{
		if (settings->m_stopBits == SerialStopBits_2)
			attr.c_cflag |= CSTOPB;
		else
			attr.c_cflag &= ~CSTOPB;
	}

	if (mask & SerialSettingId_Parity)
	{
		attr.c_iflag &= ~(PARMRK | INPCK);
		attr.c_iflag |= IGNPAR;

		switch (settings->m_parity)
		{
		case SerialParity_None:
			attr.c_cflag &= ~PARENB;
			break;

		case SerialParity_Odd:
			attr.c_cflag |= PARENB | PARODD;
			break;

		case SerialParity_Even:
			attr.c_cflag &= ~PARODD;
			attr.c_cflag |= PARENB;
			break;

#ifdef CMSPAR
		case SerialParity_Mark:
			attr.c_cflag |= PARENB | CMSPAR | PARODD;
			break;

		case SerialParity_Space:
			attr.c_cflag &= ~PARODD;
			attr.c_cflag |= PARENB | CMSPAR;
			break;
#endif

		default:
			attr.c_cflag |= PARENB;
			attr.c_iflag |= PARMRK | INPCK;
			attr.c_iflag &= ~IGNPAR;
		}
	}

	if (mask & SerialSettingId_FlowControl)
		switch (settings->m_flowControl)
		{
		case SerialFlowControl_RtsCts:
			attr.c_cflag |= CRTSCTS;
			attr.c_iflag &= ~(IXON | IXOFF | IXANY);
			break;

		case SerialFlowControl_XonXoff:
			attr.c_cflag &= ~CRTSCTS;
			attr.c_iflag |= IXON | IXOFF | IXANY;
			break;

		case SerialFlowControl_None:
		default:
			attr.c_cflag &= ~CRTSCTS;
			attr.c_iflag &= ~(IXON | IXOFF | IXANY);
		}

	// ensure some extra default flags

	attr.c_cflag |= CREAD | CLOCAL;
	attr.c_lflag = 0;
	attr.c_oflag = 0;
	attr.c_cc [VTIME] = 0;
	attr.c_cc [VMIN]  = 1;

	return m_serial.setAttr (&attr);
}

bool
Serial::getSettings (SerialSettings* settings)
{
	termios attr;
	bool result = m_serial.getAttr (&attr);
	if (!result)
		return false;

	speed_t speed = cfgetispeed (&attr);
	switch (speed)
	{
	case B110:
		settings->m_baudRate = 110;
		break;

	case B300:
		settings->m_baudRate = 300;
		break;

	case B600:
		settings->m_baudRate = 600;
		break;

	case B1200:
		settings->m_baudRate = 1200;
		break;

	case B2400:
		settings->m_baudRate = 2400;
		break;

	case B4800:
		settings->m_baudRate = 4800;
		break;

	case B9600:
		settings->m_baudRate = 9600;
		break;

	case B19200:
		settings->m_baudRate = 19200;
		break;

	case B38400:
		settings->m_baudRate = 38400;
		break;

	case B57600:
		settings->m_baudRate = 57600;
		break;

	case B115200:
		settings->m_baudRate = 115200;
		break;

	default:
		// TODO: custom baud rate (currently fall back to 38400)
		settings->m_baudRate = 38400;
	}

	uint_t byteSize = attr.c_cflag & CSIZE;
	switch (byteSize)
	{
	case CS5:
		settings->m_dataBits = 5;
		break;

	case CS6:
		settings->m_dataBits = 6;
		break;

	case CS7:
		settings->m_dataBits = 7;
		break;

	case CS8:
	default:
		settings->m_dataBits = 8;
		break;
	}

	settings->m_stopBits = (attr.c_cflag & CSTOPB) ?
		SerialStopBits_2 :
		SerialStopBits_1;

#ifdef CMSPAR
	settings->m_parity =
		(attr.c_cflag & PARENB) ?
			(attr.c_cflag & CMSPAR)  ?
				(attr.c_cflag & PARODD) ? SerialParity_Mark : SerialParity_Space :
				(attr.c_cflag & PARODD) ? SerialParity_Odd : SerialParity_Even :
		SerialParity_None;
#else
	settings->m_parity = (attr.c_cflag & PARENB) ? (attr.c_cflag & PARODD) ?
		SerialParity_Odd :
		SerialParity_Even :
		SerialParity_None;
#endif

	settings->m_flowControl =
		(attr.c_cflag & CRTSCTS) ? SerialFlowControl_RtsCts :
		(attr.c_iflag & (IXON | IXOFF)) ? SerialFlowControl_XonXoff : SerialFlowControl_None;

	return true;
}

uint_t
Serial::getStatusLines ()
{
	uint_t result = m_serial.getStatusLines ();
	if (result == -1)
		return -1;

	uint_t lines = 0;
	if (result & TIOCM_CTS)
		lines |= SerialStatusLine_Cts;

	if (result & TIOCM_DSR)
		lines |= SerialStatusLine_Dsr;

	if (result & TIOCM_RNG)
		lines |= SerialStatusLine_Ring;

	if (result & TIOCM_CAR)
		lines |= SerialStatusLine_Dcd;

	return lines;
}

#endif

//.............................................................................

} // namespace io
} // namespace axl
<|endoftext|>


<commit_before>#include "EvmGdownIIR.h"
#include "Window.h"
#include "ext_opencv.h"

EvmGdownIIR::EvmGdownIIR() {
    first = true;
    blurLevel = 4;
    fLow = 50/60./10;
    fHigh = 60/60./10;
    alpha = 200;
    minFaceSizePercentage = 0.3;
    t = 0;
}

EvmGdownIIR::~EvmGdownIIR() {
}

void EvmGdownIIR::load(const string& filename) {
    classifier.load(filename);
}

void EvmGdownIIR::start(int width, int height) {
    srcSize = Size(width, height);
    minFaceSize = Size(width * minFaceSizePercentage, height * minFaceSizePercentage);
}

void EvmGdownIIR::onFrame(const Mat& src, Mat& out) {
    // count frames
    t++;

    // detect faces
    cvtColor(src, gray, CV_RGB2GRAY);
    classifier.detectMultiScale(src, faces, 1.1, 3, 0, minFaceSize);

    // convert to float
    src.convertTo(srcFloat, CV_32F);

    // apply spatial filter: blur and downsample
    srcFloat.copyTo(blurred);
    for (int i = 0; i < blurLevel; i++) {
        pyrDown(blurred, blurred);
    }

    if (first) {
        first = false;
        blurred.copyTo(lowpassHigh);
        blurred.copyTo(lowpassLow);
        src.copyTo(out);
    } else {
        // apply temporal filter: subtraction of two IIR lowpass filters
        lowpassHigh = lowpassHigh * (1-fHigh) + fHigh * blurred;
        lowpassLow = lowpassLow * (1-fLow) + fLow * blurred;

        blurred = lowpassHigh - lowpassLow;

        // amplify
        blurred *= alpha;

        // resize back to original size
        for (int i = 0; i < blurLevel; i++) {
            pyrUp(blurred, blurred);
        }
        resize(blurred, blurred, srcSize);

        // add back to original frame
        blurred += srcFloat;

        // convert to 8 bit
        blurred.convertTo(out, CV_8U);
    }

    // iterate through faces
    for (int i = 0; i < faces.size(); i++) {
        rectangle(out, faces.at(i), BLUE);
        stringstream ss;
        ss << i;
        putText(out, ss.str(), faces.at(i).tl() + Point(5, 15), FONT_HERSHEY_PLAIN, 1, BLUE);
    }
    // TODO support multiple faces
    face(out, faces.front());
}

void EvmGdownIIR::face(Mat& frame, const Rect& face) {
    // TODO extract static variables to class
    static Rect f = face;
    static Rect roi;
    static Mat1d timestamps;
    static Mat1d green;
    static Mat1d detrended;
    static Mat1d powerSpectrum;
    static Mat1d pulse;
    static string bpmStr;

    {
        interpolate(f, face, f, 0.05);
        Point p = f.tl() + Point(f.size().width * .5, f.size().height * 0.15);
        Point s(f.width * 0.05, f.height * 0.025);
        roi = Rect(p - s, p + s);
    }

    const int total = green.total();
    if (total >= 100) { // TODO extract constant to class?
        timestamps.rowRange(1, total).copyTo(timestamps.rowRange(0, total-1));
        green.rowRange(1, total).copyTo(green.rowRange(0, total-1));
        timestamps.pop_back();
        green.pop_back();
    }
    timestamps.push_back<double>(getTickCount());
    green.push_back<double>(mean(frame(roi))[1]);

    detrend(green, detrended);
    normalization(detrended, detrended);
    meanFilter(detrended, detrended);

    if (t % 30 == 0) { // TODO extract constant to class?
        const double diff = (timestamps(total-1) - timestamps(0)) * 1000. / getTickFrequency();
        const double fps = total * 1000 / diff;
        // TODO extract constants to class?
        const int low = total * 45./60./fps + 1;
        const int high = total * 240./60./fps + 1;

        dft(green, powerSpectrum);

        // band limit
        powerSpectrum.rowRange(0, low) = ZERO;
        powerSpectrum.pop_back(min(total - high, total));

        // power spectrum
        pow(powerSpectrum, 2, powerSpectrum);

        if (!powerSpectrum.empty()) {
            // grab index of max power spectrum
            int idx[2];
            minMaxIdx(powerSpectrum, 0, 0, 0, &idx[0]);

            // calculate BPM
            const double bpm = idx[0] * fps * 60. / total;
            pulse.push_back(bpm);

            stringstream ss;
            ss.precision(3);
            ss << "BPM:  " << bpm;
            bpmStr = ss.str();
        }
    }

    // draw some stuff
    rectangle(frame, f, BLUE, 2);
    rectangle(frame, roi, RED);

    Point bl = f.tl() + Point(0, f.height);
    Point g;
    for (int i = 0; i < total; i++) {
        g = bl + Point(i, -green(i) + 50);
        line(frame, g, g, GREEN);
        g = bl + Point(i, -detrended(i) * 10 - 50);
        line(frame, g, g, RED);
    }

    putText(frame, bpmStr, bl, FONT_HERSHEY_PLAIN, 1, RED);
}
<commit_msg>Fix when no face is detected.<commit_after>#include "EvmGdownIIR.h"
#include "Window.h"
#include "ext_opencv.h"

EvmGdownIIR::EvmGdownIIR() {
    first = true;
    blurLevel = 4;
    fLow = 50/60./10;
    fHigh = 60/60./10;
    alpha = 200;
    minFaceSizePercentage = 0.3;
    t = 0;
}

EvmGdownIIR::~EvmGdownIIR() {
}

void EvmGdownIIR::load(const string& filename) {
    classifier.load(filename);
}

void EvmGdownIIR::start(int width, int height) {
    srcSize = Size(width, height);
    minFaceSize = Size(width * minFaceSizePercentage, height * minFaceSizePercentage);
}

void EvmGdownIIR::onFrame(const Mat& src, Mat& out) {
    // count frames
    t++;

    // detect faces
    cvtColor(src, gray, CV_RGB2GRAY);
    classifier.detectMultiScale(src, faces, 1.1, 3, 0, minFaceSize);

    // convert to float
    src.convertTo(srcFloat, CV_32F);

    // apply spatial filter: blur and downsample
    srcFloat.copyTo(blurred);
    for (int i = 0; i < blurLevel; i++) {
        pyrDown(blurred, blurred);
    }

    if (first) {
        first = false;
        blurred.copyTo(lowpassHigh);
        blurred.copyTo(lowpassLow);
        src.copyTo(out);
    } else {
        // apply temporal filter: subtraction of two IIR lowpass filters
        lowpassHigh = lowpassHigh * (1-fHigh) + fHigh * blurred;
        lowpassLow = lowpassLow * (1-fLow) + fLow * blurred;

        blurred = lowpassHigh - lowpassLow;

        // amplify
        blurred *= alpha;

        // resize back to original size
        for (int i = 0; i < blurLevel; i++) {
            pyrUp(blurred, blurred);
        }
        resize(blurred, blurred, srcSize);

        // add back to original frame
        blurred += srcFloat;

        // convert to 8 bit
        blurred.convertTo(out, CV_8U);
    }

    // iterate through faces
    for (int i = 0; i < faces.size(); i++) {
        rectangle(out, faces.at(i), BLUE);
        stringstream ss;
        ss << i;
        putText(out, ss.str(), faces.at(i).tl() + Point(5, 15), FONT_HERSHEY_PLAIN, 1, BLUE);
    }
    // TODO support multiple faces
    if (faces.empty()) {
        face(out, faces.front());
    }
}

void EvmGdownIIR::face(Mat& frame, const Rect& face) {
    // TODO extract static variables to class
    static Rect f = face;
    static Rect roi;
    static Mat1d timestamps;
    static Mat1d green;
    static Mat1d detrended;
    static Mat1d powerSpectrum;
    static Mat1d pulse;
    static string bpmStr;

    {
        interpolate(f, face, f, 0.05);
        Point p = f.tl() + Point(f.size().width * .5, f.size().height * 0.15);
        Point s(f.width * 0.05, f.height * 0.025);
        roi = Rect(p - s, p + s);
    }

    const int total = green.total();
    if (total >= 100) { // TODO extract constant to class?
        timestamps.rowRange(1, total).copyTo(timestamps.rowRange(0, total-1));
        green.rowRange(1, total).copyTo(green.rowRange(0, total-1));
        timestamps.pop_back();
        green.pop_back();
    }
    timestamps.push_back<double>(getTickCount());
    green.push_back<double>(mean(frame(roi))[1]);

    detrend(green, detrended);
    normalization(detrended, detrended);
    meanFilter(detrended, detrended);

    if (t % 30 == 0) { // TODO extract constant to class?
        const double diff = (timestamps(total-1) - timestamps(0)) * 1000. / getTickFrequency();
        const double fps = total * 1000 / diff;
        // TODO extract constants to class?
        const int low = total * 45./60./fps + 1;
        const int high = total * 240./60./fps + 1;

        dft(green, powerSpectrum);

        // band limit
        powerSpectrum.rowRange(0, low) = ZERO;
        powerSpectrum.pop_back(min(total - high, total));

        // power spectrum
        pow(powerSpectrum, 2, powerSpectrum);

        if (!powerSpectrum.empty()) {
            // grab index of max power spectrum
            int idx[2];
            minMaxIdx(powerSpectrum, 0, 0, 0, &idx[0]);

            // calculate BPM
            const double bpm = idx[0] * fps * 60. / total;
            pulse.push_back(bpm);

            stringstream ss;
            ss.precision(3);
            ss << "BPM:  " << bpm;
            bpmStr = ss.str();
        }
    }

    // draw some stuff
    rectangle(frame, f, BLUE, 2);
    rectangle(frame, roi, RED);

    Point bl = f.tl() + Point(0, f.height);
    Point g;
    for (int i = 0; i < total; i++) {
        g = bl + Point(i, -green(i) + 50);
        line(frame, g, g, GREEN);
        g = bl + Point(i, -detrended(i) * 10 - 50);
        line(frame, g, g, RED);
    }

    putText(frame, bpmStr, bl, FONT_HERSHEY_PLAIN, 1, RED);
}
<|endoftext|>


<commit_before>#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MAIN count count_if tests

#include <boost/test/unit_test.hpp>

#include <algorithm>
#include <vector>

#include "operators.h"
#include "rectangle.h"

using rectangle = rectangle_t<int>;

BOOST_AUTO_TEST_SUITE( count_test_suite )

BOOST_AUTO_TEST_CASE( empty_container_count )
{
    std::vector<rectangle> rects;
    rectangle target;

    /*! True regardless of the coordinates of the 'target' rectangle, which
     * *actually contains garbage*. */
    BOOST_CHECK_EQUAL(std::count(std::begin(rects), std::end(rects), target), 0);
    BOOST_CHECK_EQUAL(std::count(std::begin(rects), std::end(rects), target), 0);
}

BOOST_AUTO_TEST_CASE( empty_container_count_if )
{
    std::vector<rectangle> rects;

    BOOST_CHECK_EQUAL(std::count_if(std::begin(rects), std::end(rects), true_no_op()), 0);
    BOOST_CHECK_EQUAL(std::count_if(std::begin(rects), std::end(rects), false_no_op()), 0);
    BOOST_CHECK_EQUAL(std::count_if(std::begin(rects), std::end(rects), alternating_no_op()), 0);
}

BOOST_AUTO_TEST_CASE( count_zero )
{
    const positive_area_rects_fixture f;

    BOOST_CHECK_EQUAL(std::count(std::begin(f.rects), std::end(f.rects), rectangle{1, 2, 3, 4}), 0);
    BOOST_CHECK_EQUAL(std::count(std::begin(f.rects), std::end(f.rects), rectangle{0, 0, 0, 0}), 0);
    BOOST_CHECK_EQUAL(std::count(std::begin(f.rects), std::end(f.rects), rectangle{0, 0, 10, 10}), 0);
}

BOOST_AUTO_TEST_CASE( count_one )
{
    const positive_area_rects_fixture f;

    BOOST_CHECK_EQUAL(std::count(std::begin(f.rects), std::end(f.rects), rectangle{10, 0, 50, 10}), 1);
    BOOST_CHECK_EQUAL(std::count(std::begin(f.rects), std::end(f.rects), rectangle{20, 30, 50, 40}), 1);
    BOOST_CHECK_EQUAL(std::count(std::begin(f.rects), std::end(f.rects), f.rects.front()), 1);
}

BOOST_AUTO_TEST_CASE( count_many )
{
    const positive_area_rects_fixture f;

    BOOST_CHECK_EQUAL(std::count(std::begin(f.rects), std::end(f.rects), rectangle{0, 0, 1, 1}), 4);
}

BOOST_AUTO_TEST_SUITE_END( /* count_test_suite */ )
<commit_msg>Adds more tests for count_if.<commit_after>#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MAIN count count_if tests

#include <boost/test/unit_test.hpp>

#include <algorithm>
#include <vector>

#include "operators.h"
#include "rectangle.h"

using rectangle = rectangle_t<int>;

BOOST_AUTO_TEST_SUITE( count_test_suite )

BOOST_AUTO_TEST_CASE( empty_container_count )
{
    std::vector<rectangle> rects;
    rectangle target;

    /*! True regardless of the coordinates of the 'target' rectangle, which
     * *actually contains garbage*. */
    BOOST_CHECK_EQUAL(std::count(std::begin(rects), std::end(rects), target), 0);
    BOOST_CHECK_EQUAL(std::count(std::begin(rects), std::end(rects), target), 0);
}

BOOST_AUTO_TEST_CASE( empty_container_count_if )
{
    std::vector<rectangle> rects;

    BOOST_CHECK_EQUAL(std::count_if(std::begin(rects), std::end(rects), true_no_op()), 0);
    BOOST_CHECK_EQUAL(std::count_if(std::begin(rects), std::end(rects), false_no_op()), 0);
    BOOST_CHECK_EQUAL(std::count_if(std::begin(rects), std::end(rects), alternating_no_op()), 0);
}

BOOST_AUTO_TEST_CASE( count_zero )
{
    const positive_area_rects_fixture f;

    BOOST_CHECK_EQUAL(std::count(std::begin(f.rects), std::end(f.rects), rectangle{1, 2, 3, 4}), 0);
    BOOST_CHECK_EQUAL(std::count(std::begin(f.rects), std::end(f.rects), rectangle{0, 0, 0, 0}), 0);
    BOOST_CHECK_EQUAL(std::count(std::begin(f.rects), std::end(f.rects), rectangle{0, 0, 10, 10}), 0);
}

BOOST_AUTO_TEST_CASE( count_one )
{
    const positive_area_rects_fixture f;

    BOOST_CHECK_EQUAL(std::count(std::begin(f.rects), std::end(f.rects), rectangle{10, 0, 50, 10}), 1);
    BOOST_CHECK_EQUAL(std::count(std::begin(f.rects), std::end(f.rects), rectangle{20, 30, 50, 40}), 1);
    BOOST_CHECK_EQUAL(std::count(std::begin(f.rects), std::end(f.rects), f.rects.front()), 1);
}

BOOST_AUTO_TEST_CASE( count_many )
{
    const positive_area_rects_fixture f;

    BOOST_CHECK_EQUAL(std::count(std::begin(f.rects), std::end(f.rects), rectangle{0, 0, 1, 1}), 4);
}

BOOST_AUTO_TEST_CASE( count_if_zero )
{
    const positive_area_rects_fixture f;

    BOOST_CHECK_EQUAL(std::count_if(std::begin(f.rects), std::end(f.rects), [](rectangle const& r){ return not is_valid(r); }), 0);
    BOOST_CHECK_EQUAL(std::count_if(std::begin(f.rects), std::end(f.rects), [](rectangle const& r){ return area(r) == 0; }), 0);
}

BOOST_AUTO_TEST_CASE( count_if_one )
{
    const valid_rects_fixture f;

    BOOST_CHECK_EQUAL(std::count_if(std::begin(f.rects), std::end(f.rects), [](rectangle const& r){ return area(r) == 100; }), 1);
    BOOST_CHECK_EQUAL(std::count_if(std::begin(f.rects), std::end(f.rects), [](rectangle const& r){ return area(r) == 300; }), 1);
}

BOOST_AUTO_TEST_CASE( count_if_many )
{
    const valid_rects_fixture f;

    BOOST_CHECK_EQUAL(std::count_if(std::begin(f.rects), std::end(f.rects), [](rectangle const& r){ return area(r) == 0; }), 2);
    BOOST_CHECK_EQUAL(std::count_if(std::begin(f.rects), std::end(f.rects), [](rectangle const& r){ return area(r) == 1; }), 2);
    BOOST_CHECK_EQUAL(std::count_if(std::begin(f.rects), std::end(f.rects), [](rectangle const& r){ return area(r) > 0; }), 7);
}

BOOST_AUTO_TEST_SUITE_END( /* count_test_suite */ )
<|endoftext|>


<commit_before>/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
 * This file is part of the libfreehand project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

#include <vector>
#include <libfreehand/libfreehand.h>

namespace libfreehand
{
class FHStringVectorImpl
{
public:
  FHStringVectorImpl() : m_strings() {}
  FHStringVectorImpl(const FHStringVectorImpl &impl) : m_strings(impl.m_strings) {}
  ~FHStringVectorImpl() {}
  std::vector<WPXString> m_strings;
};

} // namespace libfreehand

libfreehand::FHStringVector::FHStringVector()
  : m_pImpl(new FHStringVectorImpl())
{
}

libfreehand::FHStringVector::FHStringVector(const FHStringVector &vec)
  : m_pImpl(new FHStringVectorImpl(*(vec.m_pImpl)))
{
}

libfreehand::FHStringVector::~FHStringVector()
{
}

libfreehand::FHStringVector &libfreehand::FHStringVector::operator=(const FHStringVector &vec)
{
  if (m_pImpl)
    delete m_pImpl;
  m_pImpl = new FHStringVectorImpl(*(vec.m_pImpl));
  return *this;
}

unsigned libfreehand::FHStringVector::size() const
{
  return (unsigned)(m_pImpl->m_strings.size());
}

bool libfreehand::FHStringVector::empty() const
{
  return m_pImpl->m_strings.empty();
}

const WPXString &libfreehand::FHStringVector::operator[](unsigned idx) const
{
  return m_pImpl->m_strings[idx];
}

void libfreehand::FHStringVector::append(const WPXString &str)
{
  m_pImpl->m_strings.push_back(str);
}

void libfreehand::FHStringVector::clear()
{
  m_pImpl->m_strings.clear();
}

/* vim:set shiftwidth=2 softtabstop=2 expandtab: */
<commit_msg>coverity: fix memory leak<commit_after>/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
 * This file is part of the libfreehand project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

#include <vector>
#include <libfreehand/libfreehand.h>

namespace libfreehand
{
class FHStringVectorImpl
{
public:
  FHStringVectorImpl() : m_strings() {}
  FHStringVectorImpl(const FHStringVectorImpl &impl) : m_strings(impl.m_strings) {}
  ~FHStringVectorImpl() {}
  std::vector<WPXString> m_strings;
};

} // namespace libfreehand

libfreehand::FHStringVector::FHStringVector()
  : m_pImpl(new FHStringVectorImpl())
{
}

libfreehand::FHStringVector::FHStringVector(const FHStringVector &vec)
  : m_pImpl(new FHStringVectorImpl(*(vec.m_pImpl)))
{
}

libfreehand::FHStringVector::~FHStringVector()
{
  delete m_pImpl;
}

libfreehand::FHStringVector &libfreehand::FHStringVector::operator=(const FHStringVector &vec)
{
  if (m_pImpl)
    delete m_pImpl;
  m_pImpl = new FHStringVectorImpl(*(vec.m_pImpl));
  return *this;
}

unsigned libfreehand::FHStringVector::size() const
{
  return (unsigned)(m_pImpl->m_strings.size());
}

bool libfreehand::FHStringVector::empty() const
{
  return m_pImpl->m_strings.empty();
}

const WPXString &libfreehand::FHStringVector::operator[](unsigned idx) const
{
  return m_pImpl->m_strings[idx];
}

void libfreehand::FHStringVector::append(const WPXString &str)
{
  m_pImpl->m_strings.push_back(str);
}

void libfreehand::FHStringVector::clear()
{
  m_pImpl->m_strings.clear();
}

/* vim:set shiftwidth=2 softtabstop=2 expandtab: */
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: xmlsignature_nssimpl.cxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: vg $ $Date: 2005-03-10 18:14:35 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  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., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _SAL_CONFIG_H_
#include <sal/config.h>
#endif

#ifndef _RTL_UUID_H_
#include <rtl/uuid.h>
#endif

#ifndef _XMLSIGNATURE_NSSIMPL_HXX_
#include "xmlsignature_nssimpl.hxx"
#endif

#ifndef _XMLDOCUMENTWRAPPER_XMLSECIMPL_HXX_
#include "xmldocumentwrapper_xmlsecimpl.hxx"
#endif

#ifndef _XMLELEMENTWRAPPER_XMLSECIMPL_HXX_
#include "xmlelementwrapper_xmlsecimpl.hxx"
#endif

#ifndef _SECURITYENVIRONMENT_NSSIMPL_HXX_
#include "securityenvironment_nssimpl.hxx"
#endif

#ifndef _XMLSECURITYCONTEXT_NSSIMPL_HXX_
#include "xmlsecuritycontext_nssimpl.hxx"
#endif

#ifndef _XMLSTREAMIO_XMLSECIMPL_HXX_
#include "xmlstreamio.hxx"
#endif

#ifndef _ERRORCALLBACK_XMLSECIMPL_HXX_
#include "errorcallback.hxx"
#endif

#include "xmlsec/xmlsec.h"
#include "xmlsec/xmldsig.h"
#include "xmlsec/crypto.h"

using namespace ::com::sun::star::uno ;
using namespace ::com::sun::star::lang ;
using ::com::sun::star::lang::XMultiServiceFactory ;
using ::com::sun::star::lang::XSingleServiceFactory ;
using ::rtl::OUString ;

using ::com::sun::star::xml::wrapper::XXMLElementWrapper ;
using ::com::sun::star::xml::wrapper::XXMLDocumentWrapper ;
using ::com::sun::star::xml::crypto::XSecurityEnvironment ;
using ::com::sun::star::xml::crypto::XXMLSignature ;
using ::com::sun::star::xml::crypto::XXMLSignatureTemplate ;
using ::com::sun::star::xml::crypto::XSecurityEnvironment ;
using ::com::sun::star::xml::crypto::XXMLSecurityContext ;
using ::com::sun::star::xml::crypto::XUriBinding ;
using ::com::sun::star::xml::crypto::XMLSignatureException ;

XMLSignature_NssImpl :: XMLSignature_NssImpl( const Reference< XMultiServiceFactory >& aFactory ) : m_xServiceManager( aFactory ) {
}

XMLSignature_NssImpl :: ~XMLSignature_NssImpl() {
}

/* XXMLSignature */
Reference< XXMLSignatureTemplate >
SAL_CALL XMLSignature_NssImpl :: generate(
    const Reference< XXMLSignatureTemplate >& aTemplate ,
    const Reference< XSecurityEnvironment >& aEnvironment
) throw( com::sun::star::xml::crypto::XMLSignatureException,
         com::sun::star::uno::SecurityException )
{
    xmlSecKeysMngrPtr pMngr = NULL ;
    xmlSecDSigCtxPtr pDsigCtx = NULL ;
    xmlNodePtr pNode = NULL ;

    if( !aTemplate.is() )
        throw RuntimeException() ;

    if( !aEnvironment.is() )
        throw RuntimeException() ;

    //Get the xml node
    Reference< XXMLElementWrapper > xElement = aTemplate->getTemplate() ;
    if( !xElement.is() ) {
        throw RuntimeException() ;
    }

    Reference< XUnoTunnel > xNodTunnel( xElement , UNO_QUERY ) ;
    if( !xNodTunnel.is() ) {
        throw RuntimeException() ;
    }

    XMLElementWrapper_XmlSecImpl* pElement = ( XMLElementWrapper_XmlSecImpl* )xNodTunnel->getSomething( XMLElementWrapper_XmlSecImpl::getUnoTunnelImplementationId() ) ;
    if( pElement == NULL ) {
        throw RuntimeException() ;
    }

    pNode = pElement->getNativeElement() ;

    //Get the stream/URI binding
    Reference< XUriBinding > xUriBinding = aTemplate->getBinding() ;
    if( xUriBinding.is() ) {
        //Register the stream input callbacks into libxml2
        if( xmlRegisterStreamInputCallbacks( xUriBinding ) < 0 )
            throw RuntimeException() ;
    }

    //Get Keys Manager
    Reference< XUnoTunnel > xSecTunnel( aEnvironment , UNO_QUERY ) ;
    if( !xSecTunnel.is() ) {
         throw RuntimeException() ;
    }

#if 0 //i39448 : the key manager should be retrieved from SecurityEnvironment, instead of SecurityContext
    XMLSecurityContext_NssImpl* pSecCtxt = ( XMLSecurityContext_NssImpl* )xSecTunnel->getSomething( XMLSecurityContext_NssImpl::getUnoTunnelId() ) ;
    if( pSecCtxt == NULL )
        throw RuntimeException() ;
#endif

    SecurityEnvironment_NssImpl* pSecEnv = ( SecurityEnvironment_NssImpl* )xSecTunnel->getSomething( SecurityEnvironment_NssImpl::getUnoTunnelId() ) ;
    if( pSecEnv == NULL )
        throw RuntimeException() ;

     setErrorRecorder( aTemplate );

    pMngr = pSecEnv->createKeysManager() ; //i39448
    if( !pMngr ) {
        throw RuntimeException() ;
    }

    //Create Signature context
    pDsigCtx = xmlSecDSigCtxCreate( pMngr ) ;
    if( pDsigCtx == NULL )
    {
        pSecEnv->destroyKeysManager( pMngr ) ; //i39448
        //throw XMLSignatureException() ;
        clearErrorRecorder();
        return aTemplate;
    }

    //Sign the template
    if( xmlSecDSigCtxSign( pDsigCtx , pNode ) < 0 ) {
        xmlSecDSigCtxDestroy( pDsigCtx ) ;
        pSecEnv->destroyKeysManager( pMngr ) ; //i39448

        //Unregistered the stream/URI binding
        if( xUriBinding.is() )
            xmlUnregisterStreamInputCallbacks() ;

        //throw XMLSignatureException() ;
        clearErrorRecorder();
        return aTemplate;
    }

    xmlSecDSigCtxDestroy( pDsigCtx ) ;
    pSecEnv->destroyKeysManager( pMngr ) ; //i39448

    //Unregistered the stream/URI binding
    if( xUriBinding.is() )
        xmlUnregisterStreamInputCallbacks() ;

    clearErrorRecorder();
    return aTemplate ;
}

/* XXMLSignature */
Reference< XXMLSignatureTemplate >
SAL_CALL XMLSignature_NssImpl :: validate(
    const Reference< XXMLSignatureTemplate >& aTemplate ,
    const Reference< XXMLSecurityContext >& aSecurityCtx
) throw( com::sun::star::uno::RuntimeException,
         com::sun::star::uno::SecurityException,
         com::sun::star::xml::crypto::XMLSignatureException ) {
    xmlSecKeysMngrPtr pMngr = NULL ;
    xmlSecDSigCtxPtr pDsigCtx = NULL ;
    xmlNodePtr pNode = NULL ;
    //sal_Bool valid ;

    if( !aTemplate.is() )
        throw RuntimeException() ;

    if( !aSecurityCtx.is() )
        throw RuntimeException() ;

    //Get the xml node
    Reference< XXMLElementWrapper > xElement = aTemplate->getTemplate() ;
    if( !xElement.is() )
        throw RuntimeException() ;

    Reference< XUnoTunnel > xNodTunnel( xElement , UNO_QUERY ) ;
    if( !xNodTunnel.is() ) {
        throw RuntimeException() ;
    }

    XMLElementWrapper_XmlSecImpl* pElement = ( XMLElementWrapper_XmlSecImpl* )xNodTunnel->getSomething( XMLElementWrapper_XmlSecImpl::getUnoTunnelImplementationId() ) ;
    if( pElement == NULL )
        throw RuntimeException() ;

    pNode = pElement->getNativeElement() ;

    //Get the stream/URI binding
    Reference< XUriBinding > xUriBinding = aTemplate->getBinding() ;
    if( xUriBinding.is() ) {
        //Register the stream input callbacks into libxml2
        if( xmlRegisterStreamInputCallbacks( xUriBinding ) < 0 )
            throw RuntimeException() ;
    }

     setErrorRecorder( aTemplate );

    sal_Int32 nSecurityEnvironment = aSecurityCtx->getSecurityEnvironmentNumber();
    sal_Int32 i;

    for (i=0; i<nSecurityEnvironment; ++i)
    {
        Reference< XSecurityEnvironment > aEnvironment = aSecurityCtx->getSecurityEnvironmentByIndex(i);

        //Get Keys Manager
        Reference< XUnoTunnel > xSecTunnel( aEnvironment , UNO_QUERY ) ;
        if( !xSecTunnel.is() ) {
             throw RuntimeException() ;
        }

        SecurityEnvironment_NssImpl* pSecEnv = ( SecurityEnvironment_NssImpl* )xSecTunnel->getSomething( SecurityEnvironment_NssImpl::getUnoTunnelId() ) ;
        if( pSecEnv == NULL )
            throw RuntimeException() ;

        pMngr = pSecEnv->createKeysManager() ; //i39448
        if( !pMngr ) {
            throw RuntimeException() ;
        }

        //Create Signature context
        pDsigCtx = xmlSecDSigCtxCreate( pMngr ) ;
        if( pDsigCtx == NULL )
        {
            pSecEnv->destroyKeysManager( pMngr ) ; //i39448
            //throw XMLSignatureException() ;
            clearErrorRecorder();
            return aTemplate;
        }

        //Verify signature
        int rs = xmlSecDSigCtxVerify( pDsigCtx , pNode );

        xmlSecDSigCtxDestroy( pDsigCtx ) ;
        pSecEnv->destroyKeysManager( pMngr ) ; //i39448

        if (rs >= 0)
        {
            break;
        }
    }

    //Unregistered the stream/URI binding
    if( xUriBinding.is() )
        xmlUnregisterStreamInputCallbacks() ;

    //return valid ;
    clearErrorRecorder();
    return aTemplate;
}

/* XInitialization */
void SAL_CALL XMLSignature_NssImpl :: initialize( const Sequence< Any >& aArguments ) throw( Exception, RuntimeException ) {
    // TBD
} ;

/* XServiceInfo */
OUString SAL_CALL XMLSignature_NssImpl :: getImplementationName() throw( RuntimeException ) {
    return impl_getImplementationName() ;
}

/* XServiceInfo */
sal_Bool SAL_CALL XMLSignature_NssImpl :: supportsService( const OUString& serviceName) throw( RuntimeException ) {
    Sequence< OUString > seqServiceNames = getSupportedServiceNames() ;
    const OUString* pArray = seqServiceNames.getConstArray() ;
    for( sal_Int32 i = 0 ; i < seqServiceNames.getLength() ; i ++ ) {
        if( *( pArray + i ) == serviceName )
            return sal_True ;
    }
    return sal_False ;
}

/* XServiceInfo */
Sequence< OUString > SAL_CALL XMLSignature_NssImpl :: getSupportedServiceNames() throw( RuntimeException ) {
    return impl_getSupportedServiceNames() ;
}

//Helper for XServiceInfo
Sequence< OUString > XMLSignature_NssImpl :: impl_getSupportedServiceNames() {
    ::osl::Guard< ::osl::Mutex > aGuard( ::osl::Mutex::getGlobalMutex() ) ;
    Sequence< OUString > seqServiceNames( 1 ) ;
    seqServiceNames.getArray()[0] = OUString::createFromAscii( "com.sun.star.xml.crypto.XMLSignature" ) ;
    return seqServiceNames ;
}

OUString XMLSignature_NssImpl :: impl_getImplementationName() throw( RuntimeException ) {
    return OUString::createFromAscii( "com.sun.star.xml.security.bridge.xmlsec.XMLSignature_NssImpl" ) ;
}

//Helper for registry
Reference< XInterface > SAL_CALL XMLSignature_NssImpl :: impl_createInstance( const Reference< XMultiServiceFactory >& aServiceManager ) throw( RuntimeException ) {
    return Reference< XInterface >( *new XMLSignature_NssImpl( aServiceManager ) ) ;
}

Reference< XSingleServiceFactory > XMLSignature_NssImpl :: impl_createFactory( const Reference< XMultiServiceFactory >& aServiceManager ) {
    //Reference< XSingleServiceFactory > xFactory ;
    //xFactory = ::cppu::createSingleFactory( aServiceManager , impl_getImplementationName , impl_createInstance , impl_getSupportedServiceNames ) ;
    //return xFactory ;
    return ::cppu::createSingleFactory( aServiceManager , impl_getImplementationName() , impl_createInstance , impl_getSupportedServiceNames() ) ;
}

<commit_msg>INTEGRATION: CWS ooo19126 (1.4.52); FILE MERGED 2005/09/05 17:02:04 rt 1.4.52.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: xmlsignature_nssimpl.cxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-09 17:36:20 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    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., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef _SAL_CONFIG_H_
#include <sal/config.h>
#endif

#ifndef _RTL_UUID_H_
#include <rtl/uuid.h>
#endif

#ifndef _XMLSIGNATURE_NSSIMPL_HXX_
#include "xmlsignature_nssimpl.hxx"
#endif

#ifndef _XMLDOCUMENTWRAPPER_XMLSECIMPL_HXX_
#include "xmldocumentwrapper_xmlsecimpl.hxx"
#endif

#ifndef _XMLELEMENTWRAPPER_XMLSECIMPL_HXX_
#include "xmlelementwrapper_xmlsecimpl.hxx"
#endif

#ifndef _SECURITYENVIRONMENT_NSSIMPL_HXX_
#include "securityenvironment_nssimpl.hxx"
#endif

#ifndef _XMLSECURITYCONTEXT_NSSIMPL_HXX_
#include "xmlsecuritycontext_nssimpl.hxx"
#endif

#ifndef _XMLSTREAMIO_XMLSECIMPL_HXX_
#include "xmlstreamio.hxx"
#endif

#ifndef _ERRORCALLBACK_XMLSECIMPL_HXX_
#include "errorcallback.hxx"
#endif

#include "xmlsec/xmlsec.h"
#include "xmlsec/xmldsig.h"
#include "xmlsec/crypto.h"

using namespace ::com::sun::star::uno ;
using namespace ::com::sun::star::lang ;
using ::com::sun::star::lang::XMultiServiceFactory ;
using ::com::sun::star::lang::XSingleServiceFactory ;
using ::rtl::OUString ;

using ::com::sun::star::xml::wrapper::XXMLElementWrapper ;
using ::com::sun::star::xml::wrapper::XXMLDocumentWrapper ;
using ::com::sun::star::xml::crypto::XSecurityEnvironment ;
using ::com::sun::star::xml::crypto::XXMLSignature ;
using ::com::sun::star::xml::crypto::XXMLSignatureTemplate ;
using ::com::sun::star::xml::crypto::XSecurityEnvironment ;
using ::com::sun::star::xml::crypto::XXMLSecurityContext ;
using ::com::sun::star::xml::crypto::XUriBinding ;
using ::com::sun::star::xml::crypto::XMLSignatureException ;

XMLSignature_NssImpl :: XMLSignature_NssImpl( const Reference< XMultiServiceFactory >& aFactory ) : m_xServiceManager( aFactory ) {
}

XMLSignature_NssImpl :: ~XMLSignature_NssImpl() {
}

/* XXMLSignature */
Reference< XXMLSignatureTemplate >
SAL_CALL XMLSignature_NssImpl :: generate(
    const Reference< XXMLSignatureTemplate >& aTemplate ,
    const Reference< XSecurityEnvironment >& aEnvironment
) throw( com::sun::star::xml::crypto::XMLSignatureException,
         com::sun::star::uno::SecurityException )
{
    xmlSecKeysMngrPtr pMngr = NULL ;
    xmlSecDSigCtxPtr pDsigCtx = NULL ;
    xmlNodePtr pNode = NULL ;

    if( !aTemplate.is() )
        throw RuntimeException() ;

    if( !aEnvironment.is() )
        throw RuntimeException() ;

    //Get the xml node
    Reference< XXMLElementWrapper > xElement = aTemplate->getTemplate() ;
    if( !xElement.is() ) {
        throw RuntimeException() ;
    }

    Reference< XUnoTunnel > xNodTunnel( xElement , UNO_QUERY ) ;
    if( !xNodTunnel.is() ) {
        throw RuntimeException() ;
    }

    XMLElementWrapper_XmlSecImpl* pElement = ( XMLElementWrapper_XmlSecImpl* )xNodTunnel->getSomething( XMLElementWrapper_XmlSecImpl::getUnoTunnelImplementationId() ) ;
    if( pElement == NULL ) {
        throw RuntimeException() ;
    }

    pNode = pElement->getNativeElement() ;

    //Get the stream/URI binding
    Reference< XUriBinding > xUriBinding = aTemplate->getBinding() ;
    if( xUriBinding.is() ) {
        //Register the stream input callbacks into libxml2
        if( xmlRegisterStreamInputCallbacks( xUriBinding ) < 0 )
            throw RuntimeException() ;
    }

    //Get Keys Manager
    Reference< XUnoTunnel > xSecTunnel( aEnvironment , UNO_QUERY ) ;
    if( !xSecTunnel.is() ) {
         throw RuntimeException() ;
    }

#if 0 //i39448 : the key manager should be retrieved from SecurityEnvironment, instead of SecurityContext
    XMLSecurityContext_NssImpl* pSecCtxt = ( XMLSecurityContext_NssImpl* )xSecTunnel->getSomething( XMLSecurityContext_NssImpl::getUnoTunnelId() ) ;
    if( pSecCtxt == NULL )
        throw RuntimeException() ;
#endif

    SecurityEnvironment_NssImpl* pSecEnv = ( SecurityEnvironment_NssImpl* )xSecTunnel->getSomething( SecurityEnvironment_NssImpl::getUnoTunnelId() ) ;
    if( pSecEnv == NULL )
        throw RuntimeException() ;

     setErrorRecorder( aTemplate );

    pMngr = pSecEnv->createKeysManager() ; //i39448
    if( !pMngr ) {
        throw RuntimeException() ;
    }

    //Create Signature context
    pDsigCtx = xmlSecDSigCtxCreate( pMngr ) ;
    if( pDsigCtx == NULL )
    {
        pSecEnv->destroyKeysManager( pMngr ) ; //i39448
        //throw XMLSignatureException() ;
        clearErrorRecorder();
        return aTemplate;
    }

    //Sign the template
    if( xmlSecDSigCtxSign( pDsigCtx , pNode ) < 0 ) {
        xmlSecDSigCtxDestroy( pDsigCtx ) ;
        pSecEnv->destroyKeysManager( pMngr ) ; //i39448

        //Unregistered the stream/URI binding
        if( xUriBinding.is() )
            xmlUnregisterStreamInputCallbacks() ;

        //throw XMLSignatureException() ;
        clearErrorRecorder();
        return aTemplate;
    }

    xmlSecDSigCtxDestroy( pDsigCtx ) ;
    pSecEnv->destroyKeysManager( pMngr ) ; //i39448

    //Unregistered the stream/URI binding
    if( xUriBinding.is() )
        xmlUnregisterStreamInputCallbacks() ;

    clearErrorRecorder();
    return aTemplate ;
}

/* XXMLSignature */
Reference< XXMLSignatureTemplate >
SAL_CALL XMLSignature_NssImpl :: validate(
    const Reference< XXMLSignatureTemplate >& aTemplate ,
    const Reference< XXMLSecurityContext >& aSecurityCtx
) throw( com::sun::star::uno::RuntimeException,
         com::sun::star::uno::SecurityException,
         com::sun::star::xml::crypto::XMLSignatureException ) {
    xmlSecKeysMngrPtr pMngr = NULL ;
    xmlSecDSigCtxPtr pDsigCtx = NULL ;
    xmlNodePtr pNode = NULL ;
    //sal_Bool valid ;

    if( !aTemplate.is() )
        throw RuntimeException() ;

    if( !aSecurityCtx.is() )
        throw RuntimeException() ;

    //Get the xml node
    Reference< XXMLElementWrapper > xElement = aTemplate->getTemplate() ;
    if( !xElement.is() )
        throw RuntimeException() ;

    Reference< XUnoTunnel > xNodTunnel( xElement , UNO_QUERY ) ;
    if( !xNodTunnel.is() ) {
        throw RuntimeException() ;
    }

    XMLElementWrapper_XmlSecImpl* pElement = ( XMLElementWrapper_XmlSecImpl* )xNodTunnel->getSomething( XMLElementWrapper_XmlSecImpl::getUnoTunnelImplementationId() ) ;
    if( pElement == NULL )
        throw RuntimeException() ;

    pNode = pElement->getNativeElement() ;

    //Get the stream/URI binding
    Reference< XUriBinding > xUriBinding = aTemplate->getBinding() ;
    if( xUriBinding.is() ) {
        //Register the stream input callbacks into libxml2
        if( xmlRegisterStreamInputCallbacks( xUriBinding ) < 0 )
            throw RuntimeException() ;
    }

     setErrorRecorder( aTemplate );

    sal_Int32 nSecurityEnvironment = aSecurityCtx->getSecurityEnvironmentNumber();
    sal_Int32 i;

    for (i=0; i<nSecurityEnvironment; ++i)
    {
        Reference< XSecurityEnvironment > aEnvironment = aSecurityCtx->getSecurityEnvironmentByIndex(i);

        //Get Keys Manager
        Reference< XUnoTunnel > xSecTunnel( aEnvironment , UNO_QUERY ) ;
        if( !xSecTunnel.is() ) {
             throw RuntimeException() ;
        }

        SecurityEnvironment_NssImpl* pSecEnv = ( SecurityEnvironment_NssImpl* )xSecTunnel->getSomething( SecurityEnvironment_NssImpl::getUnoTunnelId() ) ;
        if( pSecEnv == NULL )
            throw RuntimeException() ;

        pMngr = pSecEnv->createKeysManager() ; //i39448
        if( !pMngr ) {
            throw RuntimeException() ;
        }

        //Create Signature context
        pDsigCtx = xmlSecDSigCtxCreate( pMngr ) ;
        if( pDsigCtx == NULL )
        {
            pSecEnv->destroyKeysManager( pMngr ) ; //i39448
            //throw XMLSignatureException() ;
            clearErrorRecorder();
            return aTemplate;
        }

        //Verify signature
        int rs = xmlSecDSigCtxVerify( pDsigCtx , pNode );

        xmlSecDSigCtxDestroy( pDsigCtx ) ;
        pSecEnv->destroyKeysManager( pMngr ) ; //i39448

        if (rs >= 0)
        {
            break;
        }
    }

    //Unregistered the stream/URI binding
    if( xUriBinding.is() )
        xmlUnregisterStreamInputCallbacks() ;

    //return valid ;
    clearErrorRecorder();
    return aTemplate;
}

/* XInitialization */
void SAL_CALL XMLSignature_NssImpl :: initialize( const Sequence< Any >& aArguments ) throw( Exception, RuntimeException ) {
    // TBD
} ;

/* XServiceInfo */
OUString SAL_CALL XMLSignature_NssImpl :: getImplementationName() throw( RuntimeException ) {
    return impl_getImplementationName() ;
}

/* XServiceInfo */
sal_Bool SAL_CALL XMLSignature_NssImpl :: supportsService( const OUString& serviceName) throw( RuntimeException ) {
    Sequence< OUString > seqServiceNames = getSupportedServiceNames() ;
    const OUString* pArray = seqServiceNames.getConstArray() ;
    for( sal_Int32 i = 0 ; i < seqServiceNames.getLength() ; i ++ ) {
        if( *( pArray + i ) == serviceName )
            return sal_True ;
    }
    return sal_False ;
}

/* XServiceInfo */
Sequence< OUString > SAL_CALL XMLSignature_NssImpl :: getSupportedServiceNames() throw( RuntimeException ) {
    return impl_getSupportedServiceNames() ;
}

//Helper for XServiceInfo
Sequence< OUString > XMLSignature_NssImpl :: impl_getSupportedServiceNames() {
    ::osl::Guard< ::osl::Mutex > aGuard( ::osl::Mutex::getGlobalMutex() ) ;
    Sequence< OUString > seqServiceNames( 1 ) ;
    seqServiceNames.getArray()[0] = OUString::createFromAscii( "com.sun.star.xml.crypto.XMLSignature" ) ;
    return seqServiceNames ;
}

OUString XMLSignature_NssImpl :: impl_getImplementationName() throw( RuntimeException ) {
    return OUString::createFromAscii( "com.sun.star.xml.security.bridge.xmlsec.XMLSignature_NssImpl" ) ;
}

//Helper for registry
Reference< XInterface > SAL_CALL XMLSignature_NssImpl :: impl_createInstance( const Reference< XMultiServiceFactory >& aServiceManager ) throw( RuntimeException ) {
    return Reference< XInterface >( *new XMLSignature_NssImpl( aServiceManager ) ) ;
}

Reference< XSingleServiceFactory > XMLSignature_NssImpl :: impl_createFactory( const Reference< XMultiServiceFactory >& aServiceManager ) {
    //Reference< XSingleServiceFactory > xFactory ;
    //xFactory = ::cppu::createSingleFactory( aServiceManager , impl_getImplementationName , impl_createInstance , impl_getSupportedServiceNames ) ;
    //return xFactory ;
    return ::cppu::createSingleFactory( aServiceManager , impl_getImplementationName() , impl_createInstance , impl_getSupportedServiceNames() ) ;
}

<|endoftext|>


<commit_before>/*
 * file: entity314.cpp
 *
 * Copyright 2015, Dr. Cirilo Bernardo (cirilo.bernardo@gmail.com)
 *
 * Description: IGES Entity 314: Color, Section 4.77, p.386 (414)
 *
 * This file is part of libIGES.
 *
 * libIGES 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 2.1 of the License, or (at your option) any later version.
 *
 * libIGES 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, If not, see
 * <http://www.gnu.org/licenses/> or write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 *
 */

#include <sstream>
#include <error_macros.h>
#include <iges.h>
#include <iges_io.h>
#include <entity314.h>
#include <entity124.h>

using namespace std;

IGES_ENTITY_314::IGES_ENTITY_314( IGES* aParent ) : IGES_ENTITY( aParent ),
CNAME( cname )
{
    entityType = 314;
    form = 0;
    red = 85.0;
    green = 20.0;
    blue = 20.0;
    colorNum = COLOR_RED;
}

IGES_ENTITY_314::~IGES_ENTITY_314()
{
    return;
}

void IGES_ENTITY_314::Compact( void )
{
    return;
}

bool IGES_ENTITY_314::associate(std::vector<IGES_ENTITY *> *entities)
{
    if( !IGES_ENTITY::associate(entities) )
    {
        ERRMSG << "\n + [INFO] failed to establish associations\n";
        return false;
    }

    structure = 0;
    lineFontPattern = 0;
    level = 0;
    view = 0;
    transform = 0;
    labelAssoc = 0;
    lineWeightNum = 0;

    if( pStructure )
    {
        ERRMSG << "\n + [VIOLATION] Structure entity is set\n";
        pStructure->delReference(this);
        pStructure = NULL;
    }

    if( pLineFontPattern )
    {
        ERRMSG << "\n + [VIOLATION] Line Font Pattern entity is set\n";
        pLineFontPattern->delReference(this);
        pLineFontPattern = NULL;
    }

    if( pLevel )
    {
        ERRMSG << "\n + [VIOLATION] Level entity is set\n";
        pLevel->delReference(this);
        pLevel = NULL;
    }

    if( pView )
    {
        ERRMSG << "\n + [VIOLATION] View entity is set\n";
        pView->delReference(this);
        pView = NULL;
    }

    if( pTransform )
    {
        ERRMSG << "\n + [VIOLATION] Transform entity is set\n";
        pTransform->delReference(this);
        pTransform = NULL;
    }

    if( pLabelAssoc )
    {
        ERRMSG << "\n + [VIOLATION] Label Associativity is set\n";
        pLabelAssoc->delReference(this);
        pLabelAssoc = NULL;
    }

    if( pColor )
    {
        ERRMSG << "\n + [VIOLATION] Color entity is set\n";
        pColor->delReference(this);
        pColor = NULL;
    }

    return true;
}

bool IGES_ENTITY_314::format( int &index )
{
    pdout.clear();
    iExtras.clear();

    // ensure compliance of STATUS NUM with specification
    depends = STAT_INDEPENDENT;     // fixed value
    use = STAT_USE_DEFINITION;      // fixed value

    if( red < 0.0 || red > 100.0 )
    {
        ERRMSG << "\n + [INFO] invalid value for RED (" << red << ")\n";
        red = 85.0;
    }

    if( green < 0.0 || green > 100.0 )
    {
        ERRMSG << "\n + [INFO] invalid value for GREEN (" << green << ")\n";
        green = 20.0;
    }

    if( blue < 0.0 || blue > 100.0 )
    {
        ERRMSG << "\n + [INFO] invalid value for BLUE (" << blue << ")\n";
        blue = 20.0;
    }

    if( cname.empty() )
        cname = "none";

    if( index < 1 || index > 9999999 )
    {
        ERRMSG << "\n + [INFO] invalid Parameter Data Sequence Number\n";
        return false;
    }

    parameterData = index;

    if( !parent )
    {
        ERRMSG << "\n + [INFO] method invoked with no parent IGES object\n";
        return false;
    }

    char pd = parent->globalData.pdelim;
    char rd = parent->globalData.rdelim;

    ostringstream ostr;
    ostr << entityType << pd;
    string fStr = ostr.str();
    string tStr;

    if( !FormatPDREal( tStr, red, pd, 0.1 ) )
    {
        ERRMSG << "\n + [INFO] could not format RED\n";
        return false;
    }

    AddPDItem( tStr, fStr, pdout, index, sequenceNumber, pd, rd );

    if( !FormatPDREal( tStr, green, pd, 0.1 ) )
    {
        ERRMSG << "\n + [INFO] could not format GREEN\n";
        pdout.clear();
        return false;
    }

    AddPDItem( tStr, fStr, pdout, index, sequenceNumber, pd, rd );

    char idelim;

    if( extras.empty() )
        idelim = rd;
    else
        idelim = pd;

    if( !FormatPDREal( tStr, blue, idelim, 0.1 ) )
    {
        ERRMSG << "\n + [INFO] could not format yEnd\n";
        pdout.clear();
        return false;
    }

    AddPDItem( tStr, fStr, pdout, index, sequenceNumber, pd, rd );

    if( !extras.empty() && !formatExtraParams( fStr, index, pd, rd ) )
    {
        ERRMSG << "\n + [INFO] could not format optional parameters\n";
        pdout.clear();
        iExtras.clear();
        return false;
    }

    if( !formatComments( index ) )
    {
        ERRMSG << "\n + [INFO] could not format comments\n";
        pdout.clear();
        return false;
    }

    paramLineCount = index - parameterData;

    return true;
}

bool IGES_ENTITY_314::rescale( double sf )
{
    // there is nothing to scale
    return true;
}

bool IGES_ENTITY_314::unlink(IGES_ENTITY *aChild)
{
    // check if there are any extra entities to unlink
    return IGES_ENTITY::unlink(aChild);
}

bool IGES_ENTITY_314::isOrphaned( void )
{
    if( refs.empty() )
        return true;

    return false;
}

bool IGES_ENTITY_314::addReference(IGES_ENTITY *aParentEntity, bool &isDuplicate)
{
    return IGES_ENTITY::addReference(aParentEntity, isDuplicate);
}

bool IGES_ENTITY_314::delReference(IGES_ENTITY *aParentEntity)
{
    return IGES_ENTITY::delReference(aParentEntity);
}

bool IGES_ENTITY_314::readDE(IGES_RECORD *aRecord, std::ifstream &aFile, int &aSequenceVar)
{
    if( !IGES_ENTITY::readDE(aRecord, aFile, aSequenceVar) )
    {
        ERRMSG << "\n + [INFO] failed to read Directory Entry\n";
        return false;
    }

    depends = STAT_INDEPENDENT;     // fixed value
    use = STAT_USE_DEFINITION;      // fixed value

    structure = 0;                  // N.A.
    lineFontPattern = 0;            // N.A.
    level = 0;                      // N.A.
    view = 0;                       // N.A.
    transform = 0;                  // N.A.
    labelAssoc = 0;                 // N.A.
    lineWeightNum = 0;              // N.A.

    if( form != 0 )
    {
        ERRMSG << "\n + [CORRUPT FILE] non-zero Form Number in Color Def.\n";
        cerr << " + DE: " << aRecord->index << "\n";
        return false;
    }

    return true;
}

bool IGES_ENTITY_314::readPD(std::ifstream &aFile, int &aSequenceVar)
{
    if( !IGES_ENTITY::readPD(aFile, aSequenceVar) )
    {
        ERRMSG << "\n + [INFO] could not read data for Color Definition\n";
        pdout.clear();
        return false;
    }

    int idx;
    bool eor = false;
    char pd = parent->globalData.pdelim;
    char rd = parent->globalData.rdelim;

	idx = (int)pdout.find(pd);

    if( idx < 1 || idx > 8 )
    {
        ERRMSG << "\n + [BAD FILE] strange index for first parameter delimeter (";
        cerr << idx << ")\n";
        pdout.clear();
        return false;
    }

    ++idx;

    if( !ParseReal( pdout, idx, red, eor, pd, rd ) )
    {
        ERRMSG << "\n + [BAD FILE] no value for RED\n";
        pdout.clear();
        return false;
    }

    if( !ParseReal( pdout, idx, green, eor, pd, rd ) )
    {
        ERRMSG << "\n + [BAD FILE] no value for RED\n";
        pdout.clear();
        return false;
    }

    if( !ParseReal( pdout, idx, blue, eor, pd, rd ) )
    {
        ERRMSG << "\n + [BAD FILE] no value for RED\n";
        pdout.clear();
        return false;
    }

    if( !eor && !ParseHString( pdout, idx, cname, eor, pd, rd ) )
    {
        ERRMSG << "\n + [BAD FILE] problems encountered while parsing color name\n";
        pdout.clear();
        return false;
    }

    if( red < 0.0 || red > 100.0 )
    {
        ERRMSG << "\n + [INFO] invalid value for RED (" << red << ")\n";
        red = 85.0;
    }

    if( green < 0.0 || green > 100.0 )
    {
        ERRMSG << "\n + [INFO] invalid value for GREEN (" << green << ")\n";
        green = 20.0;
    }

    if( blue < 0.0 || blue > 100.0 )
    {
        ERRMSG << "\n + [INFO] invalid value for BLUE (" << blue << ")\n";
        blue = 20.0;
    }

    if( cname.empty() )
        cname = "none";

    if( !eor && !readExtraParams( idx ) )
    {
        ERRMSG << "\n + [BAD FILE] could not read optional pointers\n";
        pdout.clear();
        return false;
    }

    if( !readComments( idx ) )
    {
        ERRMSG << "\n + [BAD FILE] could not read extra comments\n";
        pdout.clear();
        return false;
    }

    pdout.clear();
    return true;
}

bool IGES_ENTITY_314::SetEntityForm( int aForm )
{
    if( aForm != 0 )
    {
        ERRMSG << "\n + [WARNING] [BUG] Color Definition Entity only supports Form 0 (requested form: ";
        cerr << aForm << ")\n";
    }

    return true;
}

bool IGES_ENTITY_314::SetDependency( IGES_STAT_DEPENDS aDependency )
{
    if( aDependency != 0 )
    {
        ERRMSG << "\n + [WARNING] [BUG] Color Definition Entity only supports STAT_INDEPENDENT\n";
    }

    return true;
}

bool IGES_ENTITY_314::SetEntityUse( IGES_STAT_USE aUseCase )
{
    if( aUseCase != 2 )
    {
        ERRMSG << "\n + [WARNING] [BUG] Color Definition Entity only supports STAT_USE_DEFINITION\n";
    }

    return true;
}

bool IGES_ENTITY_314::SetHierarchy( IGES_STAT_HIER aHierarchy )
{
    // value ignored
    ERRMSG << "\n + [WARNING] [BUG] Color Definition Entity does not support hierarchy\n";
    return true;
}

bool IGES_ENTITY_314::SetLineFontPattern( IGES_LINEFONT_PATTERN aPattern )
{
    ERRMSG << "\n + [WARNING] [BUG] Color Definition Entity does not support Line Font Pattern\n";
    return true;
}

bool IGES_ENTITY_314::SetLineFontPattern( IGES_ENTITY* aPattern )
{
    ERRMSG << "\n + [WARNING] [BUG] Color Definition Entity does not support Line Font Pattern\n";
    return true;
}

bool IGES_ENTITY_314::SetLevel( int aLevel )
{
    ERRMSG << "\n + [WARNING] [BUG] Color Definition Entity does not support Level\n";
    return true;
}

bool IGES_ENTITY_314::SetLevel( IGES_ENTITY* aLevel )
{
    ERRMSG << "\n + [WARNING] [BUG] Color Definition Entity does not support Level\n";
    return true;
}

bool IGES_ENTITY_314::SetView( IGES_ENTITY* aView )
{
    ERRMSG << "\n + [WARNING] [BUG] Color Definition Entity does not support View\n";
    return true;
}

bool IGES_ENTITY_314::SetTransform( IGES_ENTITY* aTransform )
{
    ERRMSG << "\n + [WARNING] [BUG] Color Definition Entity does not support Transform\n";
    return true;
}

bool IGES_ENTITY_314::SetLabelAssoc( IGES_ENTITY* aLabelAssoc )
{
    ERRMSG << "\n + [WARNING] [BUG] Color Definition Entity does not support Label Associativity\n";
    return true;
}

bool IGES_ENTITY_314::SetColor( IGES_COLOR aColor )
{
    if( aColor > COLOR_NONE && aColor < COLOR_END )
    {
        colorNum = aColor;
        return true;
    }

    ERRMSG << "\n + [WARNING] [BUG] Color Number must be one of 1 .. 8\n";
    return false;
}

bool IGES_ENTITY_314::SetColor( IGES_ENTITY* aColor )
{
    ERRMSG << "\n + [WARNING] [BUG] Color Definition Entity does not support child Color Definition Entity\n";
    return true;
}

bool IGES_ENTITY_314::SetVisibility(bool isVisible)
{
    ERRMSG << "\n + [WARNING] [BUG] Color Definition Entity does not support Blank Status (visibility)\n";
    return true;
}

bool IGES_ENTITY_314::SetLineWeightNum( int aLineWeight )
{
    ERRMSG << "\n + [WARNING] [BUG] Color Definition Entity does not support Line Weight\n";
    return true;
}
<commit_msg>Bug fix in E314 (color name was not written)<commit_after>/*
 * file: entity314.cpp
 *
 * Copyright 2015, Dr. Cirilo Bernardo (cirilo.bernardo@gmail.com)
 *
 * Description: IGES Entity 314: Color, Section 4.77, p.386 (414)
 *
 * This file is part of libIGES.
 *
 * libIGES 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 2.1 of the License, or (at your option) any later version.
 *
 * libIGES 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, If not, see
 * <http://www.gnu.org/licenses/> or write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 *
 */

#include <sstream>
#include <error_macros.h>
#include <iges.h>
#include <iges_io.h>
#include <entity314.h>
#include <entity124.h>

using namespace std;

IGES_ENTITY_314::IGES_ENTITY_314( IGES* aParent ) : IGES_ENTITY( aParent ),
CNAME( cname )
{
    entityType = 314;
    form = 0;
    red = 85.0;
    green = 20.0;
    blue = 20.0;
    colorNum = COLOR_RED;
}

IGES_ENTITY_314::~IGES_ENTITY_314()
{
    return;
}

void IGES_ENTITY_314::Compact( void )
{
    return;
}

bool IGES_ENTITY_314::associate(std::vector<IGES_ENTITY *> *entities)
{
    if( !IGES_ENTITY::associate(entities) )
    {
        ERRMSG << "\n + [INFO] failed to establish associations\n";
        return false;
    }

    structure = 0;
    lineFontPattern = 0;
    level = 0;
    view = 0;
    transform = 0;
    labelAssoc = 0;
    lineWeightNum = 0;

    if( pStructure )
    {
        ERRMSG << "\n + [VIOLATION] Structure entity is set\n";
        pStructure->delReference(this);
        pStructure = NULL;
    }

    if( pLineFontPattern )
    {
        ERRMSG << "\n + [VIOLATION] Line Font Pattern entity is set\n";
        pLineFontPattern->delReference(this);
        pLineFontPattern = NULL;
    }

    if( pLevel )
    {
        ERRMSG << "\n + [VIOLATION] Level entity is set\n";
        pLevel->delReference(this);
        pLevel = NULL;
    }

    if( pView )
    {
        ERRMSG << "\n + [VIOLATION] View entity is set\n";
        pView->delReference(this);
        pView = NULL;
    }

    if( pTransform )
    {
        ERRMSG << "\n + [VIOLATION] Transform entity is set\n";
        pTransform->delReference(this);
        pTransform = NULL;
    }

    if( pLabelAssoc )
    {
        ERRMSG << "\n + [VIOLATION] Label Associativity is set\n";
        pLabelAssoc->delReference(this);
        pLabelAssoc = NULL;
    }

    if( pColor )
    {
        ERRMSG << "\n + [VIOLATION] Color entity is set\n";
        pColor->delReference(this);
        pColor = NULL;
    }

    return true;
}

bool IGES_ENTITY_314::format( int &index )
{
    pdout.clear();
    iExtras.clear();

    // ensure compliance of STATUS NUM with specification
    depends = STAT_INDEPENDENT;     // fixed value
    use = STAT_USE_DEFINITION;      // fixed value

    if( red < 0.0 || red > 100.0 )
    {
        ERRMSG << "\n + [INFO] invalid value for RED (" << red << ")\n";
        red = 85.0;
    }

    if( green < 0.0 || green > 100.0 )
    {
        ERRMSG << "\n + [INFO] invalid value for GREEN (" << green << ")\n";
        green = 20.0;
    }

    if( blue < 0.0 || blue > 100.0 )
    {
        ERRMSG << "\n + [INFO] invalid value for BLUE (" << blue << ")\n";
        blue = 20.0;
    }

    if( index < 1 || index > 9999999 )
    {
        ERRMSG << "\n + [INFO] invalid Parameter Data Sequence Number\n";
        return false;
    }

    parameterData = index;

    if( !parent )
    {
        ERRMSG << "\n + [INFO] method invoked with no parent IGES object\n";
        return false;
    }

    char pd = parent->globalData.pdelim;
    char rd = parent->globalData.rdelim;

    ostringstream ostr;
    ostr << entityType << pd;
    string fStr = ostr.str();
    string tStr;

    if( !FormatPDREal( tStr, red, pd, 0.1 ) )
    {
        ERRMSG << "\n + [INFO] could not format RED\n";
        return false;
    }

    AddPDItem( tStr, fStr, pdout, index, sequenceNumber, pd, rd );

    if( !FormatPDREal( tStr, green, pd, 0.1 ) )
    {
        ERRMSG << "\n + [INFO] could not format GREEN\n";
        pdout.clear();
        return false;
    }

    AddPDItem( tStr, fStr, pdout, index, sequenceNumber, pd, rd );

    char idelim;

    if( cname.empty() )
    {
        if( extras.empty() )
            idelim = rd;
        else
            idelim = pd;
    }
    else
    {
        idelim = pd;
    }

    if( !FormatPDREal( tStr, blue, idelim, 0.1 ) )
    {
        ERRMSG << "\n + [INFO] could not format yEnd\n";
        pdout.clear();
        return false;
    }

    AddPDItem( tStr, fStr, pdout, index, sequenceNumber, pd, rd );

    if( !cname.empty() )
    {
        if( extras.empty() )
            idelim = rd;
        else
            idelim = pd;

        ostr.str( "" );
        ostr << cname.size() << "H" << cname << idelim;
        tStr = ostr.str();
        AddPDItem( tStr, fStr, pdout, index, sequenceNumber, pd, rd );
    }

    if( !extras.empty() && !formatExtraParams( fStr, index, pd, rd ) )
    {
        ERRMSG << "\n + [INFO] could not format optional parameters\n";
        pdout.clear();
        iExtras.clear();
        return false;
    }

    if( !formatComments( index ) )
    {
        ERRMSG << "\n + [INFO] could not format comments\n";
        pdout.clear();
        return false;
    }

    paramLineCount = index - parameterData;

    return true;
}

bool IGES_ENTITY_314::rescale( double sf )
{
    // there is nothing to scale
    return true;
}

bool IGES_ENTITY_314::unlink(IGES_ENTITY *aChild)
{
    // check if there are any extra entities to unlink
    return IGES_ENTITY::unlink(aChild);
}

bool IGES_ENTITY_314::isOrphaned( void )
{
    if( refs.empty() )
        return true;

    return false;
}

bool IGES_ENTITY_314::addReference(IGES_ENTITY *aParentEntity, bool &isDuplicate)
{
    return IGES_ENTITY::addReference(aParentEntity, isDuplicate);
}

bool IGES_ENTITY_314::delReference(IGES_ENTITY *aParentEntity)
{
    return IGES_ENTITY::delReference(aParentEntity);
}

bool IGES_ENTITY_314::readDE(IGES_RECORD *aRecord, std::ifstream &aFile, int &aSequenceVar)
{
    if( !IGES_ENTITY::readDE(aRecord, aFile, aSequenceVar) )
    {
        ERRMSG << "\n + [INFO] failed to read Directory Entry\n";
        return false;
    }

    depends = STAT_INDEPENDENT;     // fixed value
    use = STAT_USE_DEFINITION;      // fixed value

    structure = 0;                  // N.A.
    lineFontPattern = 0;            // N.A.
    level = 0;                      // N.A.
    view = 0;                       // N.A.
    transform = 0;                  // N.A.
    labelAssoc = 0;                 // N.A.
    lineWeightNum = 0;              // N.A.

    if( form != 0 )
    {
        ERRMSG << "\n + [CORRUPT FILE] non-zero Form Number in Color Def.\n";
        cerr << " + DE: " << aRecord->index << "\n";
        return false;
    }

    return true;
}

bool IGES_ENTITY_314::readPD(std::ifstream &aFile, int &aSequenceVar)
{
    if( !IGES_ENTITY::readPD(aFile, aSequenceVar) )
    {
        ERRMSG << "\n + [INFO] could not read data for Color Definition\n";
        pdout.clear();
        return false;
    }

    int idx;
    bool eor = false;
    char pd = parent->globalData.pdelim;
    char rd = parent->globalData.rdelim;

	idx = (int)pdout.find(pd);

    if( idx < 1 || idx > 8 )
    {
        ERRMSG << "\n + [BAD FILE] strange index for first parameter delimeter (";
        cerr << idx << ")\n";
        pdout.clear();
        return false;
    }

    ++idx;

    if( !ParseReal( pdout, idx, red, eor, pd, rd ) )
    {
        ERRMSG << "\n + [BAD FILE] no value for RED\n";
        pdout.clear();
        return false;
    }

    if( !ParseReal( pdout, idx, green, eor, pd, rd ) )
    {
        ERRMSG << "\n + [BAD FILE] no value for RED\n";
        pdout.clear();
        return false;
    }

    if( !ParseReal( pdout, idx, blue, eor, pd, rd ) )
    {
        ERRMSG << "\n + [BAD FILE] no value for RED\n";
        pdout.clear();
        return false;
    }

    if( !eor && !ParseHString( pdout, idx, cname, eor, pd, rd ) )
    {
        ERRMSG << "\n + [BAD FILE] problems encountered while parsing color name\n";
        pdout.clear();
        return false;
    }

    if( red < 0.0 || red > 100.0 )
    {
        ERRMSG << "\n + [INFO] invalid value for RED (" << red << ")\n";
        red = 85.0;
    }

    if( green < 0.0 || green > 100.0 )
    {
        ERRMSG << "\n + [INFO] invalid value for GREEN (" << green << ")\n";
        green = 20.0;
    }

    if( blue < 0.0 || blue > 100.0 )
    {
        ERRMSG << "\n + [INFO] invalid value for BLUE (" << blue << ")\n";
        blue = 20.0;
    }

    if( cname.empty() )
        cname = "none";

    if( !eor && !readExtraParams( idx ) )
    {
        ERRMSG << "\n + [BAD FILE] could not read optional pointers\n";
        pdout.clear();
        return false;
    }

    if( !readComments( idx ) )
    {
        ERRMSG << "\n + [BAD FILE] could not read extra comments\n";
        pdout.clear();
        return false;
    }

    pdout.clear();
    return true;
}

bool IGES_ENTITY_314::SetEntityForm( int aForm )
{
    if( aForm != 0 )
    {
        ERRMSG << "\n + [WARNING] [BUG] Color Definition Entity only supports Form 0 (requested form: ";
        cerr << aForm << ")\n";
    }

    return true;
}

bool IGES_ENTITY_314::SetDependency( IGES_STAT_DEPENDS aDependency )
{
    if( aDependency != 0 )
    {
        ERRMSG << "\n + [WARNING] [BUG] Color Definition Entity only supports STAT_INDEPENDENT\n";
    }

    return true;
}

bool IGES_ENTITY_314::SetEntityUse( IGES_STAT_USE aUseCase )
{
    if( aUseCase != 2 )
    {
        ERRMSG << "\n + [WARNING] [BUG] Color Definition Entity only supports STAT_USE_DEFINITION\n";
    }

    return true;
}

bool IGES_ENTITY_314::SetHierarchy( IGES_STAT_HIER aHierarchy )
{
    // value ignored
    ERRMSG << "\n + [WARNING] [BUG] Color Definition Entity does not support hierarchy\n";
    return true;
}

bool IGES_ENTITY_314::SetLineFontPattern( IGES_LINEFONT_PATTERN aPattern )
{
    ERRMSG << "\n + [WARNING] [BUG] Color Definition Entity does not support Line Font Pattern\n";
    return true;
}

bool IGES_ENTITY_314::SetLineFontPattern( IGES_ENTITY* aPattern )
{
    ERRMSG << "\n + [WARNING] [BUG] Color Definition Entity does not support Line Font Pattern\n";
    return true;
}

bool IGES_ENTITY_314::SetLevel( int aLevel )
{
    ERRMSG << "\n + [WARNING] [BUG] Color Definition Entity does not support Level\n";
    return true;
}

bool IGES_ENTITY_314::SetLevel( IGES_ENTITY* aLevel )
{
    ERRMSG << "\n + [WARNING] [BUG] Color Definition Entity does not support Level\n";
    return true;
}

bool IGES_ENTITY_314::SetView( IGES_ENTITY* aView )
{
    ERRMSG << "\n + [WARNING] [BUG] Color Definition Entity does not support View\n";
    return true;
}

bool IGES_ENTITY_314::SetTransform( IGES_ENTITY* aTransform )
{
    ERRMSG << "\n + [WARNING] [BUG] Color Definition Entity does not support Transform\n";
    return true;
}

bool IGES_ENTITY_314::SetLabelAssoc( IGES_ENTITY* aLabelAssoc )
{
    ERRMSG << "\n + [WARNING] [BUG] Color Definition Entity does not support Label Associativity\n";
    return true;
}

bool IGES_ENTITY_314::SetColor( IGES_COLOR aColor )
{
    if( aColor > COLOR_NONE && aColor < COLOR_END )
    {
        colorNum = aColor;
        return true;
    }

    ERRMSG << "\n + [WARNING] [BUG] Color Number must be one of 1 .. 8\n";
    return false;
}

bool IGES_ENTITY_314::SetColor( IGES_ENTITY* aColor )
{
    ERRMSG << "\n + [WARNING] [BUG] Color Definition Entity does not support child Color Definition Entity\n";
    return true;
}

bool IGES_ENTITY_314::SetVisibility(bool isVisible)
{
    ERRMSG << "\n + [WARNING] [BUG] Color Definition Entity does not support Blank Status (visibility)\n";
    return true;
}

bool IGES_ENTITY_314::SetLineWeightNum( int aLineWeight )
{
    ERRMSG << "\n + [WARNING] [BUG] Color Definition Entity does not support Line Weight\n";
    return true;
}
<|endoftext|>