예제 #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;
}
예제 #2
0
BOOL CSonicImage::Load(HGLOBAL hGlobal, DWORD dwSize)
{
	if(m_gif.LoadGif(hGlobal, dwSize) == 1)
	{		
		if(PrepareMemDC(m_gif.GetWidth(), m_gif.GetHeight()) == FALSE)
		{
			m_gif.Clear();
			return FALSE;
		}
		m_gif.Draw(m_Dib.GetSafeHdc());
	}
	else
	{
		BYTE * pData = (BYTE *)GlobalLock(hGlobal);
		CxImage img;
		img.Decode(pData, dwSize, 0);
		GlobalUnlock(hGlobal);
		if(PrepareMemDC(img.GetWidth(), img.GetHeight()) == FALSE)
		{
			img.Clear();
			return FALSE;
		}
		if(!img.AlphaIsValid())
		{
			img.Draw(m_Dib.GetSafeHdc());
			CSSE::DoOr(0xff000000, m_Dib.GetBits(), m_Dib.GetSize());
		}
		else
		{
			if(img.GetBpp() != 24)
			{
				img.Clear();
				return FALSE;
			}
			BYTE * pSrc = img.GetBits();
			BYTE * pAlpha = img.AlphaGetBits();
			BYTE * pMyBits = m_Dib.GetBits();
			int nLineTail = m_nWidth % 4;
			for(int i = 0; i < m_nHeight; i++)
			{
				for(int j = 0; j < m_nWidth; j++)
				{
					*pMyBits++ = *pSrc++;
					*pMyBits++ = *pSrc++;
					*pMyBits++ = *pSrc++;
					*pMyBits++ = *pAlpha++;
				}
				pSrc += nLineTail;
			}
			EnableAlphaChannel();
		}
		img.Clear();
	}	
	return TRUE;
}
예제 #3
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;
}
예제 #4
0
UINT CFrameGrabThread::GrabFrames(){
	#define TIMEBETWEENFRAMES	50.0 // could be a param later, if needed
	for (int i = 0; i!= nFramesToGrab; i++)
		imgResults[i] = NULL;
	try{
		HRESULT hr;
		CComPtr<IMediaDet> pDet;
		hr = pDet.CoCreateInstance(__uuidof(MediaDet));
		if (!SUCCEEDED(hr))
			return 0;

		// Convert the file name to a BSTR.
		CComBSTR bstrFilename(strFileName);
		hr = pDet->put_Filename(bstrFilename);

		long lStreams;
		bool bFound = false;
		hr = pDet->get_OutputStreams(&lStreams);
		for (long i = 0; i < lStreams; i++)
		{
			GUID major_type;
			hr = pDet->put_CurrentStream(i);
			hr = pDet->get_StreamType(&major_type);
			if (major_type == MEDIATYPE_Video)
			{
				bFound = true;
				break;
			}
		}
		
		if (!bFound)
			return 0;
		
		double dLength = 0;
		pDet->get_StreamLength(&dLength);
		if (dStartTime > dLength)
			dStartTime = 0;

		long width = 0, height = 0; 
		AM_MEDIA_TYPE mt;
		hr = pDet->get_StreamMediaType(&mt);
		if (mt.formattype == FORMAT_VideoInfo) 
		{
			VIDEOINFOHEADER *pVih = (VIDEOINFOHEADER*)(mt.pbFormat);
			width = pVih->bmiHeader.biWidth;
			height = pVih->bmiHeader.biHeight;
			
	        
			// We want the absolute height, don't care about orientation.
			if (height < 0) height *= -1;
		}
		else {
			return 0; // Should not happen, in theory.
		}

		/*FreeMediaType(mt); = */	
		if (mt.cbFormat != 0){
			CoTaskMemFree((PVOID)mt.pbFormat);
			mt.cbFormat = 0;
			mt.pbFormat = NULL;
		}
		if (mt.pUnk != NULL){
			mt.pUnk->Release();
			mt.pUnk = NULL;
		}
		/**/

	    
		long size;
		uint32 nFramesGrabbed;
		for (nFramesGrabbed = 0; nFramesGrabbed != nFramesToGrab; nFramesGrabbed++){
			hr = pDet->GetBitmapBits(dStartTime + (nFramesGrabbed*TIMEBETWEENFRAMES), &size, NULL, width, height);
			if (SUCCEEDED(hr)) 
			{
				// we could also directly create a Bitmap in memory, however this caused problems/failed with *some* movie files
				// when I tried it for the MMPreview, while this method works always - so I'll continue to use this one
				long nFullBufferLen = sizeof( BITMAPFILEHEADER ) + size;
				char* buffer = new char[nFullBufferLen];
				
				BITMAPFILEHEADER bfh;
				memset( &bfh, 0, sizeof( bfh ) );
				bfh.bfType = 'MB';
				bfh.bfSize = nFullBufferLen;
				bfh.bfOffBits = sizeof( BITMAPINFOHEADER ) + sizeof( BITMAPFILEHEADER );
				memcpy(buffer,&bfh,sizeof( bfh ) );

				try {
					hr = pDet->GetBitmapBits(dStartTime+ (nFramesGrabbed*TIMEBETWEENFRAMES), NULL, buffer + sizeof( bfh ), width, height);
				}
				catch (...) {
					ASSERT(0);
					hr = E_FAIL;
				}
				if (SUCCEEDED(hr))
				{
					// decode
					CxImage* imgResult = new CxImage();
					imgResult->Decode((BYTE*)buffer, nFullBufferLen, CXIMAGE_FORMAT_BMP);
					delete[] buffer;
					if (!imgResult->IsValid()){
						delete imgResult;
						break;
					}

					// resize if needed
					if (nMaxWidth > 0 && nMaxWidth < width){
						float scale = (float)nMaxWidth / imgResult->GetWidth();
						int nMaxHeigth = (int)(imgResult->GetHeight() * scale);
						imgResult->Resample(nMaxWidth, nMaxHeigth, 0);
					}
					
					// decrease bpp if needed
					if (bReduceColor){
						RGBQUAD* ppal=(RGBQUAD*)malloc(256*sizeof(RGBQUAD));
						if (ppal) {
							CQuantizer q(256,8);
							q.ProcessImage(imgResult->GetDIB());
							q.SetColorTable(ppal);
							imgResult->DecreaseBpp(8, true, ppal);
							free(ppal);
						}
					}
					
					//CString TestName;
					//TestName.Format("G:\\testframe%i.png",nFramesGrabbed);
					//imgResult->Save(TestName,CXIMAGE_FORMAT_PNG);
					// done
					imgResults[nFramesGrabbed] = imgResult;
				}
				else{
					delete[] buffer;
					break;
				}
			}
		}
		return nFramesGrabbed;
	}
	catch(...){
		ASSERT(0);
		return 0;
	}
}
예제 #5
0
파일: ximaico.cpp 프로젝트: sd-eblana/bawx
bool CxImageICO::Decode(CxFile *hFile)
{
	if (hFile==NULL) return false;

	DWORD off = hFile->Tell(); //<yuandi>
	int	page=info.nFrame;	//internal icon structure indexes

	// read the first part of the header
	ICONHEADER icon_header;
	hFile->Read(&icon_header,sizeof(ICONHEADER),1);

	icon_header.idType = my_ntohs(icon_header.idType);
	icon_header.idCount = my_ntohs(icon_header.idCount);

	// check if it's an icon or a cursor
	if ((icon_header.idReserved == 0) && ((icon_header.idType == 1)||(icon_header.idType == 2))) {

		info.nNumFrames = icon_header.idCount;

		// load the icon descriptions
		ICONDIRENTRY *icon_list = (ICONDIRENTRY *)malloc(icon_header.idCount * sizeof(ICONDIRENTRY));
		int c;
		for (c = 0; c < icon_header.idCount; c++) {
			hFile->Read(icon_list + c, sizeof(ICONDIRENTRY), 1);

			icon_list[c].wPlanes = my_ntohs(icon_list[c].wPlanes);
			icon_list[c].wBitCount = my_ntohs(icon_list[c].wBitCount);
			icon_list[c].dwBytesInRes = my_ntohl(icon_list[c].dwBytesInRes);
			icon_list[c].dwImageOffset = my_ntohl(icon_list[c].dwImageOffset);
		}
		
		if ((page>=0)&&(page<icon_header.idCount)){

			if (info.nEscape == -1) {
				// Return output dimensions only
				head.biWidth = icon_list[page].bWidth;
				head.biHeight = icon_list[page].bHeight;
#if CXIMAGE_SUPPORT_PNG
				if (head.biWidth==0 && head.biHeight==0)
				{	// Vista icon support
					hFile->Seek(off + icon_list[page].dwImageOffset, SEEK_SET);
					CxImage png;
					png.SetEscape(-1);
					if (png.Decode(hFile,CXIMAGE_FORMAT_PNG)){
						Transfer(png);
						info.nNumFrames = icon_header.idCount;
					}
				}
#endif //CXIMAGE_SUPPORT_PNG
				free(icon_list);
				info.dwType = CXIMAGE_FORMAT_ICO;
				return true;
			}

			// get the bit count for the colors in the icon <CoreyRLucier>
			BITMAPINFOHEADER bih;
			hFile->Seek(off + icon_list[page].dwImageOffset, SEEK_SET);

			if (icon_list[page].bWidth==0 && icon_list[page].bHeight==0)
			{	// Vista icon support
#if CXIMAGE_SUPPORT_PNG
				CxImage png;
				if (png.Decode(hFile,CXIMAGE_FORMAT_PNG)){
					Transfer(png);
					info.nNumFrames = icon_header.idCount;
				}
				SetType(CXIMAGE_FORMAT_ICO);
#endif //CXIMAGE_SUPPORT_PNG
			}
			else
			{	// standard icon
				hFile->Read(&bih,sizeof(BITMAPINFOHEADER),1);

				bihtoh(&bih);

				c = bih.biBitCount;

				// allocate memory for one icon
				Create(icon_list[page].bWidth,icon_list[page].bHeight, c, CXIMAGE_FORMAT_ICO);	//image creation

				// read the palette
				RGBQUAD pal[256];
				if (bih.biClrUsed)
					hFile->Read(pal,bih.biClrUsed*sizeof(RGBQUAD), 1);
				else
					hFile->Read(pal,head.biClrUsed*sizeof(RGBQUAD), 1);

				SetPalette(pal,head.biClrUsed);	//palette assign

				//read the icon
				if (c<=24){
					hFile->Read(info.pImage, head.biSizeImage, 1);
				} else { // 32 bit icon
					BYTE* buf=(BYTE*)malloc(4*head.biHeight*head.biWidth);
					BYTE* src = buf;
					hFile->Read(buf, 4*head.biHeight*head.biWidth, 1);
#if CXIMAGE_SUPPORT_ALPHA
					if (!AlphaIsValid()) AlphaCreate();
#endif //CXIMAGE_SUPPORT_ALPHA
					for (long y = 0; y < head.biHeight; y++) {
						BYTE* dst = GetBits(y);
						for(long x=0;x<head.biWidth;x++){
							*dst++=src[0];
							*dst++=src[1];
							*dst++=src[2];
#if CXIMAGE_SUPPORT_ALPHA
							AlphaSet(x,y,src[3]);
#endif //CXIMAGE_SUPPORT_ALPHA
							src+=4;
						}
					}
					free(buf);
				}
				// apply the AND and XOR masks
				int maskwdt = ((head.biWidth+31) / 32) * 4;	//line width of AND mask (always 1 Bpp)
				int masksize = head.biHeight * maskwdt;				//size of mask
				BYTE *mask = (BYTE *)malloc(masksize);
				if (hFile->Read(mask, masksize, 1)){

					bool bGoodMask=false;
					for (int im=0;im<masksize;im++){
						if (mask[im]!=255){
							bGoodMask=true;
							break;
						}
					}

					if (bGoodMask && c != 32){
#if CXIMAGE_SUPPORT_ALPHA
						bool bNeedAlpha = false;
						if (!AlphaIsValid()){
							AlphaCreate();
						} else { 
							bNeedAlpha=true; //32bit icon
						}
						int x,y;
						for (y = 0; y < head.biHeight; y++) {
							for (x = 0; x < head.biWidth; x++) {
								if (((mask[y*maskwdt+(x>>3)]>>(7-x%8))&0x01)){
									AlphaSet(x,y,0);
									bNeedAlpha=true;
								}
							}
						}
						if (!bNeedAlpha) AlphaDelete();
#endif //CXIMAGE_SUPPORT_ALPHA

						//check if there is only one transparent color
						RGBQUAD cc,ct;
						long* pcc = (long*)&cc;
						long* pct = (long*)&ct;
						int nTransColors=0;
						int nTransIndex=0;
						for (y = 0; y < head.biHeight; y++){
							for (x = 0; x < head.biWidth; x++){
								if (((mask[y*maskwdt+(x>>3)] >> (7-x%8)) & 0x01)){
									cc = GetPixelColor(x,y,false);
									if (nTransColors==0){
										nTransIndex = GetPixelIndex(x,y);
										nTransColors++;
										ct = cc;
									} else {
										if (*pct!=*pcc){
											nTransColors++;
										}
									}
								}
							}
						}
						if (nTransColors==1){
							SetTransColor(ct);
							SetTransIndex(nTransIndex);
#if CXIMAGE_SUPPORT_ALPHA
							AlphaDelete(); //because we have a unique transparent color in the image
#endif //CXIMAGE_SUPPORT_ALPHA
						}

						// <vho> - Transparency support w/o Alpha support
						if (c <= 8){ // only for icons with less than 256 colors (XP icons need alpha).
							  
							// find a color index, which is not used in the image
							// it is almost sure to find one, bcs. nobody uses all possible colors for an icon

							BYTE colorsUsed[256];
							memset(colorsUsed, 0, sizeof(colorsUsed));

							for (y = 0; y < head.biHeight; y++){
								for (x = 0; x < head.biWidth; x++){
									colorsUsed[BlindGetPixelIndex(x,y)] = 1;
								}
							}

							int iTransIdx = -1;
							for (x = (int)(head.biClrUsed-1); x>=0 ; x--){
								if (colorsUsed[x] == 0){
									iTransIdx = x; // this one is not in use. we may use it as transparent color
									break;
								}
							}

							// Go thru image and set unused color as transparent index if needed
							if (iTransIdx >= 0){
								bool bNeedTrans = false;
								for (y = 0; y < head.biHeight; y++){
									for (x = 0; x < head.biWidth; x++){
										// AND mask (Each Byte represents 8 Pixels)
										if (((mask[y*maskwdt+(x>>3)] >> (7-x%8)) & 0x01)){
											// AND mask is set (!=0). This is a transparent part
											SetPixelIndex(x, y, (BYTE)iTransIdx);
											bNeedTrans = true;
										}
									}
								}
								// set transparent index if needed
								if (bNeedTrans)	SetTransIndex(iTransIdx);
#if CXIMAGE_SUPPORT_ALPHA
								AlphaDelete(); //because we have a transparent color in the palette
#endif //CXIMAGE_SUPPORT_ALPHA
							}
						}
					} else if(c != 32){
예제 #6
0
  __declspec(dllexport) bool LoadImageFromMemory(const BYTE *buffer, unsigned int size, const char *mime, unsigned int maxwidth, unsigned int maxheight, ImageInfo *info)
  {
    if (!buffer || !size || !mime || !info) return false;

    // load the image
    DWORD dwImageType = CXIMAGE_FORMAT_UNKNOWN;
    if (strlen(mime))
      dwImageType = GetImageType(mime);
    if (dwImageType == CXIMAGE_FORMAT_UNKNOWN)
      dwImageType = DetectFileType(buffer, size);
    if (dwImageType == CXIMAGE_FORMAT_UNKNOWN)
    {
      printf("PICTURE::LoadImageFromMemory: Unable to determine image type.");
      return false;
    }

    CxImage *image = new CxImage(dwImageType);
    if (!image)
      return false;

    int actualwidth = maxwidth;
    int actualheight = maxheight;

    try
    {
      bool success = image->Decode((BYTE*)buffer, size, dwImageType, actualwidth, actualheight);
      if (!success && dwImageType != CXIMAGE_FORMAT_UNKNOWN)
      { // try to decode with unknown imagetype
        success = image->Decode((BYTE*)buffer, size, CXIMAGE_FORMAT_UNKNOWN);
      }
      if (!success || !image->IsValid())
      {
        printf("PICTURE::LoadImageFromMemory: Unable to decode image. Error:%s\n", image->GetLastError());
        delete image;
        return false;
      }
    }
    catch (...)
    {
      printf("PICTURE::LoadImageFromMemory: Unable to decode image.");
      delete image;
      return false;
    }

    // ok, now resample the image down if necessary
    if (ResampleKeepAspect(*image, maxwidth, maxheight) < 0)
    {
      printf("PICTURE::LoadImage: Unable to resample picture\n");
      delete image;
      return false;
    }

    // make sure our image is 24bit minimum
    image->IncreaseBpp(24);

    // fill in our struct
    info->width = image->GetWidth();
    info->height = image->GetHeight();
    info->originalwidth = actualwidth;
    info->originalheight = actualheight;
    memcpy(&info->exifInfo, image->GetExifInfo(), sizeof(EXIFINFO));

    // create our texture
    info->context = image;
    info->texture = image->GetBits();
    info->alpha = image->AlphaGetBits();
    return (info->texture != NULL);
  };
예제 #7
-2
BOOL	
CResponseParser::SaveAsImage( const wchar_t* lpszPath,const char* lpszContentData, 
									 uint32 dwContentSize, DWORD dwType)
{
	CxImage image;

	bool bRet = false;

	DWORD dwFileType = CResponseParser::CheckImageFileHeader( (BYTE*)lpszContentData, dwContentSize);
	if( dwFileType == CXIMAGE_FORMAT_BMP )
	{
		bRet = image.Decode( (BYTE*)lpszContentData, dwContentSize, CXIMAGE_FORMAT_BMP);
	}
	else if( dwFileType == CXIMAGE_FORMAT_GIF)
	{
		bRet = image.Decode( (BYTE*)lpszContentData, dwContentSize, CXIMAGE_FORMAT_GIF);
	}
	else if( dwFileType == CXIMAGE_FORMAT_JPG )
	{
		bRet = image.Decode( (BYTE*)lpszContentData, dwContentSize, CXIMAGE_FORMAT_JPG);
	}
	else if( dwFileType == CXIMAGE_FORMAT_PNG)
	{
		bRet = image.Decode( (BYTE*)lpszContentData, dwContentSize, CXIMAGE_FORMAT_PNG);
	}

	if( bRet == true)
	{
		if( dwType == CXIMAGE_FORMAT_BMP)
		{
			return image.SaveW( lpszPath, CXIMAGE_FORMAT_BMP);
		}
		else if( dwType == CXIMAGE_FORMAT_GIF)
		{
			return image.SaveW( lpszPath, CXIMAGE_FORMAT_GIF);
		}
		else if( dwType == CXIMAGE_FORMAT_JPG)
		{
			return image.SaveW( lpszPath, CXIMAGE_FORMAT_JPG);
		}
		else if( dwType == CXIMAGE_FORMAT_PNG)
		{
			return image.SaveW( lpszPath, CXIMAGE_FORMAT_PNG);
		}
		else
			return image.SaveW( lpszPath, CXIMAGE_FORMAT_BMP);
	}

	return FALSE;
}