示例#1
0
bool CxImageIG::Encode(CxFile *hFile)
{
	if (!hFile)
		throw IGEXCEPTION (CxImageIGException, "Encode", "hFile failed");
	// create ig format header
	IGHEADER	igHeader;
	igHeader.Manufacturer = IGHEADER_MAGICKEY;
	igHeader.Version = 0x01;
	igHeader.Encoding = 0x01;
	igHeader.nWidth = head.biWidth;
	igHeader.nHeight = head.biHeight;
	igHeader.nNbLayers = info.nNumLayers;
	igHeader.nNbSelections = 0;
	igHeader.nNbSections = info.nNumLayers;	
	igHeader.nPosWorkingLayer = (BYTE)GetLayerPos(dynamic_cast<IGLibrary::IGLayer*> (GetSelectionLayer()));		

	// write layer headers
	int nLayerSumHeight = 0;
	IGSECTIONHEADER_LAYER *pLayerHeader = new IGSECTIONHEADER_LAYER[CXIMAGEIG_MAX_NBLAYERS];
	for (int i = 0; i < info.nNumLayers; i++)
	{
		if (i < info.nNumLayers)
		{
			IGLibrary::IGLayer *pLayer = GetLayer (i);
			pLayerHeader[i].commonHeader.eSectionType = IGSECTION_LAYER;
			pLayerHeader[i].commonHeader.nId = (int)pLayer->GetId();
			pLayerHeader[i].commonHeader.nSectionId = i;
			pLayerHeader[i].commonHeader.nFirstByteOffset = 0;
			pLayerHeader[i].ptOffset.x = pLayer->info.xOffset;
			pLayerHeader[i].ptOffset.y = pLayer->info.yOffset;
			pLayerHeader[i].ptSize.x = pLayer->GetWidth();
			pLayerHeader[i].ptSize.y = pLayer->GetHeight();
			pLayerHeader[i].nSubLayers = 0;
			nLayerSumHeight += pLayer->GetHeight();		
		}
	}
	if (info.nNumLayers < CXIMAGEIG_MAX_NBLAYERS)
		ZeroMemory (&pLayerHeader [info.nNumLayers], sizeof(IGSECTIONHEADER_LAYER) * (CXIMAGEIG_MAX_NBLAYERS - info.nNumLayers));	

	ProgressSetRange (nLayerSumHeight, 0);
	ProgressSetMessage (L"Encoding picture...");	
	
	// write layer data
	if (!hFile->Seek (sizeof(IGHEADER) + sizeof (IGSECTIONHEADER_LAYER) * CXIMAGEIG_MAX_NBLAYERS + sizeof (IGSECTIONHEADER_SELECTION) * CXIMAGEIG_MAX_NBSELECTIONS, SEEK_SET))
		throw IGEXCEPTION (CxImageIGException, "Encode", "hFile->Seek failed");
	// write layers
	IGLibrary::IGLayer	*pLayer;
	for (int i = 0; i < info.nNumLayers; i++)
	{
		// write layer pixels
		pLayer = GetLayer (i);
		if (i == 0)
			pLayerHeader [i].commonHeader.nFirstByteOffset = sizeof(IGHEADER) + sizeof (IGSECTIONHEADER_LAYER) * CXIMAGEIG_MAX_NBLAYERS + sizeof (IGSECTIONHEADER_SELECTION) * CXIMAGEIG_MAX_NBSELECTIONS;
		else
			pLayerHeader [i].commonHeader.nFirstByteOffset = pLayerHeader [i - 1].commonHeader.nEndByteOffset;
		float fCurQuality = pLayer->GetJpegQualityF();
		pLayer->SetJpegQualityF (100.0f);
		
		BYTE *pBuf = new BYTE [CXIMAGEIG_INIT_LAYERSIZE];
		CxMemFile memFile (pBuf, CXIMAGEIG_INIT_LAYERSIZE);
		if (!pLayer->Encode (&memFile, CXIMAGEIG_LAYERFORMAT))
			throw IGEXCEPTION (CxImageIGException, "Encode", "pLayer->Encode failed");
		BYTE *pBufImg = memFile.GetBuffer();
		long nSizeBufImg = memFile.Tell();

		pLayer->SetJpegQualityF (fCurQuality);

		hFile->Write (pBufImg, nSizeBufImg, 1);
		delete [] pBufImg;
		pLayerHeader [i].commonHeader.nSizeBuf = nSizeBufImg;
		// write layer alpha
		if (!pLayer->pAlpha)
			pLayer->AlphaCreate(255);
		int nNbPixels = pLayer->GetWidth() * pLayer->GetHeight();
		hFile->Write (pLayer->pAlpha, nNbPixels, 1);
		pLayerHeader [i].commonHeader.nEndByteOffset = pLayerHeader [i].commonHeader.nFirstByteOffset + nSizeBufImg + nNbPixels;
	}
	// write section layer headers
	if (!hFile->Seek (sizeof(IGHEADER), SEEK_SET))
		throw IGEXCEPTION (CxImageIGException, "Encode", "hFile->Seek failed");
	hFile->Write (pLayerHeader, sizeof (IGSECTIONHEADER_LAYER) * info.nNumLayers, 1);
	
	// write section selection headers
	if (IsSelection())
	{
		// the selection is saved as well
		igHeader.nNbSelections = 1; 
		igHeader.nNbSections++;
		RECT rcSel;
		CxImage	*pSelectionLayer = GetSelectionLayer();
		pSelectionLayer->SelectionGetBox(rcSel);		
		IGSECTIONHEADER_SELECTION *pSelectionHeader = new IGSECTIONHEADER_SELECTION;
		pSelectionHeader->commonHeader.eSectionType = IGSECTION_SELECTION;
		pSelectionHeader->commonHeader.nFirstByteOffset = pLayerHeader [info.nNumLayers - 1].commonHeader.nEndByteOffset;
		pSelectionHeader->commonHeader.nSizeBuf = (rcSel.right - rcSel.left + 1) * (rcSel.top - rcSel.bottom + 1);
		pSelectionHeader->commonHeader.nEndByteOffset = pSelectionHeader->commonHeader.nFirstByteOffset + pSelectionHeader->commonHeader.nSizeBuf;
		pSelectionHeader->commonHeader.nId = IGFrameHistory::GetMaxSelectionId() + 1;
		pSelectionHeader->commonHeader.nSectionId = (BYTE)info.nNumLayers;
		pSelectionHeader->nLayerId = (int)(dynamic_cast<IGLibrary::IGLayer&> (*pSelectionLayer)).GetId();
		pSelectionHeader->rcSelection = rcSel;
		if (!hFile->Seek (sizeof(IGHEADER) + sizeof (IGSECTIONHEADER_LAYER) * info.nNumLayers, SEEK_SET))
			throw IGEXCEPTION (CxImageIGException, "Encode", "hFile->Seek failed");
		hFile->Write (pSelectionHeader, sizeof (IGSECTIONHEADER_SELECTION), 1);

		if (!writeSelection (*hFile, *pSelectionHeader, *pSelectionLayer))
			throw IGEXCEPTION (CxImageIGException, "Encode", "writeSelection failed");

		delete pSelectionHeader;
	}
	delete [] pLayerHeader;

	// write ig format header
	if (!hFile->Seek (0, SEEK_SET))
		throw IGEXCEPTION (CxImageIGException, "Encode", "hFile->Seek failed");
	hFile->Write (&igHeader, sizeof(IGHEADER), 1);

	if (!hFile->Seek (0, SEEK_END))
		throw IGEXCEPTION (CxImageIGException, "Encode", "hFile->Seek failed");
	return TRUE;
}
示例#2
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;
}
示例#3
0
bool CxImagePCX::Encode(CxFile * hFile)
{
	if (EncodeSafeCheck(hFile)) return false;

  cx_try
  {
	PCXHEADER pcxHeader;
	memset(&pcxHeader,0,sizeof(pcxHeader));
	pcxHeader.Manufacturer = PCX_MAGIC;
	pcxHeader.Version = 5;
	pcxHeader.Encoding = 1;
	pcxHeader.Xmin = 0;
	pcxHeader.Ymin = 0;
	pcxHeader.Xmax = (WORD)head.biWidth-1;
	pcxHeader.Ymax = (WORD)head.biHeight-1;
	pcxHeader.Hres = (WORD)info.xDPI;
	pcxHeader.Vres = (WORD)info.yDPI;
	pcxHeader.Reserved = 0;
	pcxHeader.PaletteType = head.biClrUsed==0;

	switch(head.biBitCount){
	case 24:
	case 8:
		{
			pcxHeader.BitsPerPixel = 8;
			pcxHeader.ColorPlanes = head.biClrUsed==0 ? 3 : 1;
#if CXIMAGE_SUPPORT_ALPHA
			if (AlphaIsValid() && head.biClrUsed==0) pcxHeader.ColorPlanes =4;
#endif //CXIMAGE_SUPPORT_ALPHA
			pcxHeader.BytesPerLine = (WORD)head.biWidth;
			break;
		}
	default: //(4 1)
		pcxHeader.BitsPerPixel = 1;
		pcxHeader.ColorPlanes = head.biClrUsed==16 ? 4 : 1;
		pcxHeader.BytesPerLine = (WORD)((head.biWidth * pcxHeader.BitsPerPixel + 7)>>3);
	}

    if (pcxHeader.BitsPerPixel == 1 && pcxHeader.ColorPlanes == 1){
		pcxHeader.ColorMap[0][0] = pcxHeader.ColorMap[0][1] = pcxHeader.ColorMap[0][2] = 0;
		pcxHeader.ColorMap[1][0] = pcxHeader.ColorMap[1][1] = pcxHeader.ColorMap[1][2] = 255;
	}
	if (pcxHeader.BitsPerPixel == 1 && pcxHeader.ColorPlanes == 4){
		RGBQUAD c;
		for (int i = 0; i < 16; i++){
			c=GetPaletteColor(i);
			pcxHeader.ColorMap[i][0] = c.rgbRed;
			pcxHeader.ColorMap[i][1] = c.rgbGreen;
			pcxHeader.ColorMap[i][2] = c.rgbBlue;
		}
	}

	pcxHeader.BytesPerLine = (pcxHeader.BytesPerLine + 1)&(~1);

	PCX_toh(&pcxHeader);
	if (hFile->Write(&pcxHeader, sizeof(pcxHeader), 1) == 0 )
	   cx_throw("cannot write PCX header");
	PCX_toh(&pcxHeader);

	CxMemFile buffer;
	buffer.Open();

	BYTE c,n;
	long x,y;
	if (head.biClrUsed==0){
		for (y = head.biHeight-1; y >=0 ; y--){
			for (int p=0; p<pcxHeader.ColorPlanes; p++){
				c=n=0;
				for (x = 0; x<head.biWidth; x++){
					if (p==0)
						PCX_PackPixels(BlindGetPixelColor(x,y).rgbRed,c,n,buffer);
					else if (p==1)
						PCX_PackPixels(BlindGetPixelColor(x,y).rgbGreen,c,n,buffer);
					else if (p==2)
						PCX_PackPixels(BlindGetPixelColor(x,y).rgbBlue,c,n,buffer);
#if CXIMAGE_SUPPORT_ALPHA
					else if (p==3)
						PCX_PackPixels(BlindAlphaGet(x,y),c,n,buffer);
#endif //CXIMAGE_SUPPORT_ALPHA
				}
				PCX_PackPixels(-1-(head.biWidth&0x1),c,n,buffer);
			}
		}

		hFile->Write(buffer.GetBuffer(false),buffer.Tell(),1);

	} else if (head.biBitCount==8) {

		for (y = head.biHeight-1; y >=0 ; y--){
			c=n=0;
			for (x = 0; x<head.biWidth; x++){
				PCX_PackPixels(GetPixelIndex(x,y),c,n,buffer);
			}
			PCX_PackPixels(-1-(head.biWidth&0x1),c,n,buffer);
		}

		hFile->Write(buffer.GetBuffer(false),buffer.Tell(),1);

		if (head.biBitCount == 8){
			hFile->PutC(0x0C);
			BYTE* pal = (BYTE*)malloc(768);
			RGBQUAD c;
			for (int i=0;i<256;i++){
				c=GetPaletteColor(i);
				pal[3*i+0] = c.rgbRed;
				pal[3*i+1] = c.rgbGreen;
				pal[3*i+2] = c.rgbBlue;
			}
			hFile->Write(pal,768,1);
			free(pal);
		}
	} else { //(head.biBitCount==4) || (head.biBitCount==1)

		RGBQUAD *rgb = GetPalette();
		bool binvert = false;
		if (CompareColors(&rgb[0],&rgb[1])>0) binvert=(head.biBitCount==1);
		
		BYTE* plane = (BYTE*)malloc(pcxHeader.BytesPerLine);
		BYTE* raw = (BYTE*)malloc(head.biWidth);

		for(y = head.biHeight-1; y >=0 ; y--) {

			for( x = 0; x < head.biWidth; x++)	raw[x] = (BYTE)GetPixelIndex(x,y);

			if (binvert) for( x = 0; x < head.biWidth; x++)	raw[x] = 1-raw[x];

			for( x = 0; x < pcxHeader.ColorPlanes; x++ ) {
				PCX_PixelsToPlanes(raw, head.biWidth, plane, x);
				PCX_PackPlanes(plane, pcxHeader.BytesPerLine, buffer);
			}
		}

		free(plane);
		free(raw);

		hFile->Write(buffer.GetBuffer(false),buffer.Tell(),1);

	}

  } cx_catch {
	if (strcmp(message,"")) strncpy(info.szLastError,message,255);
	return false;
  }
    return true;
}