Exemple #1
0
bool CxImageIG::DecodeSelection (const wchar_t *pcwFilePath, int nSelectionIdx, int nLayerPos, bool bUndo)
{
	CxIOFile file;
	if (!file.Open (pcwFilePath, L"rb"))
		throw IGEXCEPTION (CxImageIGException, "DecodeSelection", "file.Open failed");
	return DecodeSelection (file, nSelectionIdx, nLayerPos, bUndo);
}
Exemple #2
0
bool CxImageIG::DecodeLayer (const wchar_t *pcwFilePath, int nLayerIdx, int nLayerPos, RECT *p_rcSubLayer, bool bUndo, int nSubLayerId)
{
	CxIOFile file;
	if (!file.Open (pcwFilePath, L"rb"))
		throw IGEXCEPTION (CxImageIGException, "DecodeLayer", "file.Open failed");
	return DecodeLayer (file, nLayerIdx, nLayerPos, p_rcSubLayer, bUndo, nSubLayerId);
}
Exemple #3
0
int CxImageIG::GetNbSelections (const wchar_t *pcwFilePath)
{
	CxIOFile file;
	if (!file.Open (pcwFilePath, L"r+b"))
		return -1;
	// read current header
	IGHEADER igHeader;
	if (!decodeHeader (&file, &igHeader))
		return -1;
	return igHeader.nNbSelections;
}
Exemple #4
0
int CxImageIG::GetMaxSelectionId (const wchar_t *pcwFilePath)
{
	CxIOFile file;
	if (!file.Open (pcwFilePath, L"r+b"))
		return -1;
	// read current header
	IGHEADER igHeader;
	if (!decodeHeader (&file, &igHeader))
		return -1;
	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]))
		return -1;
	if (igHeader.nNbSelections <= 0)
		return -1;
	int nMaxSelectionId = pSelectionSections[0].commonHeader.nId;
	for (int nSelectionId = 1; nSelectionId < igHeader.nNbSelections; nSelectionId++)
	{
		if (nMaxSelectionId < pSelectionSections[nSelectionId].commonHeader.nId)
			nMaxSelectionId = pSelectionSections[nSelectionId].commonHeader.nId;
	}
	return nMaxSelectionId;
}
Exemple #5
0
bool CxImageJPG::GetExifThumbnail(const TCHAR *filename, const TCHAR *outname, int32_t type)
{
  CxIOFile file;
  if (!file.Open(filename, _T("rb"))) return false;
	CxExifInfo exif(&info.ExifInfo);
	exif.DecodeExif(&file);
  if (info.ExifInfo.IsExif && info.ExifInfo.ThumbnailPointer && info.ExifInfo.ThumbnailSize > 0)
  { // have a thumbnail - check whether it needs rotating or resizing
    // TODO: Write a fast routine to read the jpeg header to get the width and height
    CxImage image(info.ExifInfo.ThumbnailPointer, info.ExifInfo.ThumbnailSize, CXIMAGE_FORMAT_JPG);
    if (image.IsValid())
    {
      if (image.GetWidth() > 256 || image.GetHeight() > 256)
      { // resize the image
//        float amount = 256.0f / max(image.GetWidth(), image.GetHeight());
//        image.Resample((int32_t)(image.GetWidth() * amount), (int32_t)(image.GetHeight() * amount), 0);
      }
#if CXIMAGE_SUPPORT_TRANSFORMATION
      if (info.ExifInfo.Orientation != 1)
        image.RotateExif(info.ExifInfo.Orientation);
#endif
#if CXIMAGE_SUPPORT_ENCODE
      return image.Save(outname, CXIMAGE_FORMAT_JPG);
#endif
    }
    // nice and fast, but we can't resize :(
    /*
    FILE *hFileWrite;
    if ((hFileWrite=fopen(outname, "wb")) != NULL)
    {
      fwrite(m_exifinfo.ThumbnailPointer, m_exifinfo.ThumbnailSize, 1, hFileWrite);
      fclose(hFileWrite);
      return true;
    }*/
  }
  return false;
}
Exemple #6
0
bool CxImageIG::RemoveSections (const wchar_t *pcwFilePath, int nLayerId, int nSelectionId)
{
	CxIOFile file;
	if (!file.Open (pcwFilePath, L"r+b"))
		throw IGEXCEPTION (CxImageIGException, "RemoveSections", "file.Open failed");
	// read current header
	IGHEADER igHeader;
	if (!decodeHeader (&file, &igHeader))
		throw IGEXCEPTION (CxImageIGException, "RemoveSections", "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, pSelectionSections))
		throw IGEXCEPTION (CxImageIGException, "RemoveSections", "decodeSections failed");
	// remove layers
	bool bFound = false;
	int nLayerSectionId = 0;
	int nSelectionSectionId = 0;
	if (nLayerId >= 0 && igHeader.nNbLayers > 0)
	{
		int nSubLayerId = 0;
		while (nLayerSectionId < igHeader.nNbLayers)
		{
			// update the number of sublayer sections if the removed layer is a sublayer
			nSubLayerId = 0;
			bool bSubLayerFound = false;
			while (nSubLayerId < pLayerSections [nLayerSectionId].nSubLayers)
			{
				if (pLayerSections [nLayerSectionId].pnSubLayers [nSubLayerId] == nLayerId)
				{
					bSubLayerFound = true;
					break;
				}
				nSubLayerId++;
			}
			if (bSubLayerFound)
				pLayerSections [nLayerSectionId].nSubLayers = nSubLayerId + 1;
			if (pLayerSections [nLayerSectionId].commonHeader.nId == nLayerId)
			{
				bFound = true;
				break;
			}
			nLayerSectionId++;
		}
		if (bFound)
		{
			igHeader.nNbLayers = nLayerSectionId + 1;
			// remove selections if necessary
			int nNbRemovedSelections = 0;
			nSelectionSectionId = -1;
			while (++nSelectionSectionId < igHeader.nNbSelections)
			{
				if (pSelectionSections [nSelectionSectionId].commonHeader.nSectionId > pLayerSections [nLayerSectionId].commonHeader.nSectionId)
				{
					if (pSelectionSections [nSelectionSectionId].commonHeader.nId > nSelectionId && nSelectionId >= 0)
					{
						nNbRemovedSelections = igHeader.nNbSelections - nSelectionSectionId;
						break;
					}
				}
			}
			igHeader.nNbSelections -= nNbRemovedSelections;
		}
	}
	// remove selections
	bFound = false;
	if (igHeader.nNbSelections > 0) 
	{
		if (nSelectionId >= 0)
		{
			nSelectionSectionId = 0;
			while (nSelectionSectionId < igHeader.nNbSelections)
			{
				if (pSelectionSections [nSelectionSectionId].commonHeader.nId == nSelectionId)
				{
					bFound = true;
					break;
				}
				nSelectionSectionId++;
			}
			if (bFound)
			{
				igHeader.nNbSelections = nSelectionSectionId + 1;
				// remove layers if necessary
				int nNbRemovedLayers = 0;
				nLayerSectionId = -1;
				while (++nLayerSectionId < igHeader.nNbLayers)
				{
					if (pLayerSections [nLayerSectionId].commonHeader.nSectionId > pSelectionSections [nSelectionSectionId].commonHeader.nSectionId)
					{
						if (pLayerSections [nLayerSectionId].commonHeader.nId > nLayerId)
						{
							nNbRemovedLayers = igHeader.nNbLayers - nLayerSectionId;
							break;
						}
					}
				}
				igHeader.nNbLayers -= nNbRemovedLayers;
			}
		}
		else
			igHeader.nNbSelections = 0;
	}
	igHeader.nNbSections = igHeader.nNbSelections + igHeader.nNbLayers;
	// write new headers
	if (!encodeHeader (&file, &igHeader))
		throw IGEXCEPTION (CxImageIGException, "RemoveSections", "encodeHeader failed");
	if (!encodeSections (&file, &igHeader, pLayerSections, pSelectionSections))
		throw IGEXCEPTION (CxImageIGException, "RemoveSections", "encodeSections failed");
	delete [] pLayerSections;
	delete [] pSelectionSections;
	return true;
}
Exemple #7
0
bool CxImageIG::EncodeSelection (const wchar_t *pcwFilePath, int nSelectionIdx, int nLayerPos, const RECT& rcSelection)
{
	CxIOFile file;
	if (!file.Open (pcwFilePath, L"r+b"))
		throw IGEXCEPTION (CxImageIGException, "EncodeSelection", "file.Open failed");

	if (((rcSelection.left == -1) && (rcSelection.top != -1)) ||
		((rcSelection.right != -1) && (rcSelection.bottom == -1)))
		throw IGEXCEPTION (CxImageIGException, "EncodeSelection", "rcSelection failed");
	// read current header
	IGHEADER igHeader;
	if (!decodeHeader (&file, &igHeader))
		throw IGEXCEPTION (CxImageIGException, "EncodeSelection", "decodeHeader failed");
	if ((nLayerPos < 0) || (nLayerPos >= info.nNumLayers))
		throw IGEXCEPTION (CxImageIGException, "EncodeSelection", "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, "EncodeSelection", "decodeSections failed");

	IGLibrary::IGLayer *pLayer = GetLayer (nLayerPos);
	if (!pLayer)
		throw IGEXCEPTION (CxImageIGException, "EncodeSelection", "GetLayer failed");
	int nSelectionSectionIndex = findSelectionSectionIndex (&igHeader, pSelectionSections, nSelectionIdx);
	if (nSelectionSectionIndex < 0)
		throw IGEXCEPTION (CxImageIGException, "EncodeSelection", "findSelectionSectionIndex failed");
	if ((nSelectionSectionIndex > igHeader.nNbSelections) || (nSelectionSectionIndex >= CXIMAGEIG_MAX_NBSELECTIONS)
		|| (pLayer->GetId() < 0))
		throw IGEXCEPTION (CxImageIGException, "EncodeSelection", "findSelectionSectionIndex failed");

	// check rect bounds
	if (rcSelection.right != -1)	// right = -1 is a special case (full selection)
	{
		if ((rcSelection.left < 0) || (rcSelection.top < 0) ||
				(rcSelection.left >= pLayer->GetWidth()) || (rcSelection.top >= pLayer->GetHeight()) ||
				(rcSelection.right >= pLayer->GetWidth()) || (rcSelection.bottom >= pLayer->GetHeight()) ||
				(rcSelection.right <= rcSelection.left) || (rcSelection.bottom <= rcSelection.top))
				throw IGEXCEPTION (CxImageIGException, "EncodeSelection", "rcSelection failed");
	}	
	// fill layer offset and size
	pSelectionSections [nSelectionSectionIndex].rcSelection.left = (rcSelection.right == -1) ? 0 : rcSelection.left;
	pSelectionSections [nSelectionSectionIndex].rcSelection.bottom = (rcSelection.right == -1) ? 0 : pLayer->GetHeight() - 1 - rcSelection.bottom;
	pSelectionSections [nSelectionSectionIndex].rcSelection.right = (rcSelection.right == -1) ? pLayer->GetWidth() - 1 : rcSelection.right;
	pSelectionSections [nSelectionSectionIndex].rcSelection.top = (rcSelection.right == -1) ? pLayer->GetHeight()  - 1 : pLayer->GetHeight() - 1 - rcSelection.top;
	if (nSelectionSectionIndex == igHeader.nNbSelections)
		pSelectionSections [nSelectionSectionIndex].commonHeader.nSectionId = (BYTE)igHeader.nNbSections;
	pSelectionSections [nSelectionSectionIndex].commonHeader.nId = nSelectionIdx;
	pSelectionSections [nSelectionSectionIndex].nLayerId = (int)pLayer->GetId();
	pSelectionSections [nSelectionSectionIndex].commonHeader.eSectionType = IGSECTION_SELECTION;
	// no need to set byte offset if it is not the last layer
	if (igHeader.nNbSections == 0)
		pSelectionSections [nSelectionSectionIndex].commonHeader.nFirstByteOffset = sizeof (IGHEADER) + sizeof (IGSECTIONHEADER_LAYER) * CXIMAGEIG_MAX_NBLAYERS + sizeof (IGSECTIONHEADER_SELECTION) * CXIMAGEIG_MAX_NBSELECTIONS;
	else
		pSelectionSections [nSelectionSectionIndex].commonHeader.nFirstByteOffset = findSectionFirstByteOffset (&igHeader, pLayerSections, pSelectionSections, pSelectionSections [nSelectionSectionIndex].commonHeader.nSectionId);

	if (nSelectionSectionIndex == igHeader.nNbSelections)
		igHeader.nNbSections++;
	else
		igHeader.nNbSections = pSelectionSections [nSelectionSectionIndex].commonHeader.nSectionId + 1;

	igHeader.nNbSelections = nSelectionSectionIndex + 1;
	igHeader.nNbLayers = igHeader.nNbSections - igHeader.nNbSelections;

	if (!writeSelection (file, pSelectionSections [nSelectionSectionIndex], *pLayer, rcSelection.right == -1))
		throw IGEXCEPTION (CxImageIGException, "EncodeSelection", "writeSelection failed");
	
	// write new headers
	if (!encodeHeader (&file, &igHeader))
		throw IGEXCEPTION (CxImageIGException, "EncodeSelection", "encodeHeader failed");
	if (!encodeSections (&file, &igHeader, pLayerSections, pSelectionSections))
		throw IGEXCEPTION (CxImageIGException, "EncodeSelection", "encodeSections failed");

	delete [] pLayerSections;
	delete [] pSelectionSections;
	return true;
}
Exemple #8
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;
}