///////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////
//
//
// Transformation
//
//
///////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////
void colorTransform::checkColorSpaces(const std::wstring& inputHandlerColorSpace, const std::wstring& outputHandlerColorSpace)
{
	PUNTOEXE_FUNCTION_START(L"colorTransform::runTransform");

	if(inputHandlerColorSpace != getInitialColorSpace())
	{
		PUNTOEXE_THROW(colorTransformExceptionWrongColorSpace, "The image's color space cannot be handled by the transform");
	}

	if(outputHandlerColorSpace != getFinalColorSpace())
	{
		PUNTOEXE_THROW(colorTransformExceptionWrongColorSpace, "The image's color space cannot be handled by the transform");
	}

	PUNTOEXE_FUNCTION_END();
}
///////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////
//
//
// Set the charset used in the tag
//
//
///////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////
void dataHandlerStringUnicode::setCharsetsList(charsetsList::tCharsetsList* pCharsetsList)
{
	PUNTOEXE_FUNCTION_START(L"dataHandlerStringUnicode::setCharsetInfo");

	// Copy the specified charsets into the tag
	///////////////////////////////////////////////////////////
	m_charsetsList.clear();
	charsetsList::updateCharsets(pCharsetsList, &m_charsetsList);

	// If no charset has been defined then we use the default 
	//  one
	///////////////////////////////////////////////////////////
	if(m_charsetsList.empty())
	{
		m_charsetsList.push_back(m_dicomCharsets[0].m_dicomName);
	}

	// Check for the dicom charset's name
	///////////////////////////////////////////////////////////
	dicomCharsetInformation* pCharset = getCharsetInfo(m_charsetsList.front());
	if(pCharset == 0 || pCharset->m_isoRegistration.empty())
	{
		PUNTOEXE_THROW(dataHandlerStringUnicodeExceptionUnknownCharset, "Unknown charset");
	}

	// Setup the conversion objects
	///////////////////////////////////////////////////////////
    m_charsetConversion->initialize(pCharset->m_isoRegistration);
    m_localeCharsetConversion->initialize("LOCALE");

	PUNTOEXE_FUNCTION_END();
}
Example #3
0
///////////////////////////////////////////////////////////
//
// Initialize the charsetConversion object
//
///////////////////////////////////////////////////////////
void charsetConversion::initialize(const std::string& tableName)
{
	PUNTOEXE_FUNCTION_START(L"charsetConversion::initialize");

	// Find the table ID
	///////////////////////////////////////////////////////////
	int requestedTable = findTable(tableName);
	if(requestedTable == -1)
	{
		close();
		PUNTOEXE_THROW(charsetConversionExceptionNoTable, "The requested ISO table doesn't exist");
	}

	// The specified table is already active. Simply return
	///////////////////////////////////////////////////////////
	if(m_charsetTable[requestedTable].m_isoRegistration == m_isoCharset)
	{
		return;
	}

	// Close the active table
	///////////////////////////////////////////////////////////
	close();

	// Save the name of the active table
	///////////////////////////////////////////////////////////
	m_isoCharset = m_charsetTable[requestedTable].m_isoRegistration;

    initialize(requestedTable);

	PUNTOEXE_FUNCTION_END();
}
///////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////
//
//
// Try to lock a critical section
//
//
///////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////
bool criticalSection::tryLock()
{

#ifdef PUNTOEXE_WINDOWS // WINDOWS
	return TryEnterCriticalSection(&m_criticalSection) != 0;

#else // POSIX

	PUNTOEXE_FUNCTION_START(L"criticalSection::tryLock");

	int tryLockResult = pthread_mutex_trylock(&m_criticalSection);
	if(tryLockResult == 0)
	{
		return true;
	}
	if(tryLockResult == EBUSY)
	{
		return false;
	}
	PUNTOEXE_THROW(posixMutexException, "A mutex is in an error state");

	PUNTOEXE_FUNCTION_END();
#endif

}
///////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////
//
//
// Read an Huffman code
//
//
///////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////
imbxUint32 huffmanTable::readHuffmanCode(streamReader* pStream)
{
	PUNTOEXE_FUNCTION_START(L"huffmanTable::readHuffmanCode");

	// Read initial number of bits
	imbxUint32 readBuffer(pStream->readBits(m_firstValidLength));

	// Validate the current Huffman code. If it's OK, then
	//  return the ordered value
	///////////////////////////////////////////////////////////
	if(readBuffer<=m_maxValuePerLength[m_firstValidLength])
	{
		return m_orderedValues[readBuffer - m_minValuePerLength[m_firstValidLength]];
	}

	imbxUint32 orderedValue(m_valuesPerLength[m_firstValidLength]);

	// Scan all the codes sizes
	///////////////////////////////////////////////////////////
	for(imbxUint8 scanSize(m_firstValidLength + 1), missingBits(0); scanSize != sizeof(m_valuesPerLength)/sizeof(m_valuesPerLength[0]); ++scanSize)
	{
		++missingBits;

		// If the active length is empty, then continue the loop
		///////////////////////////////////////////////////////////
		if(m_valuesPerLength[scanSize] == 0)
		{
			continue;
		}

		readBuffer <<= missingBits;
		if(missingBits == 1)
		{
			readBuffer |= pStream->readBit();
		}
		else
		{
			readBuffer |= pStream->readBits(missingBits);
		}

		// Validate the current Huffman code. If it's OK, then
		//  return the ordered value
		///////////////////////////////////////////////////////////
		if(readBuffer<=m_maxValuePerLength[scanSize])
		{
			return m_orderedValues[orderedValue + readBuffer - m_minValuePerLength[scanSize]];
		}

		orderedValue += m_valuesPerLength[scanSize];

		// Reset the number of bits to read in one go
		///////////////////////////////////////////////////////////
		missingBits = 0;

	}

	PUNTOEXE_THROW(huffmanExceptionRead, "Invalid huffman code found while reading from a stream");

	PUNTOEXE_FUNCTION_END();
}
///////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////
//
//
// Write an Huffman code
//
//
///////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////
void huffmanTable::writeHuffmanCode(const imbxUint32 code, streamWriter* pStream)
{
	PUNTOEXE_FUNCTION_START(L"huffmanTable::writeHuffmanCode");

	if(m_valuesToHuffmanLength[code] == 0)
	{
		PUNTOEXE_THROW(huffmanExceptionWrite, "Trying to write an invalid huffman code");
	}
	pStream->writeBits(m_valuesToHuffman[code], m_valuesToHuffmanLength[code]);

	PUNTOEXE_FUNCTION_END();
}
Example #7
0
///////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////
//
//
// Load the data from the specified stream and build a
//  dicomSet structure
//
//
///////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////
ptr<dataSet> codecFactory::load(ptr<streamReader> pStream, std::uint32_t maxSizeBufferLoad /* = 0xffffffff */)
{
	PUNTOEXE_FUNCTION_START(L"codecFactory::load");

	// Copy the list of codecs in a local list so we don't have
	//  to lock the object for a long time
	///////////////////////////////////////////////////////////
	std::list<ptr<codec> > localCodecsList;
	ptr<codecFactory> pFactory(getCodecFactory());
	{
		lockObject lockAccess(pFactory.get());
		for(std::list<ptr<codec> >::iterator scanCodecs=pFactory->m_codecsList.begin(); scanCodecs!=pFactory->m_codecsList.end(); ++scanCodecs)
		{
			ptr<codec> copyCodec((*scanCodecs)->createCodec());
			localCodecsList.push_back(copyCodec);
		}
	}

	ptr<dataSet> pDataSet;
	for(std::list<ptr<codec> >::iterator scanCodecs=localCodecsList.begin(); scanCodecs != localCodecsList.end() && pDataSet == 0; ++scanCodecs)
	{
		try
		{
			return (*scanCodecs)->read(pStream, maxSizeBufferLoad);
		}
		catch(codecExceptionWrongFormat& /* e */)
		{
			exceptionsManager::getMessage(); // Reset the messages stack
			continue;
		}
	}

	if(pDataSet == 0)
	{
		PUNTOEXE_THROW(codecExceptionWrongFormat, "none of the codecs recognized the file format");
	}

	return pDataSet;

	PUNTOEXE_FUNCTION_END();
}
Example #8
0
///////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////
//
//
// Remove a transaction from the transactions stack
//
//
///////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////
void transactionsManager::removeTransaction(std::thread::id threadId)
{
	PUNTOEXE_FUNCTION_START(L"transactionsManager::removeTransaction");

	// Retrieve the transactions manager and lock it
	///////////////////////////////////////////////////////////
	transactionsManager* pManager = getTransactionsManager();
	lockObject lockThis(pManager->m_lockObject.get());

	// Find the thread's transactions stack
	///////////////////////////////////////////////////////////
	tTransactionsMap::iterator findThread = pManager->m_transactions.find(threadId);
	if(findThread == pManager->m_transactions.end())
	{
		PUNTOEXE_THROW(std::logic_error, "Transaction not found in the transactions stack");
	}

	// Pop the last transaction in the stack
	///////////////////////////////////////////////////////////
	transaction* pLastTransaction = findThread->second.back(); // This throw if the stack is empty. It's OK
	findThread->second.pop_back();

	// If there are no parent transactions then return
	///////////////////////////////////////////////////////////
	if(findThread->second.empty())
	{
		pManager->m_transactions.erase(findThread);
		return;
	}

	// If there is a parent transaction then copy there the 
	//  dataHandlers from the removed transaction
	///////////////////////////////////////////////////////////
	transaction* pParentTransaction = findThread->second.back();
	pLastTransaction->copyHandlersTo(pParentTransaction);

	PUNTOEXE_FUNCTION_END();
}
Example #9
0
///////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////
//
//
// Copy the charsets in the list into the local list.
// An exception is thrown if a mismatch in the default
//  charset is detected
//
//
///////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////
void updateCharsets(const tCharsetsList* pCharsetsList, tCharsetsList* pDestinationCharsetsList)
{
	PUNTOEXE_FUNCTION_START(L"charsetsList::updateCharsets");

	// Check the default charset
	///////////////////////////////////////////////////////////
	if(!pCharsetsList->empty() && !pDestinationCharsetsList->empty() && pCharsetsList->front() != pDestinationCharsetsList->front())
	{
		PUNTOEXE_THROW(charsetListExceptionDiffDefault, "Different default charsets");
	}

	// Copy the charsets in the local list (if they are not
	//  already there)
	///////////////////////////////////////////////////////////
	for(tCharsetsList::const_iterator scanCharsets = pCharsetsList->begin(); scanCharsets != pCharsetsList->end(); ++scanCharsets)
	{
        std::string charsetName(*scanCharsets);
        if(charsetName.empty())
        {
            charsetName = "ISO 2022 IR 6";
        }
		bool bExist = false;
		for(tCharsetsList::iterator scanExistingCharsets = pDestinationCharsetsList->begin(); scanExistingCharsets != pDestinationCharsetsList->end(); ++scanExistingCharsets)
		{
            if(charsetName == *scanExistingCharsets)
			{
				bExist = true;
				break;
			}
		}
		if(!bExist)
		{
            pDestinationCharsetsList->push_back(charsetName);
		}
	}

	PUNTOEXE_FUNCTION_END();
}
Example #10
0
///////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////
//
//
// Create a data handler and connect it to the buffer
// (raw or normal)
//
//
///////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////
ptr<handlers::dataHandler> buffer::getDataHandler(bool bWrite, bool bRaw, imbxUint32 size)
{
	PUNTOEXE_FUNCTION_START(L"buffer::getDataHandler");

	// Lock the object
	///////////////////////////////////////////////////////////
	lockObject lockAccess(this);

	ptr<memory> localMemory(m_memory);

	// If the object must be loaded from the original stream,
	//  then load it...
	///////////////////////////////////////////////////////////
	if(m_originalStream != 0 && (localMemory == 0 || localMemory->empty()) )
	{
		localMemory = ptr<memory>(memoryPool::getMemoryPool()->getMemory(m_originalBufferLength));
		if(m_originalBufferLength != 0)
		{
			ptr<streamReader> reader(new streamReader(m_originalStream, m_originalBufferPosition, m_originalBufferLength));
			std::vector<imbxUint8> localBuffer;
			localBuffer.resize(m_originalBufferLength);
			reader->read(&localBuffer[0], m_originalBufferLength);
			if(m_originalWordLength != 0)
			{
				reader->adjustEndian(&localBuffer[0], m_originalWordLength, m_originalEndianType, m_originalBufferLength/m_originalWordLength);
			}
			localMemory->assign(&localBuffer[0], m_originalBufferLength);
		}
	}

	// Reset the pointer to the data handler
	///////////////////////////////////////////////////////////
	ptr<handlers::dataHandler> handler;

	// Allocate a raw data handler if bRaw==true
	///////////////////////////////////////////////////////////
	if(bRaw)
	{
		ptr<handlers::dataHandler> tempHandler(new handlers::dataHandlerRaw);
		handler = tempHandler;
	}
	else
	{
		// Retrieve an Application entity handler
		///////////////////////////////////////////////////////////
		if(m_bufferType=="AE")
		{
			ptr<handlers::dataHandler> tempHandler(new handlers::dataHandlerStringAE);
			handler = tempHandler;
		}

		// Retrieve an Age string data handler
		///////////////////////////////////////////////////////////
		if(m_bufferType=="AS")
		{
			ptr<handlers::dataHandler> tempHandler(new handlers::dataHandlerStringAS);
			handler = tempHandler;
		}

		// Retrieve a Code string data handler
		///////////////////////////////////////////////////////////
		if(m_bufferType=="CS")
		{
			ptr<handlers::dataHandler> tempHandler(new handlers::dataHandlerStringCS);
			handler = tempHandler;
		}

		// Retrieve a Decimal string data handler
		///////////////////////////////////////////////////////////
		if(m_bufferType=="DS")
		{
			ptr<handlers::dataHandler> tempHandler(new handlers::dataHandlerStringDS);
			handler = tempHandler;
		}

		// Retrieve an Integer string data handler
		///////////////////////////////////////////////////////////
		if(m_bufferType=="IS")
		{
			ptr<handlers::dataHandler> tempHandler(new handlers::dataHandlerStringIS);
			handler = tempHandler;
		}

		// Retrieve a Long string data handler
		///////////////////////////////////////////////////////////
		if(m_bufferType=="LO")
		{
			ptr<handlers::dataHandler> tempHandler(new handlers::dataHandlerStringLO);
			handler = tempHandler;
		}

		// Retrieve a Long text data handler
		///////////////////////////////////////////////////////////
		if(m_bufferType=="LT")
		{
			ptr<handlers::dataHandler> tempHandler(new handlers::dataHandlerStringLT);
			handler = tempHandler;
		}

		// Retrieve a Person Name data handler
		///////////////////////////////////////////////////////////
		if(m_bufferType=="PN")
		{
			ptr<handlers::dataHandler> tempHandler(new handlers::dataHandlerStringPN);
			handler = tempHandler;
		}

		// Retrieve a Short string data handler
		///////////////////////////////////////////////////////////
		if(m_bufferType=="SH")
		{
			ptr<handlers::dataHandler> tempHandler(new handlers::dataHandlerStringSH);
			handler = tempHandler;
		}

		// Retrieve a Short text data handler
		///////////////////////////////////////////////////////////
		if(m_bufferType=="ST")
		{
			ptr<handlers::dataHandler> tempHandler(new handlers::dataHandlerStringST);
			handler = tempHandler;
		}

		// Retrieve an Unique Identifier data handler
		///////////////////////////////////////////////////////////
		if(m_bufferType=="UI")
		{
			ptr<handlers::dataHandler> tempHandler(new handlers::dataHandlerStringUI);
			handler = tempHandler;
		}

		// Retrieve an Unlimited text data handler
		///////////////////////////////////////////////////////////
		if(m_bufferType=="UT")
		{
			ptr<handlers::dataHandler> tempHandler(new handlers::dataHandlerStringUT);
			handler = tempHandler;
		}

		// Retrieve an object handler
		///////////////////////////////////////////////////////////
		if(m_bufferType=="OB")
		{
			ptr<handlers::dataHandler> tempHandler(new handlers::dataHandlerNumeric<imbxUint8>);
			handler = tempHandler;
		}

		// Retrieve a signed-byte object handler.
		// Non standard: used by the images handler.
		///////////////////////////////////////////////////////////
		if(m_bufferType=="SB")
		{
			ptr<handlers::dataHandler> tempHandler(new handlers::dataHandlerNumeric<imbxInt8>);
			handler = tempHandler;
		}

		// Retrieve an unknown object handler
		///////////////////////////////////////////////////////////
		if(m_bufferType=="UN")
		{
			ptr<handlers::dataHandler> tempHandler(new handlers::dataHandlerNumeric<imbxUint8>);
			handler = tempHandler;
		}

		// Retrieve a WORD handler
		///////////////////////////////////////////////////////////
		if(m_bufferType=="OW")
		{
			ptr<handlers::dataHandler> tempHandler(new handlers::dataHandlerNumeric<imbxUint16>);
			handler = tempHandler;
		}

		// Retrieve a WORD handler (AT)
		///////////////////////////////////////////////////////////
		if(m_bufferType=="AT")
		{
			ptr<handlers::dataHandler> tempHandler(new handlers::dataHandlerNumeric<imbxUint16>);
			handler = tempHandler;
		}

		// Retrieve a float handler
		///////////////////////////////////////////////////////////
		if(m_bufferType=="FL")
		{
			ptr<handlers::dataHandler> tempHandler(new handlers::dataHandlerNumeric<float>);
			handler = tempHandler;
		}

		// Retrieve a double float handler
		///////////////////////////////////////////////////////////
		if(m_bufferType=="FD")
		{
			ptr<handlers::dataHandler> tempHandler(new handlers::dataHandlerNumeric<double>);
			handler = tempHandler;
		}

		// Retrieve a signed long handler
		///////////////////////////////////////////////////////////
		if(m_bufferType=="SL")
		{
			ptr<handlers::dataHandler> tempHandler(new handlers::dataHandlerNumeric<imbxInt32>);
			handler = tempHandler;
		}

		// Retrieve a signed short handler
		///////////////////////////////////////////////////////////
		if(m_bufferType=="SS")
		{
			ptr<handlers::dataHandler> tempHandler(new handlers::dataHandlerNumeric<imbxInt16>);
			handler = tempHandler;
		}

		// Retrieve an unsigned long handler
		///////////////////////////////////////////////////////////
		if(m_bufferType=="UL")
		{
			ptr<handlers::dataHandler> tempHandler(new handlers::dataHandlerNumeric<imbxUint32>);
			handler = tempHandler;
		}

		// Retrieve an unsigned short handler
		///////////////////////////////////////////////////////////
		if(m_bufferType=="US")
		{
			ptr<handlers::dataHandler> tempHandler(new handlers::dataHandlerNumeric<imbxUint16>);
			handler = tempHandler;
		}

		// Retrieve date
		///////////////////////////////////////////////////////////
		if(m_bufferType=="DA")
		{
			ptr<handlers::dataHandler> tempHandler(new handlers::dataHandlerDate);
			handler = tempHandler;
		}

		// Retrieve date-time
		///////////////////////////////////////////////////////////
		if(m_bufferType=="DT")
		{
			ptr<handlers::dataHandler> tempHandler(new handlers::dataHandlerDateTime);
			handler = tempHandler;
		}

		// Retrieve time
		///////////////////////////////////////////////////////////
		if(m_bufferType=="TM")
		{
			ptr<handlers::dataHandler> tempHandler(new handlers::dataHandlerTime);
			handler = tempHandler;
		}

	} // check bRaw

	// If an error occurred during the data handler creation,
	//  then throw an exception
	///////////////////////////////////////////////////////////
	if(handler == 0)
	{
		PUNTOEXE_THROW(bufferExceptionUnknownType, "Unknown data type requested");
	}

	//  Connect the handler to this buffer
	///////////////////////////////////////////////////////////
	if(localMemory == 0)
	{
		localMemory = ptr<memory>(new memory);
	}
	ptr<memory> parseMemory(localMemory);

	// Set the handler's attributes
	///////////////////////////////////////////////////////////
	if(bWrite)
	{
		ptr<buffer> tempBuffer(this);
		handler->m_buffer = tempBuffer;

		imbxUint32 actualMemorySize = localMemory->size();
		imbxUint32 newMemorySize = actualMemorySize;
		if(newMemorySize == 0)
		{
			newMemorySize = size * handler->getUnitSize();
		}
		ptr<memory> newMemoryBuffer(memoryPool::getMemoryPool()->getMemory(newMemorySize));
		if(actualMemorySize != 0)
		{
			newMemoryBuffer->copyFrom(localMemory);
		}
		parseMemory = newMemoryBuffer;

		// Add writing handlers to the current transaction
		///////////////////////////////////////////////////////////
		transactionsManager::addHandlerToTransaction(handler);
	}

	handler->m_bufferType = m_bufferType;
	handler->setCharsetsList(&m_charsetsList);
	handler->parseBuffer(parseMemory);

	// Rewind the data pointer
	///////////////////////////////////////////////////////////
	if(handler->getSize() != 0)
	{
		handler->setPointer(0);
	}

	// Return the allocated handler
	///////////////////////////////////////////////////////////
	return handler;

	PUNTOEXE_FUNCTION_END();
}
Example #11
0
///////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////
//
//
// Transformation
//
//
///////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////
void colorTransform::doTransform()
{
	PUNTOEXE_FUNCTION_START(L"colorTransform::doTransform");

	// Process all the input images
	///////////////////////////////////////////////////////////
	for(int scanImages = 0; ; ++scanImages)
	{
		// Get the input image
		///////////////////////////////////////////////////////////
		ptr<image> pInputImage=getInputImage(scanImages);

		// If the input image doesn't exist, then exit
		///////////////////////////////////////////////////////////
		if(pInputImage == 0)
			break;

		// Check the input color space
		///////////////////////////////////////////////////////////
		if(pInputImage->getColorSpace()!=getInitialColorSpace())
		{
			PUNTOEXE_THROW(colorTransformExceptionWrongColorSpace, "the image's color space cannot be handled by the transform");
		}

		// Get the output image
		///////////////////////////////////////////////////////////
		ptr<image> pOutputImage=getOutputImage(scanImages);
		if(pOutputImage == 0)
		{
			ptr<image> tempImage(new image);
			pOutputImage=tempImage;
			declareOutputImage(scanImages, pOutputImage);
		}

		// Get the input image's attributes and the data handler
		///////////////////////////////////////////////////////////
		imbxUint32 sizeX, sizeY;
		pInputImage->getSize(&sizeX, &sizeY);

		double sizeMmX, sizeMmY;
		pInputImage->getSizeMm(&sizeMmX, &sizeMmY);
		pOutputImage->setSizeMm(sizeMmX, sizeMmY);

		image::bitDepth inputDepth=pInputImage->getDepth();
		image::bitDepth outputDepth=inputDepth;
		imbxUint32  highBit=pInputImage->getHighBit();
		imbxUint32 totalPixelsNumber=sizeX*sizeY;
		
		imbxInt32 inputMinValue = 0;
		imbxInt32 inputMaxValue = (1L<<(highBit+1))-1L;
		imbxInt32 outputMinValue = inputMinValue;
		imbxInt32 outputMaxValue = inputMaxValue;

		if(inputDepth==image::depthS8 || inputDepth==image::depthS16)
		{
			inputMinValue-=1L<<highBit;
			inputMaxValue-=1L<<highBit;

			std::wstring outputColorSpace = getFinalColorSpace();
			if(outputColorSpace == L"MONOCHROME2" || outputColorSpace == L"MONOCHROME1")
			{
				outputMinValue-=1L<<highBit;
				outputMaxValue-=1L<<highBit;
			}
			else
			{
				if(inputDepth==image::depthS8)
					outputDepth = image::depthU8;
				if(inputDepth==image::depthS16)
					outputDepth = image::depthU16;
			}
		}

		// Get the data handler for the input and the output
		//  images
		///////////////////////////////////////////////////////////
		imbxUint32 rowSize, channelPixelSize, channelsNumber;
		ptr<handlers::imageHandler> pInputDataHandler = pInputImage->getDataHandler(false, &rowSize, &channelPixelSize, &channelsNumber);
		if(pInputDataHandler->getSize() < totalPixelsNumber * channelsNumber)
		{
			PUNTOEXE_THROW(colorTransformExceptionWrongColorSpace, "the input image's size doesn't match the requested size");
		}
		
		ptr<handlers::imageHandler> pOutputDataHandler = pOutputImage->create(sizeX, sizeY, outputDepth, getFinalColorSpace(), (imbxUint8)highBit);
		channelsNumber = pOutputImage->getChannelsNumber();
		if(pOutputDataHandler->getSize() < totalPixelsNumber * channelsNumber)
		{
			PUNTOEXE_THROW(colorTransformExceptionWrongColorSpace, "the output image's size doesn't match the requested size");
		}

		doColorTransform(pInputDataHandler->getMemoryBuffer(), pOutputDataHandler->getMemoryBuffer(), totalPixelsNumber, inputMinValue, inputMaxValue, outputMinValue, outputMaxValue);
	}
	
	PUNTOEXE_FUNCTION_END();
}
///////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////
//
//
// Create an image with the specified size, colorspace and
//  bit depth
//
//
///////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////
ptr<handlers::dataHandlerNumericBase> image::create(
						const imbxUint32 sizeX, 
						const imbxUint32 sizeY, 
						const bitDepth depth, 
						std::wstring inputColorSpace, 
						const imbxUint8 highBit)
{
	PUNTOEXE_FUNCTION_START(L"image::create");

	lockObject lockAccess(this);

	if(sizeX == 0 || sizeY == 0)
	{
		PUNTOEXE_THROW(imageExceptionInvalidSize, "An invalid image's size has been specified");
	}

	// Normalize the color space (remove _420 & _422 and
	//  make it uppercase).
	///////////////////////////////////////////////////////////
	m_colorSpace=transforms::colorTransforms::colorTransformsFactory::normalizeColorSpace(inputColorSpace);

	// Find the number of channels to allocate
	///////////////////////////////////////////////////////////
	m_channelsNumber = transforms::colorTransforms::colorTransformsFactory::getNumberOfChannels(inputColorSpace);
	if(m_channelsNumber == 0)
	{
		PUNTOEXE_THROW(imageExceptionUnknownColorSpace, "Cannot recognize the specified color space");
	}

	// Find the datatype to use to allocate the
	//  buffer (datatypes are in Dicom standard, plus SB
	//  for signed bytes).
	///////////////////////////////////////////////////////////
	m_channelPixelSize = 0;
	imbxUint8 defaultHighBit = 0;

	std::string bufferDataType;

	switch(depth)
	{
	case depthU8:
		bufferDataType = "OB";
		defaultHighBit=7;
		break;
	case depthS8:
		bufferDataType = "SB";
		defaultHighBit=7;
		break;
	case depthU16:
		bufferDataType = "US";
		defaultHighBit=15;
		break;
	case depthS16:
		bufferDataType = "SS";
		defaultHighBit=15;
		break;
	case depthU32:
		bufferDataType = "UL";
		defaultHighBit=31;
		break;
	case depthS32:
		bufferDataType = "SL";
		defaultHighBit=31;
		break;
	default:
		PUNTOEXE_THROW(imageExceptionUnknownDepth, "Unknown depth");
	}

	// Adjust the high bit value
	///////////////////////////////////////////////////////////
	if(highBit == 0 || highBit>defaultHighBit)
		m_highBit=defaultHighBit;
	else
		m_highBit=highBit;

	// If a valid buffer with the same data type is already
	//  allocated then use it.
	///////////////////////////////////////////////////////////
	if(m_buffer == 0 || !(m_buffer->isReferencedOnce()) )
	{
		ptr<buffer> tempBuffer(new buffer(this, bufferDataType));
		m_buffer = tempBuffer;
	}

	m_sizeX = m_sizeY = 0;
	
	ptr<handlers::dataHandler> imageHandler(m_buffer->getDataHandler(true, sizeX * sizeY * (imbxUint32)m_channelsNumber) );
	if(imageHandler != 0)
	{
		m_rowLength = m_channelsNumber*sizeX;
		
		imageHandler->setSize(m_rowLength*sizeY);
		m_channelPixelSize = imageHandler->getUnitSize();

		// Set the attributes
		///////////////////////////////////////////////////////////
		m_imageDepth=depth;
		m_sizeX=sizeX;
		m_sizeY=sizeY;
	}

	return ptr<handlers::dataHandlerNumericBase>(dynamic_cast<handlers::dataHandlerNumericBase*>(imageHandler.get()) );

	PUNTOEXE_FUNCTION_END();
}