⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 compress.cpp

📁 pocket printer的一个打印机驱动程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*++
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) 1995-1998  Microsoft Corporation

Module Name:


Abstract:


Functions:




Notes:


--*/


#include "precomp.hxx"
#include <string.h>
#include "compress.h"
#include "local.h"
#include "serial.h"

// A6SDK.h
typedef struct	tagA6P{
	BYTE	comm[5];
	BYTE	data[12000];
} A6PRINTDATA, *LPA6PRINTDATA;

static BYTE	pixel[12000];
static BYTE	data[12000];
static A6PRINTDATA pData;

// halftone.h
BYTE
GrayScale(
	BYTE	r,
	BYTE	g,
	BYTE	b
	);

void
PrepareImage(
	LPBYTE	pixel,
	LPBYTE	dot,
	DWORD	dwLine,
	DWORD	dwWidth
	);

// util.h
DWORD
Compress(
	LPBYTE	oData,
	LPBYTE	nData,
	DWORD dwDataLen
	);
BOOL bSkip;

//#define VERBOSE
#ifdef VERBOSE
	#define TRACE(cond, args) \
        do { if (cond) { MessageBox(GetFocus(), args, TEXT("A6PRN"), MB_OK); /*DebugBreak();*/ } } while (0)
#else
    #define TRACE(cond, args)
#endif

#define HUE_B           0.64
#define HUE_G           0.9

#define GAMMA_C         1.3
#define GAMMA_K         1.4
#define GAMMA_V         2.1

#define DOT_K           1.3
#define DOT_C           1.1
#define DOT_M           1.2
#define DOT_Y           1.1

#define MAX_8           0x0ff
#define MAX_14          0x02000
#define MAX_13          0x01000


const static int BitMask[8] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 };

Printer printer;


Port::Port(void)
{
    nBuffer  = 0;
    hPrinter = INVALID_HANDLE_VALUE;
}

Port::~Port(void)
{
    TRACE(TRUE, (TEXT("A6PRN: Port::~Port\r\n")));
    Close();
}

BOOL Port::Flush(void)
{
//nBuffer = 0;
//return TRUE;

    BOOL    f = TRUE;

    if (nBuffer) 
    {
        // Output data to debug window. This is temporary.
        //
/*
        int   Total = nBuffer;
        BYTE *pInput = Buffer;
        while (Total)
        {
            int cnt;
            if (Total < 32) cnt = Total;
            else cnt = 32;

            unsigned short Output[140];
            unsigned short *pOutput = Output;
            for (int i = 0; i < cnt; i++)
            {
                wsprintf(pOutput, (TEXT("%02x")), *pInput);
                pOutput += 2;
                pInput++;
            }
            RETAILMSG(TRUE, (TEXT("[%s]\r\n"), Output));
            Total -= cnt;
        }       
*/
        // Send data to printer.
        //
		if (hPrinter == (HANDLE)PRINT_SERIAL_PORT)
			f = PortWrite(hPrinter, Buffer, nBuffer);
		else
			f = PrinterSend(hPrinter, Buffer, nBuffer);
        nBuffer = 0;
    }

TRACE(!f, (TEXT("\tPrinterSend() Failed\r\n")));

    return f;
}

HANDLE Port::Open(PWSTR sPort)
{
	PWSTR pPort=NULL;
    Close();

    if ((pPort = (PWSTR)malloc(max((lstrlen(sPort) + 1), 6) * sizeof(TCHAR)))) {
        lstrcpy(pPort, sPort);
    }
    if (!pPort) {
        SetLastError(ERROR_OUTOFMEMORY);
	    return INVALID_HANDLE_VALUE;
    }
    if (CompareString(LOCALE_SYSTEM_DEFAULT, NORM_IGNORECASE, TEXT("COM"), 3, pPort, 3) == CSTR_EQUAL)
		hPrinter = PortInitialize(sPort);
	else
		hPrinter = PrinterOpen(sPort);
	free(pPort);
	return hPrinter;
}

void Port::Close(void)
{
    TRACE(TRUE, (TEXT("A6PRN: Port::Close\r\n")));

    if (INVALID_HANDLE_VALUE != hPrinter)
    {
        Flush();
		if (hPrinter == (HANDLE)PRINT_SERIAL_PORT)
			PortClose(hPrinter);
		else
	        PrinterClose(hPrinter);
        hPrinter = INVALID_HANDLE_VALUE;
    }
}

BOOL Port::Write(BYTE *buffer, int length)
{
    BOOL f = TRUE;

    if (!buffer) return FALSE;

    while (length && f)
    {
        // Is the buffer full and do we need to flush to the printer.
        //
        if (nBuffer == PORT_BUF_SIZE)
            f = Flush();

        // Move as many bytes as we can.
        //
        int nBytesToCopy = PORT_BUF_SIZE - nBuffer;
        if (length < nBytesToCopy) nBytesToCopy = length;

        memcpy(Buffer+nBuffer, buffer, nBytesToCopy);
        buffer += nBytesToCopy;
        length -= nBytesToCopy;
        nBuffer += nBytesToCopy;
    }

    return f;
}

BOOL Port::WriteString(char *buffer)
{
    if (!buffer) return FALSE;
    unsigned int length = strlen(buffer);
    return Write((BYTE *)buffer, length); 
}


#define PCL_UNENCODED   0
#define PCL_TIFF        2
#define PCL_DELTAROW    3

BOOL Printer::AllocateBuffers(GDIINFO * pGI, DEVMODE * pDM)
{
    TRACE(TRUE, (TEXT("A6PRN: AllocateBuffers\r\n")));

    int    i;
    double d;

    // Forget old buffers, if any.
    //
    DeallocateBuffers();

    fColor = (DMCOLOR_COLOR == pDM->dmColor); 
fColor = FALSE; 

    PaperSize = pDM->dmPaperSize;

    ResolutionPixels = pGI->ulLogPixelsX;
    if (DMORIENT_LANDSCAPE == pDM->dmOrientation)
    {
        HeightPixels = pGI->ulHorzRes;
        WidthPixels  = pGI->ulVertRes;
        pColorRow = new BYTE[WidthPixels * 3];
    }
    else
    {
        HeightPixels = pGI->ulVertRes;
        WidthPixels  = pGI->ulHorzRes;
    }
    WidthOfRasterAreaInBytes  = WidthPixels;//(WidthPixels+7)/8;

    pScanRow  = new BYTE[WidthOfRasterAreaInBytes];
    pBlackRow = new BYTE[WidthOfRasterAreaInBytes];
    pPCLData  = new BYTE[WidthOfRasterAreaInBytes];
    pError    = new short[WidthPixels + 2];

    pK  = new short[WidthPixels];
    pEK = new short[WidthPixels];
    pSK = new BYTE[WidthOfRasterAreaInBytes];

    pGK = new short[MAX_8 + 1];
    d   = pow(MAX_8, GAMMA_K) / MAX_14;
    pGK[0] = pGK[1] = 0;
    for (i = 2; i < MAX_8; i++) 
        pGK[i]  = int(pow(i, GAMMA_K) / d + 0.5);
    pGK[MAX_8]  = MAX_14;

    if (fColor) {
        pC = new short[WidthPixels];
        pM = new short[WidthPixels];
        pY = new short[WidthPixels];

        pEC = new short[WidthPixels];
        pEM = new short[WidthPixels];
        pEY = new short[WidthPixels];

        pSC = new BYTE[WidthOfRasterAreaInBytes];
        pSM = new BYTE[WidthOfRasterAreaInBytes];
        pSY = new BYTE[WidthOfRasterAreaInBytes];

        pGC = new short[MAX_8 + 1];
        d   = pow(MAX_8, GAMMA_C) / MAX_14;
        pGC[0]  = 0;
        for (i = 1; i < MAX_8; i++) 
            pGC[i]  = int(pow(i, GAMMA_C) / d + 0.5);
        pGC[MAX_8]  = MAX_14;

        pGV = new BYTE[MAX_8 + 1];
        d   = pow(MAX_8, GAMMA_V) / MAX_8;
        pGV[0] = 0;
        for (i = 1; i < MAX_8; i++) 
            pGV[i] = int(pow(i, GAMMA_V) / d + 0.5);
        pGV[MAX_8] = MAX_8;
    }

    iDotK = int(DOT_K * MAX_14);
    iDotC = int(DOT_C * MAX_14);
    iDotM = int(DOT_M * MAX_14);
    iDotY = int(DOT_Y * MAX_14);

    iHueB = int(HUE_B * MAX_8);
    iHueG = int(HUE_G * MAX_8);

    return pScanRow && pBlackRow && pPCLData && pError &&
        (pColorRow || DMORIENT_LANDSCAPE != pDM->dmOrientation) &&
        pK  && pEK && pSK && pGK &&
        (!fColor ||
         (pC  && pM  && pY  && 
          pEC && pEM && pEY &&
          pSC && pSM && pSY &&
          pGV && pGC));
}

void Printer::DeallocateBuffers(void)
{
    TRACE(TRUE, (TEXT("A6PRN: DeallocateBuffers\r\n")));

    if (pColorRow)
    {
        delete pColorRow;
        pColorRow = 0;
    }
    if (pScanRow)
    {
        delete pScanRow;
        pScanRow = 0;
    }
    if (pBlackRow)
    {
        delete pBlackRow;
        pBlackRow = 0;
    }

    if (pPCLData)
    {
        delete pPCLData;
        pPCLData = 0;
    }
    if (pError)
    {
        delete pError;
        pError = 0;
    }

    if (pC) {
        delete pC;
        pC = 0;
    }
    if (pY) {
        delete pY;
        pY = 0;
    }
    if (pM) {
        delete pM;
        pM = 0;
    }
    if (pK) {
        delete pK;
        pK = 0;
    }

    if (pSC) {
        delete pSC;
        pSC = 0;
    }
    if (pSY) {
        delete pSY;
        pSY = 0;
    }
    if (pSM) {
        delete pSM;
        pSM = 0;
    }
    if (pSK) {
        delete pSK;
        pSK = 0;
    }

    if (pEC) {
        delete pEC;
        pEC = 0;
    }
    if (pEY) {
        delete pEY;
        pEY = 0;
    }
    if (pEM) {
        delete pEM;
        pEM = 0;
    }
    if (pEK) {
        delete pEK;
        pEK = 0;
    }

    if (pGK) {
        delete pGK;
        pGK = 0;
    }
    if (pGC) {
        delete pGC;
        pGC = 0;
    }
    if (pGV) {
        delete pGV;
        pGV = 0;
    }
}

HANDLE Printer::Open(PWSTR sPort)
{
    TRACE(TRUE, (TEXT("A6PRN: Open\r\n")));

    HANDLE  h;

    h = port.Open(sPort);

    if (h != INVALID_HANDLE_VALUE) {
        int  i;
        int  j;

        f3Pen = FALSE;

        i = sizeof(j);
        if (GetPrinterInfo(h, PRINTER_PEN, &j, &i) == ERROR_SUCCESS &&
            !(j & PEN_BLACK))
            f3Pen = TRUE;
    }
    return h;
}

void Printer::Close(void)
{
    TRACE(TRUE, (TEXT("A6PRN: Close\r\n")));

    DeallocateBuffers();
    port.Close();
}

Printer::Printer(void)
{
    TRACE(TRUE, (TEXT("A6PRN: Printer\r\n")));

    pColorRow = 0;
    pScanRow  = 0;
    pBlackRow = 0;
    pPCLData  = 0;
    pError    = 0;

    iRow = 0;

    pK = 0;
    pC = 0;
    pM = 0;
    pY = 0;

    pSK = 0;
    pSC = 0;
    pSM = 0;
    pSY = 0;

    pEK = 0;
    pEC = 0;
    pEM = 0;
    pEY = 0;

    pGK = 0;
    pGC = 0;
    pGV = 0;
}

Printer::~Printer(void)
{
    TRACE(TRUE, (TEXT("A6PRN: Printer::~Printer\r\n")));

    Close();
}

void Printer::NextPage(void)
{
    TRACE(TRUE, (TEXT("A6PRN: NextPage\r\n")));

	if ((iRow%8) != 0)
	{
		PrepareImage(pixel, data, ((iRow-1)/8)%8, WidthOfRasterAreaInBytes);
		memset(pixel, 0xFF, 12000);
		DWORD dwLen = Compress(data, pData.data, 8*WidthOfRasterAreaInBytes);

		if (!bSkip)
		{
			if (dwScroll)
			{
				FeedSpace(dwScroll);
				dwScroll = 0;
			}

			SendCompressData(pData.data, dwLen);
			LineFeed();
		}

		memset(data, 0x0, 12000);
	}

	if (dwScroll && g_pParam->nPaper!=1)
	{
		FeedSpace(dwScroll);
	}

	if (g_pParam->nForm == 1)
	{
		FeedSpace((g_pParam->nScroll)*400/254);
	}
	else
	{
		FormFeed();
	}
	port.Flush();

    iRow = 0;
	dwScroll = 0;
}

void Printer::RasterStart(void)
{
    TRACE(TRUE, (TEXT("A6PRN: RasterStart\r\n")));

	Reset();

//	if (!FeedSpace((g_pParam->rcMargin.top - 10)*4000/254))
//		return;

    // Initialize SeedRow.
    //
    memset(pSK, 0, WidthOfRasterAreaInBytes);

    memset(pEK, 0, WidthPixels * sizeof(short));

    if (fColor) {
        memset(pSC, 0, WidthOfRasterAreaInBytes);
        memset(pSM, 0, WidthOfRasterAreaInBytes);
        memset(pSY, 0, WidthOfRasterAreaInBytes);

        memset(pEC, 0, WidthPixels * sizeof(short));
        memset(pEM, 0, WidthPixels * sizeof(short));
        memset(pEY, 0, WidthPixels * sizeof(short));
    }
	memset(pixel, 0xFF, 12000);
	memset(data, 0, 12000);
		
    srand(119);
}

BOOL Printer::TransferData(BYTE * Data, int length)
{
	TCHAR szMsg[MAX_PATH];
	wsprintf(szMsg, TEXT("TransferData %d"), length);
//    TRACE(TRUE, (szMsg));

//	TRACE(TRUE, (TEXT("A6PRN: TransferData\r\n")));

    // Transfer Raster Data Command
    //
	BYTE comm[] = { 0x1B, 0x2A, 0x32, 0, 0 };

	comm[3] = (BYTE)(length%256);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -