Exemplo n.º 1
0
bool CxImageIG::decodeSubLayer (CxFile& file, IGLibrary::IGLayer *pSubLayerOwner, IGSECTIONHEADER_LAYER *pLayerSection)
{
	CxImage cxSubLayer;
	if (!file.Seek (pLayerSection->commonHeader.nFirstByteOffset, SEEK_SET))
		throw IGEXCEPTION (CxImageIGException, "decodeSubLayer", "file.Seek failed");
	// read sub-layer pixels
	BYTE *pBufImg = new BYTE [pLayerSection->commonHeader.nSizeBuf];
	file.Read (pBufImg, pLayerSection->commonHeader.nSizeBuf, 1);
	if (!cxSubLayer.Decode (pBufImg, pLayerSection->commonHeader.nSizeBuf, CXIMAGEIG_LAYERFORMAT))
		throw IGEXCEPTION (CxImageIGException, "decodeSubLayer", "cxSubLayer.Decode failed");
	delete [] pBufImg;
	// read sub-layer alpha
	cxSubLayer.AlphaCreate (255);
	file.Read (cxSubLayer.pAlpha, cxSubLayer.GetWidth() * cxSubLayer.GetHeight(), 1);
	// decode sub-layer into layer
	BYTE *pLayerBits = NULL;
	BYTE *pSubLayerBits = NULL;
	for (int i = 0; i < pLayerSection->ptSize.y; i++)
	{
		pSubLayerBits = cxSubLayer.GetBits (i);
		pLayerBits = pSubLayerOwner->GetBits (pLayerSection->ptOffset.y + i) + 3 * pLayerSection->ptOffset.x;
		::memcpy (pLayerBits, pSubLayerBits, (pLayerSection->ptSize.x) * 3);			
	}
	BYTE *pLayerAlpha = NULL;
	BYTE *pSubLayerAlpha = NULL;
	for (int i = 0; i < (pLayerSection->ptSize.y); i++)
	{
		pLayerAlpha = pSubLayerOwner->AlphaGetPointer (pLayerSection->ptOffset.x, pLayerSection->ptOffset.y + i);
		pSubLayerAlpha = cxSubLayer.AlphaGetPointer (0, i);	
		::memcpy (pLayerAlpha, pSubLayerAlpha, (pLayerSection->ptSize.x));
	}
	return true;
}
Exemplo n.º 2
0
bool CxImageIG::DecodeLayer (CxFile &file, int nLayerIdx, int nLayerPos, RECT *p_rcSubLayer, bool bUndo, int nSubLayerId)
{	
	// read current header
	IGHEADER igHeader;
	if (!decodeHeader (&file, &igHeader))
		throw IGEXCEPTION (CxImageIGException, "DecodeLayer", "decodeHeader failed");
	if (nLayerIdx < 0)
		throw IGEXCEPTION (CxImageIGException, "DecodeLayer", "nLayerIdx failed");
	if ((nLayerPos < 0) || (nLayerPos >= info.nNumLayers))
		throw IGEXCEPTION (CxImageIGException, "DecodeLayer", "nLayerPos failed");

	IGSECTIONHEADER_LAYER *pLayerSections = new IGSECTIONHEADER_LAYER [CXIMAGEIG_MAX_NBLAYERS];
	IGSECTIONHEADER_SELECTION *pSelectionSections  = new IGSECTIONHEADER_SELECTION [CXIMAGEIG_MAX_NBSELECTIONS];
	if (!decodeSections (&file, &igHeader, &pLayerSections[0], &pSelectionSections[0]))
		throw IGEXCEPTION (CxImageIGException, "DecodeLayer", "decodeSections failed");

	IGLibrary::IGLayer *pLayer = GetLayer (nLayerPos);
	if (!pLayer)
		throw IGEXCEPTION (CxImageIGException, "DecodeLayer", "GetLayer failed");
	CxImage cxSubLayer;
	CxImage *pDecodingLayer = p_rcSubLayer ? &cxSubLayer : pLayer;
	bool bIsSubLayerOwner = bUndo && p_rcSubLayer; // no need to find sub-layer owner in do mode
	int nLayerSectionIndex = findLayerSectionIndex (&igHeader, pLayerSections, nLayerIdx, bIsSubLayerOwner);
	if ((nLayerSectionIndex < 0) || (nLayerSectionIndex >= igHeader.nNbLayers))
		throw IGEXCEPTION (CxImageIGException, "DecodeLayer", "findLayerSectionIndex failed");

	// in undo mode, if a sub-layer owner is found, decode it
	if (bUndo){
		if (bIsSubLayerOwner)
		{
			// decode sub-layer owner
			if (!DecodeLayer (file, pLayerSections [nLayerSectionIndex].commonHeader.nId, nLayerPos))
				throw IGEXCEPTION (CxImageIGException, "DecodeLayer", "DecodeLayer failed");
			// decode sub-layers
			int nSubLayerSectionIndex = findLayerSectionIndex (&igHeader, pLayerSections, nLayerIdx, bIsSubLayerOwner);
			if ((nSubLayerSectionIndex < 0) || (nSubLayerSectionIndex >= igHeader.nNbLayers))
				throw IGEXCEPTION (CxImageIGException, "DecodeLayer", "findLayerSectionIndex failed");
			RECT rcSubLayer;
			rcSubLayer.left = pLayerSections[nSubLayerSectionIndex].ptOffset.x;
			rcSubLayer.right = pLayerSections[nSubLayerSectionIndex].ptOffset.x + pLayerSections[nSubLayerSectionIndex].ptSize.x - 1;
			rcSubLayer.top = pLayerSections[nSubLayerSectionIndex].ptOffset.y;
			rcSubLayer.bottom = pLayerSections[nSubLayerSectionIndex].ptOffset.y + pLayerSections[nSubLayerSectionIndex].ptSize.y - 1;
			return DecodeLayer (file, pLayerSections [nLayerSectionIndex].commonHeader.nId, nLayerPos, &rcSubLayer, true, nLayerIdx);
		}
	}

	if (!file.Seek (pLayerSections [nLayerSectionIndex].commonHeader.nFirstByteOffset, SEEK_SET))
		throw IGEXCEPTION (CxImageIGException, "DecodeLayer", "file.Seek failed");
	// read layer pixels
	BYTE *pBufImg = new BYTE [pLayerSections [nLayerSectionIndex].commonHeader.nSizeBuf];
	file.Read (pBufImg, pLayerSections [nLayerSectionIndex].commonHeader.nSizeBuf, 1);
	if (!pDecodingLayer->Decode (pBufImg, pLayerSections [nLayerSectionIndex].commonHeader.nSizeBuf, CXIMAGEIG_LAYERFORMAT))
		throw IGEXCEPTION (CxImageIGException, "DecodeLayer", "pDecodingLayer->Decode failed");
	delete [] pBufImg;

	// read layer alpha
	pDecodingLayer->AlphaCreate (255);
	file.Read (pDecodingLayer->pAlpha, pDecodingLayer->GetWidth() * pDecodingLayer->GetHeight(), 1);
	
	int nSubLayerWidth = 0;
	int nSubLayerHeight = 0;
	if (p_rcSubLayer)
	{
		// decode sub-layer
		nSubLayerWidth = p_rcSubLayer->right - p_rcSubLayer->left + 1;
		nSubLayerHeight = p_rcSubLayer->bottom - p_rcSubLayer->top + 1;
		BYTE *pLayerBits = NULL;
		BYTE *pSubLayerBits = NULL;
		for (int i = 0; i < nSubLayerHeight; i++)
		{
			// if undo, then sub-layer == original layer
			pSubLayerBits = bUndo ? pDecodingLayer->GetBits (p_rcSubLayer->top + i) + 3 * p_rcSubLayer->left : pDecodingLayer->GetBits (i);
			pLayerBits = pLayer->GetBits (p_rcSubLayer->top + i) + 3 * p_rcSubLayer->left;
			::memcpy (pLayerBits, pSubLayerBits, nSubLayerWidth * 3);			
		}
		BYTE *pLayerAlpha = NULL;
		BYTE *pSubLayerAlpha = NULL;
		for (int i = 0; i < nSubLayerHeight; i++)
		{
			pLayerAlpha = pLayer->AlphaGetPointer (p_rcSubLayer->left, p_rcSubLayer->top + i);
			pSubLayerAlpha = bUndo ? pDecodingLayer->AlphaGetPointer (p_rcSubLayer->left, p_rcSubLayer->top + i) : pDecodingLayer->AlphaGetPointer (0, i);
			::memcpy (pLayerAlpha, pSubLayerAlpha, nSubLayerWidth);
		}
		if (bUndo)
		{
			// original layer is now decoded. decode sub-layers
			bIsSubLayerOwner = false;
			int nMaxSubLayerSectionIndex = findLayerSectionIndex (&igHeader, pLayerSections, nSubLayerId, bIsSubLayerOwner); // we always have bIsSubLayerOwner = false, its used for the reference only
			if (nMaxSubLayerSectionIndex < 0)
				throw IGEXCEPTION (CxImageIGException, "DecodeLayer", "findLayerSectionIndex failed");
			if (nMaxSubLayerSectionIndex <= igHeader.nNbLayers)
			{
				for (int i = 0; i < pLayerSections [nLayerSectionIndex].nSubLayers; i++)
				{
					if (pLayerSections [nLayerSectionIndex].pnSubLayers [i] <= nMaxSubLayerSectionIndex)
					{
						if (!decodeSubLayer (file, pLayer, &pLayerSections [pLayerSections [nLayerSectionIndex].pnSubLayers [i]]))
							throw IGEXCEPTION (CxImageIGException, "DecodeLayer", "decodeSubLayer failed");
					}
				}
			}
		}
	}
	else
	{
		pLayer->info.xOffset = pLayerSections [nLayerSectionIndex].ptOffset.x;
		pLayer->info.yOffset = pLayerSections [nLayerSectionIndex].ptOffset.y;
	}
	pLayer->SetId (nLayerIdx);
	pLayer->UpdateImageParameters();
	delete [] pLayerSections;
	delete [] pSelectionSections;
	return true;
}
Exemplo n.º 3
0
bool CxImageIG::EncodeLayer (const wchar_t *pcwFilePath, int nLayerIdx, int nLayerPos, RECT *p_rcSubLayer, int nSubLayerOwnerId)
{
	CxIOFile file;
	if (!file.Open (pcwFilePath, L"r+b"))
		throw IGEXCEPTION (CxImageIGException, "EncodeLayer", "file.Open failed");
	// read current header
	IGHEADER igHeader;	
	if (!decodeHeader (&file, &igHeader))
		throw IGEXCEPTION (CxImageIGException, "EncodeLayer", "decodeHeader failed");

	IGSECTIONHEADER_LAYER *pLayerSections = new IGSECTIONHEADER_LAYER[CXIMAGEIG_MAX_NBLAYERS];
	IGSECTIONHEADER_SELECTION *pSelectionSections = new IGSECTIONHEADER_SELECTION[CXIMAGEIG_MAX_NBSELECTIONS];
	if (!decodeSections (&file, &igHeader, &pLayerSections[0], &pSelectionSections[0]))
		throw IGEXCEPTION (CxImageIGException, "EncodeLayer", "decodeSections failed");

	IGLibrary::IGLayer *pLayer = GetLayer (nLayerPos);
	if (!pLayer)
		throw IGEXCEPTION (CxImageIGException, "EncodeLayer", "GetLayer failed");
	_ASSERTE ((int)pLayer->GetId() == nLayerIdx && "CxImageIG::EncodeLayer FAILED");
	bool bIsSubLayerOwner = false;
	int nLayerSectionIndex = findLayerSectionIndex (&igHeader, pLayerSections, nLayerIdx, bIsSubLayerOwner);
	if (nLayerSectionIndex < 0)
		throw IGEXCEPTION (CxImageIGException, "EncodeLayer", "findLayerSectionIndex failed");
	if ((nLayerSectionIndex > igHeader.nNbLayers) || (nLayerSectionIndex >= CXIMAGEIG_MAX_NBLAYERS))
		throw IGEXCEPTION (CxImageIGException, "EncodeLayer", "findLayerSectionIndex failed");
	CxImage cxSubLayer;
	CxImage *pEncodingLayer = pLayer;
	int nSubLayerWidth = 0;
	int nSubLayerHeight = 0;
	if (p_rcSubLayer)
	{
		// Encode sub-layer
		nSubLayerWidth = p_rcSubLayer->right - p_rcSubLayer->left + 1;
		nSubLayerHeight = p_rcSubLayer->bottom - p_rcSubLayer->top + 1;
		cxSubLayer.Create (nSubLayerWidth, nSubLayerHeight, 24);
		cxSubLayer.AlphaCreate (255);
		BYTE *pLayerBits = NULL;
		BYTE *pSubLayerBits = NULL;
		for (int i = 0; i < nSubLayerHeight; i++)
		{
			pSubLayerBits = cxSubLayer.GetBits (i);
			pLayerBits = pLayer->GetBits (p_rcSubLayer->top + i) + 3 * p_rcSubLayer->left;
			::memcpy (pSubLayerBits, pLayerBits, nSubLayerWidth * 3);
		}
		BYTE *pLayerAlpha = NULL;
		BYTE *pSubLayerAlpha = NULL;
		for (int i = 0; i < nSubLayerHeight; i++)
		{
			pLayerAlpha = pLayer->AlphaGetPointer (p_rcSubLayer->left, p_rcSubLayer->top + i);
			pSubLayerAlpha = cxSubLayer.AlphaGetPointer (0, i);		
			::memcpy (pSubLayerAlpha, pLayerAlpha, nSubLayerWidth);
		}
		pEncodingLayer = &cxSubLayer;
		int nSubLayerSectionIndex = findLayerSectionIndex (&igHeader, pLayerSections, nSubLayerOwnerId, bIsSubLayerOwner);
		if (nSubLayerSectionIndex < 0)
			throw IGEXCEPTION (CxImageIGException, "EncodeLayer", "findLayerSectionIndex failed");
		pLayerSections [nSubLayerSectionIndex].pnSubLayers [pLayerSections [nSubLayerSectionIndex].nSubLayers++] = nLayerSectionIndex;
	}
	ProgressSetRange (pLayer->GetHeight(), 0);
	ProgressSetMessage (L"Encoding layer...");	
	// fill layer offset and size
	pLayerSections [nLayerSectionIndex].nSubLayers = 0;
	pLayerSections [nLayerSectionIndex].ptOffset.x = p_rcSubLayer ? p_rcSubLayer->left : pLayer->info.xOffset;
	pLayerSections [nLayerSectionIndex].ptOffset.y = p_rcSubLayer ? p_rcSubLayer->top : pLayer->info.yOffset;
	pLayerSections [nLayerSectionIndex].ptSize.x = p_rcSubLayer ? p_rcSubLayer->right - p_rcSubLayer->left + 1 : pLayer->GetWidth();
	pLayerSections [nLayerSectionIndex].ptSize.y = p_rcSubLayer ? p_rcSubLayer->bottom - p_rcSubLayer->top + 1 : pLayer->GetHeight();
	if (nLayerSectionIndex == igHeader.nNbLayers)
		pLayerSections [nLayerSectionIndex].commonHeader.nSectionId = (BYTE)igHeader.nNbSections;
	pLayerSections [nLayerSectionIndex].commonHeader.nId = nLayerIdx;
	pLayerSections [nLayerSectionIndex].commonHeader.eSectionType = IGSECTION_LAYER;
	// set byte offset
	if (igHeader.nNbSections == 0)
		pLayerSections [nLayerSectionIndex].commonHeader.nFirstByteOffset = sizeof (IGHEADER) + sizeof (IGSECTIONHEADER_LAYER) * CXIMAGEIG_MAX_NBLAYERS + sizeof (IGSECTIONHEADER_SELECTION) * CXIMAGEIG_MAX_NBSELECTIONS;
	else
		pLayerSections [nLayerSectionIndex].commonHeader.nFirstByteOffset = findSectionFirstByteOffset (&igHeader, pLayerSections, pSelectionSections, pLayerSections [nLayerSectionIndex].commonHeader.nSectionId);

	igHeader.nNbLayers = nLayerSectionIndex + 1;
	if (igHeader.nNbSelections == 0)
	{
		igHeader.nNbSections = pLayerSections [nLayerSectionIndex].commonHeader.nSectionId + 1;
		igHeader.nNbSelections = igHeader.nNbSections - igHeader.nNbLayers;
	}
	else
	{
		if (pSelectionSections [igHeader.nNbSelections - 1].commonHeader.nSectionId == pLayerSections [nLayerSectionIndex].commonHeader.nSectionId + 1)
			igHeader.nNbSections = igHeader.nNbSelections + igHeader.nNbLayers;
		else
		{
			igHeader.nNbSections = pLayerSections [nLayerSectionIndex].commonHeader.nSectionId + 1;
			igHeader.nNbSelections = igHeader.nNbSections - igHeader.nNbLayers;
		}
	}

	// write layer pixels
	if (!file.Seek (pLayerSections [nLayerSectionIndex].commonHeader.nFirstByteOffset, SEEK_SET))
		throw IGEXCEPTION (CxImageIGException, "EncodeLayer", "file.Seek failed");

	// set max JPEG quality
	float fCurQuality = pEncodingLayer->GetJpegQualityF();
	pEncodingLayer->SetJpegQualityF (100.0f);
	// JPEG encoding
	BYTE *pBuf = new BYTE [CXIMAGEIG_INIT_LAYERSIZE];
	CxMemFile memFile (pBuf, CXIMAGEIG_INIT_LAYERSIZE);
	if (!pEncodingLayer->Encode (&memFile, CXIMAGEIG_LAYERFORMAT))
		throw IGEXCEPTION (CxImageIGException, "EncodeLayer", "pEncodingLayer->Encode failed");
	BYTE *pBufImg = memFile.GetBuffer();
	long nSizeBufImg = memFile.Tell();
	// reset JPEG quality
	pEncodingLayer->SetJpegQualityF (fCurQuality);
	file.Write (pBufImg, nSizeBufImg, 1);
	delete [] pBufImg;
	pLayerSections [nLayerSectionIndex].commonHeader.nSizeBuf = nSizeBufImg;
	// write layer alpha
	if (!pEncodingLayer->pAlpha)
		pEncodingLayer->AlphaCreate(255);
	int nNbPixels = pEncodingLayer->GetWidth() * pEncodingLayer->GetHeight();
	file.Write (pEncodingLayer->pAlpha, nNbPixels, 1);
	pLayerSections [nLayerSectionIndex].commonHeader.nEndByteOffset = pLayerSections [nLayerSectionIndex].commonHeader.nFirstByteOffset + nSizeBufImg + nNbPixels;

	// write new headers
	if (!encodeHeader (&file, &igHeader))
		throw IGEXCEPTION (CxImageIGException, "EncodeLayer", "encodeHeader failed");
	if (!encodeSections (&file, &igHeader, pLayerSections, pSelectionSections))
		throw IGEXCEPTION (CxImageIGException, "EncodeLayer", "encodeSections failed");
	delete [] pLayerSections;
	delete [] pSelectionSections;
	return true;
}