📄 bitmap.c
字号:
/****************************************************************************
* *
* THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY *
* KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE *
* IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR *
* PURPOSE. *
* *
* Copyright (C) 1993-95 Microsoft Corporation. All Rights Reserved. *
* *
****************************************************************************/
//-----------------------------------------------------------------------------
// This files contains the module name for this mini driver. Each mini driver
// must have a unique module name. The module name is used to obtain the
// module handle of this Mini Driver. The module handle is used by the
// generic library to load in tables from the Mini Driver.
//-----------------------------------------------------------------------------
#define PRINTDRIVER
#define BUILDDLL
#include "print.h"
#include "gdidefs.inc"
#include "bitmap.h"
#include "memory.h"
#include "mdevice.h"
#include "unidrv.h"
char *rgchModuleName = "BITMAP";
BYTE szBuf[4] = {0xFF, 0xFF, 0xFF, 0xFF};
//*************************************************************
//
// fnDump
//
// Purpose: Gets filled in band block from GDI and sends to BlockOut
// one scan line at a time.
//
//
// Parameters:
// LPDV lpdv
// LPPOINT lpptCursor
// WORD fMode
//
//
// Return: (short FAR PASCAL)
//*************************************************************
short FAR PASCAL fnDump(LPDV lpdv, LPPOINT lpptCursor, WORD fMode)
{
short result = 1;
WORD iScan, i, WidthBytes, BandHeight;
WORD wScanlinesPerSeg, wWAlignBytes, wSegmentInc;
LPBITMAP lpbmHdr;
BOOL fHuge;
LPBYTE lpSrc;
LPBYTE lpScanLine;
LPEXTPDEV lpXPDV;
// get pointer to our private data stored in UNIDRV's PDEVICE
lpXPDV = ((LPEXTPDEV)lpdv->lpMd);
// get ptr to PBITMAP
lpbmHdr = (LPBITMAP)((LPSTR)lpdv + lpdv->oBruteHdr);
// initialize some things
fHuge = lpbmHdr->bmSegmentIndex > 0;
lpSrc = lpbmHdr->bmBits;
wWAlignBytes = (lpbmHdr->bmWidth+7)>>3;
WidthBytes = lpbmHdr->bmWidthBytes;
BandHeight = lpbmHdr->bmHeight;
wScanlinesPerSeg = lpbmHdr->bmScanSegment;
wSegmentInc = lpbmHdr->bmSegmentIndex;
// portrait or landscape orientation.
for (iScan = 0; ((iScan < BandHeight) && QueryAbort(lpXPDV->hAppDC,0)
&& lpXPDV->hScanBuf);iScan += wScanlinesPerSeg)
{
// get next 64K segment of scans
if (iScan)
{
WORD wRemainingScans = BandHeight - iScan;
// cross the segment boundary
lpSrc = (LPBYTE)MAKELONG(0,HIWORD(lpSrc)+wSegmentInc);
if (wScanlinesPerSeg > wRemainingScans)
wScanlinesPerSeg = wRemainingScans;
}
// loop through scan lines in 64K segment
for (i=iScan, lpScanLine=lpSrc;
((i < iScan + wScanlinesPerSeg) && QueryAbort(lpXPDV->hAppDC, 0)
&& lpXPDV->hScanBuf); i++)
{
if (lpXPDV->func==103)
BlockOutCmp(lpdv, lpScanLine, wWAlignBytes);
else
BlockOut(lpdv, lpScanLine, wWAlignBytes);
lpScanLine += WidthBytes;
}
} // end for iScan
return result;
} //*** fnDump
void Mirror(LPEXTPDEV lpXPDV,WORD wBytes)
{
WORD j;
BYTE ch,ch1,ch2,ch3;
BYTE far *p;
BYTE far *q;
BYTE far *r;
r=(BYTE far *)lpXPDV->lpTmpBuf;
p=r;
q=p+wBytes-1;
for (j=0; j<wBytes/2; j++,p++,q--) {
ch=(BYTE)(~(*p));
for (ch1=0,ch2=1,ch3=(BYTE)0x80; ch2; ch2=(BYTE)(ch2<<1),ch3=(BYTE)(ch3>>1))
if (ch & ch2)
ch1=ch1 | ch3;
ch=(BYTE)(~(*q));
*q=ch1;
for (ch1=0,ch2=1,ch3=(BYTE)0x80; ch2; ch2=(BYTE)(ch2<<1),ch3=(BYTE)(ch3>>1))
if (ch & ch2)
ch1=ch1 | ch3;
*p=ch1;
}
if (wBytes%2) {
ch=(BYTE)(~(*p));
for (ch1=0,ch2=1,ch3=(BYTE)0x80; ch2; ch2=(BYTE)(ch2<<1),ch3=(BYTE)(ch3>>1))
if (ch & ch2)
ch1=ch1 | ch3;
*p=ch1;
}
}
WORD FAR PASCAL cmp(LPEXTPDEV lpXPDV,WORD wBytes)
{
WORD iSc,iDs,nSame,pt;
signed char far *scBuf;
signed char far *dsBuf;
scBuf=lpXPDV->lpTmpBuf;
dsBuf=scBuf+LINEBYTES;
iDs=0;
nSame=1;
pt=iDs++;
dsBuf[pt]=-1;
for(iSc=0;iSc<wBytes-1;iSc++)
{
if( scBuf[iSc] == scBuf[iSc+1])
{
nSame++;
if( nSame < MINCMPNUM ) {
dsBuf[pt]++;
dsBuf[iDs++]=scBuf[iSc];
if(dsBuf[pt] == 127) {
pt=iDs++;
dsBuf[pt]=-1;
nSame=1;
}
}
else
if( nSame == MINCMPNUM ) {
dsBuf[pt] -=(MINCMPNUM-2);
if (dsBuf[pt]<0)
iDs=pt;
else
iDs -=(MINCMPNUM-2);
pt=iDs++;
iDs++;
dsBuf[pt]= -(MINCMPNUM-2);
}
else {
dsBuf[pt]--;
if (dsBuf[pt]==-127) {
pt=iDs++;
dsBuf[pt]=-1;
nSame=1;
}
}
}
else {
if( nSame >= MINCMPNUM) {
dsBuf[pt]--;
pt=iDs++;
dsBuf[pt]=-1;
}
else {
dsBuf[pt]++;
dsBuf[iDs++]=scBuf[iSc];
if(dsBuf[pt] == 127) {
pt=iDs++;
dsBuf[pt]=-1;
}
}
nSame=1;
}
} // loop end
if (nSame >= MINCMPNUM)
dsBuf[pt]--;
else {
dsBuf[pt]++;
dsBuf[iDs++]=scBuf[iSc];
}
return (iDs);
}
void FAR PASCAL uncmp(LPEXTPDEV lpXPDV)
{
signed char ch,c;
WORD iDs;
WORD i,wWidthBytes;
signed char _huge *p;
signed char far *dsBuf;
_llseek(lpXPDV->hDIBFile, lpXPDV->wHdrSize, 0);
// compute scan line width
wWidthBytes = (WORD)(lpXPDV->dwTotalScanBytes / lpXPDV->dwTotalScans);
p=(signed char _huge *)lpXPDV->lpScanBuf;
dsBuf=lpXPDV->lpTmpBuf;
iDs=0;
for(i=0; i<(WORD)lpXPDV->dwTotalScans;) {
ch=*p++;
if( ch >= 0 && (int)ch <= 127) {
iDs +=(int)ch+1;
for (; ch > -1; ch--)
*dsBuf++=*p++;
}
else if ( ch < 0 && ch>=-127 ) {
iDs +=1-(int)ch;
c=*p++;
for( ; ch<1 ; ch++)
*dsBuf++=c;
}
if(iDs==wWidthBytes) {
_lwrite(lpXPDV->hDIBFile, lpXPDV->lpTmpBuf, wWidthBytes);
i++;
iDs=0;
dsBuf=lpXPDV->lpTmpBuf;
}
}
}
//*** DumpScans
short FAR PASCAL BlockOutCmp(LPDV lpdv, LPSTR lpBuf, WORD len)
{
WORD wBytes;
LPEXTPDEV lpXPDV;
WORD lenCmp;
// get pointer to our private data stored in UNIDRV's PDEVICE
lpXPDV = ((LPEXTPDEV)lpdv->lpMd);
// convert from WORD aligned to DWORD aligned buffer
// get DWORD amount of bytes
wBytes = (WORD)DW_WIDTHBYTES((DWORD)len*8);
if (lpXPDV->hTmpBuf)
{
// copy scan line to scan bufffer
_fmemcpy(lpXPDV->lpTmpBuf, lpBuf, len);
_fmemcpy(lpXPDV->lpTmpBuf+len, (LPSTR)szBuf, wBytes-len);
}
Mirror(lpXPDV,wBytes);
lenCmp=cmp(lpXPDV,wBytes);
// check to see if need to realloc scan buffer
if ((lpXPDV->dwTotalCmp + lenCmp) > lpXPDV->dwScanBufSize)
{
HANDLE hTemp;
lpXPDV->dwScanBufSize += BUF_CHUNK;
hTemp = GlobalReAlloc(lpXPDV->hScanBuf, lpXPDV->dwScanBufSize,
GMEM_MOVEABLE | GMEM_ZEROINIT);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -