int CMetafileDisplay::LoadBits(UINT uiBuf, LPVOID pBuf)
{
#pragma pack(2)
typedef struct 
{
	DWORD   key;
	WORD	hmf;
	short	left;
	short	top;
	short	right;
	short	bottom;
	WORD    inch;
	DWORD	reserved;
	WORD    checksum;
} AMETAHEADER;
#pragma pack()

	if (enhMF != NULL)
	{
		DeleteEnhMetaFile(enhMF);
		enhMF = NULL;
	}

	// See if this is an enhanced metafile
	ENHMETAHEADER *emhdr = (ENHMETAHEADER *)pBuf;
	if (uiBuf >= sizeof(ENHMETAHEADER)
	 && emhdr->iType == EMR_HEADER
	 && emhdr->dSignature == ENHMETA_SIGNATURE)
	{
		enhMF = SetEnhMetaFileBits(uiBuf, (CONST BYTE *)pBuf);
	}
	else if (uiBuf >= sizeof(METAHEADER))
	{
		METAFILEPICT mp = {MM_ANISOTROPIC, 1000, 1000, NULL};
		AMETAHEADER *ahdr = (AMETAHEADER *)pBuf;
		METAHEADER *mhdr = (METAHEADER *)pBuf;
		// See if this is a placeable metafile
		if (ahdr->key == 0x9AC6CDD7)
		{
			mp.xExt = ((LONG)(ahdr->right - ahdr->left) * 25401) / (LONG)ahdr->inch;
			mp.yExt = ((LONG)(ahdr->bottom - ahdr->top) * 25401) / (LONG)ahdr->inch;
			mhdr = (METAHEADER *) (ahdr + 1);
		}
		UINT uiSizeMF = (UINT) mhdr->mtSize * 2;
		HDC dcRef = ::GetDC(NULL);
		enhMF = SetWinMetaFileBits(uiSizeMF, (LPBYTE)mhdr, dcRef, &mp);
		::ReleaseDC(NULL, dcRef);
	}

	return (enhMF == NULL) ? -1 : 0;
}
/*
void VPictureData_GDIPlus_Vector::FromVFile(VFile& inFile)
{
	Gdiplus::Rect rect;
	SetDataSource(NULL,true);
	_DisposeMetaFile();
	_SetDecoderByExtension("emf");
	
	VString path;
	inFile.GetPath(path);
	fMetafile=new Gdiplus::Metafile(path.GetCPointer());
	_InitSize();
}
*/
void VPictureData_GDIPlus_Vector::_FromMetaFilePict(METAFILEPICT* inMetaPict)
{
	HENHMETAFILE henh;
	void*        lpWinMFBits;
	UINT         uiSizeBuf;

	uiSizeBuf = GetMetaFileBitsEx(inMetaPict->hMF, 0, NULL);
	lpWinMFBits = GlobalAllocPtr(GHND, uiSizeBuf);
	GetMetaFileBitsEx(inMetaPict->hMF, uiSizeBuf, (LPVOID)lpWinMFBits);
	henh = SetWinMetaFileBits(uiSizeBuf, (LPBYTE)lpWinMFBits, NULL, inMetaPict);
	GlobalFreePtr(lpWinMFBits);

	_FromEnhMetaFile(henh);
}
void VPictureData_EMF::FromMetaFilePict(METAFILEPICT* inMetaPict)
{
	HENHMETAFILE henh;
	_ReleaseDataProvider();
	_DisposeMetaFile();
	
	void*        lpWinMFBits;
	UINT         uiSizeBuf;

	uiSizeBuf = GetMetaFileBitsEx(inMetaPict->hMF, 0, NULL);
	lpWinMFBits = GlobalAllocPtr(GHND, uiSizeBuf);
	GetMetaFileBitsEx(inMetaPict->hMF, uiSizeBuf, (LPVOID)lpWinMFBits);
	henh = SetWinMetaFileBits(uiSizeBuf, (LPBYTE)lpWinMFBits, NULL, inMetaPict);
	GlobalFreePtr(lpWinMFBits);


	FromEnhMetaFile(henh);
}
示例#4
0
void PlayPlaceableMeta(HDC hdc,BYTE *pMeta,int len,RECT *rt)
{
    HENHMETAFILE hEnh;
    PAPMHEADER pHeader=(PAPMHEADER)pMeta;
    METAFILEPICT mp;

    if(pHeader->dwKey == 0x9ac6cdd7l) {
        mp.mm = MM_ANISOTROPIC;
        mp.xExt = pHeader->bbox.Right - pHeader->bbox.Left;
        mp.xExt = ( mp.xExt * 2540l ) / (DWORD)(pHeader->wInch);
        mp.yExt = pHeader->bbox.Bottom - pHeader->bbox.Top;
        mp.yExt = ( mp.yExt * 2540l ) / (DWORD)(pHeader->wInch);
        mp.hMF = NULL;

        hEnh = SetWinMetaFileBits(len, &(pMeta[sizeof(APMHEADER)]), hdc, &mp);
        PlayEnhMetaFile(hdc,hEnh,rt);
        DeleteEnhMetaFile(hEnh);
    }
}
示例#5
0
/**********************************************************************
 Function:	ConvertWmfFiletoEmf
 Purpose:	Converts a Windows Metafile into an Enhanced Metafile
**********************************************************************/
HENHMETAFILE CxImageWMF::ConvertWmfFiletoEmf(CxFile *fp, METAFILEHEADER *metafileheader)
{
	HENHMETAFILE	hMeta;
	long			lenFile;
	long			len;
	BYTE			*p;
	METAHEADER		mfHeader;
	DWORD			seekpos;

	hMeta = 0;

	// get length of the file
	lenFile = fp->Size();

	// a placeable metafile starts with a METAFILEHEADER
	// read it and check metafileheader
	len = fp->Read(metafileheader, 1, sizeof(METAFILEHEADER));
	if (len < sizeof(METAFILEHEADER)) return (hMeta);

	if (CheckMetafileHeader(metafileheader)) {
		// This is a placeable metafile 
		// Convert the placeable format into something that can
		// be used with GDI metafile functions 
		seekpos = sizeof(METAFILEHEADER);
	} else {
		// Not a placeable wmf. A windows metafile?
		// at least not scaleable.
		// we could try to convert, but would loose ratio. don't allow this
		return (hMeta);

		//metafileheader->bbox.right = ?;
		//metafileheader->bbox.left = ?;
		//metafileheader->bbox.bottom = ?;
		//metafileheader->bbox.top = ?;
		//metafileheader->inch = ?;
		//
		//seekpos = 0;
		// fp->Seek(0, SEEK_SET);	// rewind
	}

	// At this point we have a metaheader regardless of whether
	// the metafile was a windows metafile or a placeable metafile
	// so check to see if it is valid. There is really no good
	// way to do this so just make sure that the mtType is either
	// 1 or 2 (memory or disk file) 
	// in addition we compare the length of the METAHEADER against
	// the length of the file. if filelength < len => no Metafile

	len = fp->Read(&mfHeader, 1, sizeof(METAHEADER));
	if (len < sizeof(METAHEADER)) return (hMeta);

	if ((mfHeader.mtType != 1) && (mfHeader.mtType != 2)) return (hMeta);

	// Length in Bytes from METAHEADER
	len = mfHeader.mtSize * 2;
	if (len > lenFile) return (hMeta);

	// Allocate memory for the metafile bits 
	p = (BYTE *)malloc(len);
	if (!p)	return (hMeta);

	// seek back to METAHEADER and read all the stuff at once
	fp->Seek(seekpos, SEEK_SET);
	lenFile = fp->Read(p, 1, len);
	if (lenFile != len)	{
		free(p);
		return (hMeta);
	}

	// the following (commented code)  works, but adjusts rclBound of the
	// Enhanced Metafile to full screen.
	// the METAFILEHEADER from above is needed to scale the image

//	hMeta = SetWinMetaFileBits(len, p, NULL, NULL);

	// scale the metafile (pixels/inch of metafile => pixels/inch of display)

	METAFILEPICT	mfp;
	int cx1, cy1;
	HDC hDC;

	hDC = ::GetDC(0);
	cx1 = ::GetDeviceCaps(hDC, LOGPIXELSX);
	cy1 = ::GetDeviceCaps(hDC, LOGPIXELSY);

	memset(&mfp, 0, sizeof(mfp));

	mfp.mm = MM_ANISOTROPIC;
	mfp.xExt = (metafileheader->bbox.right - metafileheader->bbox.left) * cx1 / metafileheader->inch;
	mfp.yExt = (metafileheader->bbox.bottom - metafileheader->bbox.top) * cy1 / metafileheader->inch;
	mfp.hMF = 0;

	// in MM_ANISOTROPIC mode xExt and yExt are in MM_HIENGLISH
	// MM_HIENGLISH means: Each logical unit is converted to 0.001 inch
	//mfp.xExt *= 1000;
	//mfp.yExt *= 1000;
	// ????
	//int k = 332800 / ::GetSystemMetrics(SM_CXSCREEN);
	//mfp.xExt *= k;	mfp.yExt *= k;

	// fix for Win9x
	while ((mfp.xExt < 6554) && (mfp.yExt < 6554))
	{
		mfp.xExt *= 10;
		mfp.yExt *= 10;
	}

	hMeta = SetWinMetaFileBits(len, p, hDC, &mfp);

	if (!hMeta){ //try 2nd conversion using a different mapping
		mfp.mm = MM_TEXT;
		hMeta = SetWinMetaFileBits(len, p, hDC, &mfp);
	}

	::ReleaseDC(0, hDC);

	// Free Memory
	free(p);

	return (hMeta);
}
示例#6
0
文件: emf.c 项目: 0xPr0xy/ImageMagick
static HENHMETAFILE ReadEnhMetaFile(const char *path,long *width,
  long *height)
{
#pragma pack( push )
#pragma pack( 2 )
  typedef struct
  {
    DWORD dwKey;
    WORD hmf;
    SMALL_RECT bbox;
    WORD wInch;
    DWORD dwReserved;
    WORD wCheckSum;
  } APMHEADER, *PAPMHEADER;
#pragma pack( pop )

  DWORD
    dwSize;

  ENHMETAHEADER
    emfh;

  HANDLE
    hFile;

  HDC
    hDC;

  HENHMETAFILE
    hTemp;

  LPBYTE
    pBits;

  METAFILEPICT
    mp;

  HMETAFILE
    hOld;

  *width=512;
  *height=512;
  hTemp=GetEnhMetaFile(path);
#if defined(MAGICKCORE_HAVE__WFOPEN)
  if (hTemp == (HENHMETAFILE) NULL)
    {
      wchar_t
        *unicode_path;

      unicode_path=ConvertUTF8ToUTF16(path);
      if (unicode_path != (wchar_t *) NULL)
        {
          hTemp=GetEnhMetaFileW(unicode_path);
          unicode_path=(wchar_t *) RelinquishMagickMemory(unicode_path);
        }
    }
#endif
  if (hTemp != (HENHMETAFILE) NULL)
    {
      /*
        Enhanced metafile.
      */
      GetEnhMetaFileHeader(hTemp,sizeof(ENHMETAHEADER),&emfh);
      *width=emfh.rclFrame.right-emfh.rclFrame.left;
      *height=emfh.rclFrame.bottom-emfh.rclFrame.top;
      return(hTemp);
    }
  hOld=GetMetaFile(path);
  if (hOld != (HMETAFILE) NULL)
    {
      /*
        16bit windows metafile.
      */
      dwSize=GetMetaFileBitsEx(hOld,0,NULL);
      if (dwSize == 0)
        {
          DeleteMetaFile(hOld);
          return((HENHMETAFILE) NULL);
        }
      pBits=(LPBYTE) AcquireQuantumMemory(dwSize,sizeof(*pBits));
      if (pBits == (LPBYTE) NULL)
        {
          DeleteMetaFile(hOld);
          return((HENHMETAFILE) NULL);
        }
      if (GetMetaFileBitsEx(hOld,dwSize,pBits) == 0)
        {
          pBits=(BYTE *) DestroyString((char *) pBits);
          DeleteMetaFile(hOld);
          return((HENHMETAFILE) NULL);
        }
      /*
        Make an enhanced metafile from the windows metafile.
      */
      mp.mm=MM_ANISOTROPIC;
      mp.xExt=1000;
      mp.yExt=1000;
      mp.hMF=NULL;
      hDC=GetDC(NULL);
      hTemp=SetWinMetaFileBits(dwSize,pBits,hDC,&mp);
      ReleaseDC(NULL,hDC);
      DeleteMetaFile(hOld);
      pBits=(BYTE *) DestroyString((char *) pBits);
      GetEnhMetaFileHeader(hTemp,sizeof(ENHMETAHEADER),&emfh);
      *width=emfh.rclFrame.right-emfh.rclFrame.left;
      *height=emfh.rclFrame.bottom-emfh.rclFrame.top;
      return(hTemp);
    }
  /*
    Aldus Placeable metafile.
  */
  hFile=CreateFile(path,GENERIC_READ,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,
    NULL);
  if (hFile == INVALID_HANDLE_VALUE)
    return(NULL);
  dwSize=GetFileSize(hFile,NULL);
  pBits=(LPBYTE) AcquireQuantumMemory(dwSize,sizeof(*pBits));
  ReadFile(hFile,pBits,dwSize,&dwSize,NULL);
  CloseHandle(hFile);
  if (((PAPMHEADER) pBits)->dwKey != 0x9ac6cdd7l)
    {
      pBits=(BYTE *) DestroyString((char *) pBits);
      return((HENHMETAFILE) NULL);
    }
  /*
    Make an enhanced metafile from the placable metafile.
  */
  mp.mm=MM_ANISOTROPIC;
  mp.xExt=((PAPMHEADER) pBits)->bbox.Right-((PAPMHEADER) pBits)->bbox.Left;
  *width=mp.xExt;
  mp.xExt=(mp.xExt*2540l)/(DWORD) (((PAPMHEADER) pBits)->wInch);
  mp.yExt=((PAPMHEADER)pBits)->bbox.Bottom-((PAPMHEADER) pBits)->bbox.Top;
  *height=mp.yExt;
  mp.yExt=(mp.yExt*2540l)/(DWORD) (((PAPMHEADER) pBits)->wInch);
  mp.hMF=NULL;
  hDC=GetDC(NULL);
  hTemp=SetWinMetaFileBits(dwSize,&(pBits[sizeof(APMHEADER)]),hDC,&mp);
  ReleaseDC(NULL,hDC);
  pBits=(BYTE *) DestroyString((char *) pBits);
  return(hTemp);
}
示例#7
0
void PLWEMFDecoder::Open (PLDataSource * pDataSrc)
{
	PLASSERT_VALID(this);
  PLASSERT(m_bm == 0);
  PLASSERT(m_memdc == 0);
  PLASSERT(m_hemf == 0);

	SAPMFILEHEADER* pplaceablehdr = NULL;
	bool isadobe = false;
      bool isemf;

	// Get the type of the file (WMF or EMF) from the file name
      if (pDataSrc->NameIsWide()){
        wchar_t* strname = _wcsdup(pDataSrc->GetNameW());
        PLASSERT(strname);
        if (strname == NULL) {
                // This should never happen under 32-Bit, but who knows?
                PLASSERT(false);
                raiseError (PL_ERRNO_MEMORY,"Out of memory during strdup.");
        }
        _wcsupr(strname);
        isemf = wcsstr(strname,L".EMF") != NULL;
        free(strname);
      }
      else{
	char* strname = _strdup(pDataSrc->GetName());
	PLASSERT(strname);
	if (strname == NULL) {
		// This should never happen under 32-Bit, but who knows?
		PLASSERT(false);
		raiseError (PL_ERRNO_MEMORY,"Out of memory during strdup.");
	}
	_strupr(strname);
	bool isemf = strstr(strname,".EMF") != NULL;
	free(strname);
      }

	// Get a DC for the display
	m_dc = ::GetDC(NULL);
	PLASSERT(m_dc);
	if (m_dc == NULL) {
		PLASSERT(false);
		raiseError (PL_ERRNO_MEMORY,"Cannot allocate device context.");
	}

	if (isemf) {
		// We have an enhanced meta file which makes it alot easier
		m_hemf = SetEnhMetaFileBits(pDataSrc->GetFileSize(),pDataSrc->ReadEverything());
	}
	else {
		// Buh, old 16-Bit WMF, Convert it to an enhanced metafile before proceeding.
		// Also, check if this is a placeable metafile with an Adobe Placeable header
		pplaceablehdr = (SAPMFILEHEADER*)pDataSrc->ReadEverything();
		PLBYTE* p = NULL;
		UINT size;
		// If we have an adobe header, skip it to use only the real windows-conform data
		if (pplaceablehdr->key == ALDUSKEY) {
			isadobe = true;
			p = pDataSrc->ReadEverything()+sizeof(SAPMFILEHEADER);
			size = pDataSrc->GetFileSize() - sizeof(SAPMFILEHEADER);
		}
		else {
			// Else use the whole file contents as the metafile and assume
			// a native 16-Bit Windows-conform WMF
			p = pDataSrc->ReadEverything();
			size = pDataSrc->GetFileSize();
		}
		#ifdef _MFC_VER
		PLASSERT(AfxIsValidAddress(p,size,false));
		#endif
		m_hemf = SetWinMetaFileBits(size,p,m_dc,NULL);
	}

	// If m_hemf is NULL, windows refused to load the metafile. If this is
	// the case, we're done. Notify the caller
	if (m_hemf == NULL) {
		raiseError (PL_ERRFORMAT_NOT_SUPPORTED,"Windows Metafile functions failed to load this image.");
	}

	// Get the header from the enhanced metafile, It contains some
	// useful information which will aid us during constuction of
	// the bitmap.
	// The header is of variable length. First get the amount of
	//  memory required for the header
	UINT sizeneeded = GetEnhMetaFileHeader(m_hemf,0,NULL);
	if (sizeneeded == 0) {
		raiseError (PL_ERRFORMAT_UNKNOWN,"No header information in metafile");
	}

	// Allocate storage for the header and read it in
	m_phdr = (LPENHMETAHEADER) new PLBYTE[sizeneeded];
	if (m_phdr == NULL) {
		PLASSERT(false);
		raiseError (PL_ERRNO_MEMORY,"Out of memory during allocation of header.");
	}
	m_phdr->iType = EMR_HEADER;
	m_phdr->nSize = sizeneeded;
	#ifdef _MFC_VER
	PLASSERT(AfxIsValidAddress(m_phdr,sizeneeded,true));
	#endif
	GetEnhMetaFileHeader(m_hemf,sizeneeded,m_phdr);

	int bpp = GetDeviceCaps(m_dc,BITSPIXEL);

	// Calculate the dimensions of the final bitmap. If we have
	// a placeable header in the WMF, we use the dimensions of
	// that image, else we use the calculated dimensions in the
	// EMF
	int width,height;
	if (isadobe) {
		PLASSERT(pplaceablehdr);
		int lpx = GetDeviceCaps(m_dc,LOGPIXELSX);
		int lpy = GetDeviceCaps(m_dc,LOGPIXELSY);
		// Calculate the absolute with and height and transform from twips to pixel
		width  = (int) (pplaceablehdr->Right-pplaceablehdr->Left) * lpx / pplaceablehdr->inch;
		height = (int) (pplaceablehdr->Bottom-pplaceablehdr->Top) * lpy / pplaceablehdr->inch;
	}
	else {
		// Use the rclFrame of the header because it is the true device independent
		// information and also some applications (e.g. Corel) don't fill the
		// rclBounds correctly
		// Using:
		//     MetaPixelsX = MetaWidthMM * MetaPixels / (MetaMM * 100);
		// where:
		//     MetaWidthMM = metafile width in 0.01mm units
		//     MetaPixels  = width in pixels of the reference device
		//     MetaMM      = width in millimeters of the reference device
		// Same applies to the Y axis
		width  = ((m_phdr->rclFrame.right  - m_phdr->rclFrame.left) * m_phdr->szlDevice.cx) / (m_phdr->szlMillimeters.cx*100);
		height = ((m_phdr->rclFrame.bottom  - m_phdr->rclFrame.top) * m_phdr->szlDevice.cy) / (m_phdr->szlMillimeters.cy*100);
	}

	// If this is a very old WMF without a PLACEABLE info,
	// we use somewhat meaningful defaults. Also, if the header was
	// not written correctly, we use this as a fallback
	if (width <= 0) {
		width = 320;
	}
	if (height <= 0) {
		height = 200;
	}

	// Create a device content for the screen, and a memory device
	// content to play the metafile to

	m_memdc = CreateCompatibleDC(m_dc);
	PLASSERT(m_memdc);
	if (m_memdc == NULL) {
		PLASSERT(false);
		raiseError (PL_ERRNO_MEMORY,"Cannot allocate device context.");
	}

	m_bm = CreateCompatibleBitmap(m_dc,width,height);
	if (m_bm == NULL) {
		PLASSERT(false);
		raiseError (PL_ERRNO_MEMORY,"Cannot allocate memory bitmap.");
	}

	m_holdbm = SelectObject(m_memdc,m_bm);

	// If the metafile has a palette, read it in
	UINT pe = GetEnhMetaFilePaletteEntries(m_hemf, 0, NULL);

	// pe is the real number of palette entries. To make the resulting
	// bitmap more useful, we always setup a 256 color palette if the
	// metafile has a palette
  if (pe>0 && pe<256)
  {
    SetBmpInfo (PLPoint (width, height), PLPoint(0,0), 
             PLPixelFormat::L8);
	}
	else 
  {
    SetBmpInfo (PLPoint (width, height), PLPoint(0,0), 
            PLPixelFormat::B8G8R8A8);
  }
}
示例#8
0
文件: display.c 项目: Bouke/Pillow
PyObject *
PyImaging_DrawWmf(PyObject* self, PyObject* args)
{
    HBITMAP bitmap;
    HENHMETAFILE meta;
    BITMAPCOREHEADER core;
    HDC dc;
    RECT rect;
    PyObject* buffer = NULL;
    char* ptr;

    char* data;
    int datasize;
    int width, height;
    int x0, y0, x1, y1;
    if (!PyArg_ParseTuple(args, PY_ARG_BYTES_LENGTH"(ii)(iiii):_load", &data, &datasize,
                          &width, &height, &x0, &x1, &y0, &y1))
        return NULL;

    /* step 1: copy metafile contents into METAFILE object */

    if (datasize > 22 && GET32(data, 0) == 0x9ac6cdd7) {

        /* placeable windows metafile (22-byte aldus header) */
        meta = SetWinMetaFileBits(datasize-22, data+22, NULL, NULL);

    } else if (datasize > 80 && GET32(data, 0) == 1 &&
               GET32(data, 40) == 0x464d4520) {

        /* enhanced metafile */
        meta = SetEnhMetaFileBits(datasize, data);

    } else {

        /* unknown meta format */
        meta = NULL;

    }

    if (!meta) {
        PyErr_SetString(PyExc_IOError, "cannot load metafile");
        return NULL;
    }

    /* step 2: create bitmap */

    core.bcSize = sizeof(core);
    core.bcWidth = width;
    core.bcHeight = height;
    core.bcPlanes = 1;
    core.bcBitCount = 24;

    dc = CreateCompatibleDC(NULL);

    bitmap = CreateDIBSection(
        dc, (BITMAPINFO*) &core, DIB_RGB_COLORS, &ptr, NULL, 0
        );

    if (!bitmap) {
        PyErr_SetString(PyExc_IOError, "cannot create bitmap");
        goto error;
    }

    if (!SelectObject(dc, bitmap)) {
        PyErr_SetString(PyExc_IOError, "cannot select bitmap");
        goto error;
    }

    /* step 3: render metafile into bitmap */

    rect.left = rect.top = 0;
    rect.right = width;
    rect.bottom = height;

    /* FIXME: make background transparent? configurable? */
    FillRect(dc, &rect, GetStockObject(WHITE_BRUSH));

    if (!PlayEnhMetaFile(dc, meta, &rect)) {
        PyErr_SetString(PyExc_IOError, "cannot render metafile");
        goto error;
    }

    /* step 4: extract bits from bitmap */

    GdiFlush();

    buffer = PyBytes_FromStringAndSize(ptr, height * ((width*3 + 3) & -4));

error:
    DeleteEnhMetaFile(meta);

    if (bitmap)
        DeleteObject(bitmap);

    DeleteDC(dc);

    return buffer;
}
示例#9
0
BOOL __stdcall pvdFileOpen2(void *pContext, const wchar_t *pFileName, INT64 lFileSize, const BYTE *pBuf, UINT32 lBuf, pvdInfoImage2 *pImageInfo)
{
	_ASSERTE(pImageInfo->cbSize >= sizeof(pvdInfoImage2));

	WmfContext *pw = (WmfContext*)CALLOC(sizeof(WmfContext));
	if (!pw) {
		pImageInfo->nErrNumber = PWE_NOT_ENOUGH_MEMORY;
		return FALSE;
	}
	//pw->h = GetEnhMetaFile ( pFileName+4 );

	const wchar_t *p = GetExtension(pFileName);
	if (!p) {
		pImageInfo->nErrNumber = PWE_NO_EXTENSION;
		return FALSE;
	}

	pImageInfo->nErrNumber = PWE_WIN32_ERROR; // заранее

	//if (pImageInfo->PreferredSize.cx && pImageInfo->PreferredSize.cy) {
	//	pw->PreferredSize = pImageInfo->PreferredSize;
	//} else {
	pw->PreferredSize.cx = 1000; pw->PreferredSize.cy = 1000;
	//}

	// First try to read it as an enhanced metafile
	// If it works, simply return the handle
	pw->h = SetEnhMetaFileBits(lBuf, pBuf);
	gnLastWin32Error = GetLastError();

	if (!pw->h) {
		pw->h = GetEnhMetaFile( pFileName );
		gnLastWin32Error = GetLastError();
	}

	if (!pw->h) {
		HMETAFILE		hOld;
		DWORD			dwSize;
		LPBYTE			pBits;
		METAFILEPICT	mp;
		HDC				hDC;

		if( (hOld = GetMetaFile( pFileName )) != NULL )
		{
			// Ok, it is a 16bit windows metafile
			// How big are the bits?
			if( (dwSize = GetMetaFileBitsEx( hOld, 0, NULL )) == 0 )
			{
				gnLastWin32Error = GetLastError();
				DeleteMetaFile( hOld );
				//MessageBox( hWndParent, "Failed to Get MetaFile Bits Size", "Error Reading MetaFile", MB_OK );
			} else {
				// Allocate that much memory
				if( (pBits = (LPBYTE)CALLOC( dwSize )) == NULL )
				{
					pImageInfo->nErrNumber = PWE_NOT_ENOUGH_MEMORY;
					gnLastWin32Error = GetLastError();
					DeleteMetaFile( hOld );
					//MessageBox( hWndParent, "Failed to Allocate Memory for Metafile Bits", "Error Reading MetaFile", MB_OK );
					//return NULL;
				} else {
					// Get the metafile bits
					if( GetMetaFileBitsEx( hOld, dwSize, pBits ) == 0 )
					{
						gnLastWin32Error = GetLastError();
						FREE( pBits );
						DeleteMetaFile( hOld );
						//MessageBox( hWndParent, "Failed to Get MetaFile Bits", "Error Reading MetaFile", MB_OK );
						//return NULL;
					} else {
						// Fill out a METAFILEPICT structure
						mp.mm = MM_ANISOTROPIC;
						mp.xExt = 1000;
						mp.yExt = 1000;
						mp.hMF = NULL;
						// Get a reference DC
						hDC = GetDC( NULL );
						// Make an enhanced metafile from the windows metafile
						pw->h = SetWinMetaFileBits( dwSize, pBits, hDC, &mp );
						gnLastWin32Error = GetLastError();
						// Clean up
						ReleaseDC( NULL, hDC );
						DeleteMetaFile( hOld );
						FREE( pBits );
					}
				}
			}
		}
	}

	if (!pw->h) {
		DWORD			dwSize = lBuf;
		LPBYTE			pBits = (LPBYTE)pBuf;
		METAFILEPICT	mp;
		HDC				hDC;

		// Is it a placeable metafile? (check the key)
		if( ((PAPMHEADER)pBits)->dwKey != 0x9ac6cdd7l )
		{
			// Not a metafile that we know how to recognise - bail out
			//MessageBox( hWndParent, "Not a Valid Metafile", szFileName, MB_OK );
			//return NULL;
			pImageInfo->nErrNumber = PWE_NOT_VALID_METAFILE;
		} else {
			// Ok, its a placeable metafile
			// Fill out a METAFILEPICT structure
			mp.mm = MM_ANISOTROPIC;
			mp.xExt = ((PAPMHEADER)pBits)->bbox.Right - ((PAPMHEADER)pBits)->bbox.Left;
			mp.xExt = ( mp.xExt * 2540l ) / (DWORD)(((PAPMHEADER)pBits)->wInch);
			mp.yExt = ((PAPMHEADER)pBits)->bbox.Bottom - ((PAPMHEADER)pBits)->bbox.Top;
			mp.yExt = ( mp.yExt * 2540l ) / (DWORD)(((PAPMHEADER)pBits)->wInch);
			mp.hMF = NULL;
			// Get a reference DC
			hDC = GetDC( NULL );
			// Create an enhanced metafile from the bits
			pw->h = SetWinMetaFileBits( dwSize, &(pBits[sizeof(APMHEADER)]), hDC, &mp );
			gnLastWin32Error = GetLastError();
			// Clean up
			ReleaseDC( NULL, hDC );
			//free( pBits );
			//if( hTemp == NULL )
			//	MessageBox( hWndParent, "Failed to Create MetaFile from Bits", "Error Reading MetaFile", MB_OK );
			//return hTemp;
		}
	}

	//if (pw->h) {
	//	//pw->hCompDC = CreateCompatibleDC(NULL);
	//	pw->mfp.mm = MM_ISOTROPIC;
	//	pw->mfp.xExt = pw->PreferredSize.cx;
	//	pw->mfp.yExt = pw->PreferredSize.cy;
	//	pw->h = (HENHMETAFILE)SetMetaFileBitsEx (lBuf, pBuf);
	//	gnLastWin32Error = GetLastError();
	//	pw->h = SetWinMetaFileBits(lBuf, pBuf, NULL, NULL); //pw->hCompDC, &pw->mfp);
	//	gnLastWin32Error = GetLastError();
	//}

	if (!pw->h) {
		//gnLastWin32Error = GetLastError(); -- уже
		FREE(pw);
		return FALSE;
	}

	pw->AddRef();
	_ASSERTE(pw->nRefCount == 1);

	ENHMETAHEADER	emh = {0};
	DWORD			PixelsX, PixelsY, MMX, MMY;
	emh.nSize = sizeof(ENHMETAHEADER);
	if( GetEnhMetaFileHeader( pw->h, sizeof( ENHMETAHEADER ), &emh ) )
	{
		// Get the characteristics of the output device
		HDC hDC = GetDC(NULL);
		PixelsX = GetDeviceCaps( hDC, HORZRES );
		PixelsY = GetDeviceCaps( hDC, VERTRES );
		MMX = GetDeviceCaps( hDC, HORZSIZE ) * 100;
		MMY = GetDeviceCaps( hDC, VERTSIZE ) * 100;
		ReleaseDC(NULL, hDC);

		// Calculate the rect in which to draw the metafile based on the
		// intended size and the current output device resolution
		// Remember that the intended size is given in 0.01mm units, so
		// convert those to device units on the target device
		//pw->PreferredSize.cx = (int)((float)(emh.rclFrame.right - emh.rclFrame.left) * PixelsX / (MMX));
		//pw->PreferredSize.cy = (int)((float)(emh.rclFrame.bottom - emh.rclFrame.top) * PixelsY / (MMY));
		pw->PreferredSize.cx = ip.MulDivI32((emh.rclFrame.right - emh.rclFrame.left), PixelsX, MMX);
		pw->PreferredSize.cy = ip.MulDivI32((emh.rclFrame.bottom - emh.rclFrame.top), PixelsY, MMY);
		_ASSERTE(pw->PreferredSize.cx>0 && pw->PreferredSize.cy>0);
		if (pw->PreferredSize.cx < 0) pw->PreferredSize.cx = -pw->PreferredSize.cx;
		if (pw->PreferredSize.cy < 0) pw->PreferredSize.cy = -pw->PreferredSize.cy;
	}

	pImageInfo->pImageContext = pw;
	pImageInfo->nPages = 1;
	pImageInfo->Flags = 0;
	pImageInfo->pFormatName = L"WMF";
	pImageInfo->pCompression = NULL;
	pImageInfo->pComments = NULL;

	return TRUE;
}
示例#10
0
static HENHMETAFILE ReadEnhMetaFile(const char *szFileName,long *width,
  long *height)
{
#pragma pack( push, 2 )
  typedef struct
  {
    DWORD dwKey;
    WORD hmf;
    SMALL_RECT bbox;
    WORD wInch;
    DWORD dwReserved;
    WORD wCheckSum;
  } APMHEADER, *PAPMHEADER;
#pragma pack( pop )

  DWORD
    dwSize;

  ENHMETAHEADER
    emfh;

  HANDLE
    hFile;

  HDC
    hDC;

  HENHMETAFILE
    hTemp;

  LPBYTE
    pBits;

  METAFILEPICT
    mp;

  HMETAFILE
    hOld;

  *width=512;
  *height=512;
  hTemp=GetEnhMetaFile(szFileName);
  if (hTemp != (HENHMETAFILE) NULL)
    {
      /*
        Enhanced metafile.
      */
      GetEnhMetaFileHeader(hTemp,sizeof(ENHMETAHEADER),&emfh);
      *width=emfh.rclFrame.right-emfh.rclFrame.left;
      *height=emfh.rclFrame.bottom-emfh.rclFrame.top;
      return(hTemp);
    }
  hOld=GetMetaFile(szFileName);
  if (hOld != (HMETAFILE) NULL)
    {
      /*
        16bit windows metafile.
      */
      dwSize=GetMetaFileBitsEx(hOld,0,NULL);
      if (dwSize == 0)
        {
          DeleteMetaFile(hOld);
          return((HENHMETAFILE) NULL);
        }
      pBits=MagickAllocateMemory(LPBYTE,dwSize);
      if (pBits == (LPBYTE) NULL)
        {
          DeleteMetaFile(hOld);
          return((HENHMETAFILE) NULL);
        }
      if (GetMetaFileBitsEx(hOld,dwSize,pBits) == 0)
        {
          MagickFreeMemory(pBits);
          DeleteMetaFile(hOld);
          return((HENHMETAFILE) NULL);
        }
      /*
        Make an enhanced metafile from the windows metafile.
      */
      mp.mm=MM_ANISOTROPIC;
      mp.xExt=1000;
      mp.yExt=1000;
      mp.hMF=NULL;
      hDC=GetDC(NULL);
      hTemp=SetWinMetaFileBits(dwSize,pBits,hDC,&mp);
      ReleaseDC(NULL,hDC);
      DeleteMetaFile(hOld);
      MagickFreeMemory(pBits);
      GetEnhMetaFileHeader(hTemp,sizeof(ENHMETAHEADER),&emfh);
      *width=emfh.rclFrame.right-emfh.rclFrame.left;
      *height=emfh.rclFrame.bottom-emfh.rclFrame.top;
      return(hTemp);
    }
  /*
    Aldus Placeable metafile.
  */
  hFile=CreateFile(szFileName,GENERIC_READ,0,NULL,OPEN_EXISTING,
    FILE_ATTRIBUTE_NORMAL,NULL);
  if (hFile == INVALID_HANDLE_VALUE)
    return(NULL);
  dwSize=GetFileSize(hFile,NULL);
  pBits=MagickAllocateMemory(LPBYTE,dwSize);
  ReadFile(hFile,pBits,dwSize,&dwSize,NULL);
  CloseHandle(hFile);
  if (((PAPMHEADER) pBits)->dwKey != 0x9ac6cdd7l)
    {
      MagickFreeMemory(pBits);
      return((HENHMETAFILE) NULL);
    }
  /*
    Make an enhanced metafile from the placable metafile.
  */
  mp.mm=MM_ANISOTROPIC;
  mp.xExt=((PAPMHEADER) pBits)->bbox.Right-((PAPMHEADER) pBits)->bbox.Left;
  *width=mp.xExt;
  mp.xExt=(mp.xExt*2540l)/(DWORD) (((PAPMHEADER) pBits)->wInch);
  mp.yExt=((PAPMHEADER)pBits)->bbox.Bottom-((PAPMHEADER) pBits)->bbox.Top;
  *height=mp.yExt;
  mp.yExt=(mp.yExt*2540l)/(DWORD) (((PAPMHEADER) pBits)->wInch);
  mp.hMF=NULL;
  hDC=GetDC(NULL);
  hTemp=SetWinMetaFileBits(dwSize,&(pBits[sizeof(APMHEADER)]),hDC,&mp);
  ReleaseDC(NULL,hDC);
  MagickFreeMemory(pBits);
  return(hTemp);
}