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

📄 filterhpa.cpp

📁 HP喷墨打印机驱动代码 HP内部资料! 珍贵 珍贵 珍贵
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/*****************************************************************************\  filterhpa.cpp : Implimentation for the TErnieFilter class  Copyright (c) 1996 - 2001, Hewlett-Packard Co.  All rights reserved.  Redistribution and use in source and binary forms, with or without  modification, are permitted provided that the following conditions  are met:  1. Redistributions of source code must retain the above copyright     notice, this list of conditions and the following disclaimer.  2. Redistributions in binary form must reproduce the above copyright     notice, this list of conditions and the following disclaimer in the     documentation and/or other materials provided with the distribution.  3. Neither the name of Hewlett-Packard nor the names of its     contributors may be used to endorse or promote products derived     from this software without specific prior written permission.  THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN  NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED  TO, PATENT INFRINGEMENT; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\*****************************************************************************/#if defined(APDK_DJ9xxVIP) && defined(APDK_VIP_COLORFILTERING)#include "header.h"// copied from vob \di_research on 10/31/00// MODIFICATIONS BY GE:// 0. remove Windows header references// 1. define assert// 2. set iRastersReady, iRastersDelivered in submitrowtofilter// 3. (constructor) allocate (and delete in destructor) buffers for fRowPtr//      (instead of setting it to input buffers, since we reuse input buffers)// 4. copy data into fRowPtr in submitrowtofilter//#define assert ASSERT#include "ernieplatform.h"#include "filterhpa.h"#if kGatherStats == 1extern int blockStats[];#endif#if ((kMemWritesOptimize != 1) && (kMemWritesOptimize != 0))#error "kMemWritesOptimize must be 0 or 1"#endifAPDK_BEGIN_NAMESPACEinline void AverageNRound(bool roundGreenDown, int &rFinal, int &r0, int &r1, int &gFinal, int &g0, int &g1, int &bFinal, int &b0, int &b1);inline void AverageNRound(bool roundGreenDown, int &rFinal, int &r0, int &r1, int &gFinal, int &g0, int &g1, int &bFinal, int &b0, int &b1){    // By rounding G in the other direction than R and B L* variations are minimized while mathematically alternate rounding is accomplished. EGW 2 Dec. 1999.    if (roundGreenDown)    {        rFinal = (r0 + r1 + 1) / 2;        gFinal = (g0 + g1) / 2;        bFinal = (b0 + b1 + 1) / 2;    }    else    {        rFinal = (r0 + r1) / 2;        gFinal = (g0 + g1 + 1) / 2;        bFinal = (b0 + b1) / 2;    }}// Filter1RawRow.  To be used to filter an odd row for which we don't have a pair,// found at the bottom of bands that aren't divisable by 2.  This routine// filters its row horizontally forming 4x1 and 2x1 blocks.void TErnieFilter::Filter1RawRow(unsigned char *currPtr, int rowWidthInPixels, unsigned int *flagsPtr){    ASSERT(currPtr);    ASSERT(rowWidthInPixels > 0);    int R0, G0, B0, R1, G1, B1, lastR, lastG, lastB;    const unsigned int maxErrorForFourPixels = fMaxErrorForTwoPixels / 2;//    const unsigned int maxErrorForEightPixels = maxErrorForFourPixels / 2;//    int currPixel, lastPixel;    uint32_t currPixel, lastPixel;    bool lastPairAveraged = false;    bool last2by2Averaged = false;    for (int pixelNum = 0; pixelNum < rowWidthInPixels; pixelNum++)    {        if ((pixelNum & 0x03) == 0x00) // 0,4,8...        {            last2by2Averaged = false; // Reinitialize every four columns;        }        currPixel = get4Pixel(currPtr);        flagsPtr[0] = (e11n|e11s);  // Initialize in case nothing is found for this column        if (isWhite(currPixel))        {            flagsPtr[0] = eDone;#if kGatherStats == 1            blockStats[esWhiteFound]++;#endif        }        // Currently we bail entirely if there is white. Later we may still do RLE on the non white pixel if one is present.        if (flagsPtr[0] == (e11n|e11s))        {            R1 = GetRed(currPixel);            G1 = GetGreen(currPixel);            B1 = GetBlue(currPixel);            // Can only horizontally average every other pixel, much like the 2x2 blocks.            if (isOdd(pixelNum))            {                // do horizontal on current raster                lastPixel = get4Pixel(currPtr,-1);                lastR = GetRed(lastPixel);                lastG = GetGreen(lastPixel);                lastB = GetBlue(lastPixel);                if ((fMaxErrorForTwoPixels >= 3) && (NewDeltaE(lastR, R1, lastG, G1, lastB, B1, fMaxErrorForTwoPixels)))                {                    /*   - -                        |   | build 2x1                         - -                    */                    int didNotBuild4by1 = true;#if kGatherStats == 1                    blockStats[es21nw]++;#endif                    AverageNRound(isOdd(pixelNum), lastR, lastR, R1, lastG, lastG, G1, lastB, lastB, B1);                    if ((pixelNum >= 3) && (flagsPtr[-3] & e21nw)) // 4,5,6,7,12,13,14,15,20...                    {                        // Look for a 4x1                        ASSERT(!((flagsPtr[-3] | flagsPtr[-2] | flagsPtr[-1] | flagsPtr[0]) & eTheRest)); // no vertical blocks                        lastPixel = get4Pixel(currPtr,-3);                        R0 = GetRed(lastPixel);                        G0 = GetGreen(lastPixel);                        B0 = GetBlue(lastPixel);                        if ((maxErrorForFourPixels >= 3) && (NewDeltaE(lastR, R0, lastG, G0, lastB, B0, maxErrorForFourPixels)))                        {                            /*   - - - -                                |       | build 4x1                                 - - - -                            */#if kGatherStats == 1                            blockStats[es41ni]++;#endif                            didNotBuild4by1 = false;                            AverageNRound((pixelNum & 0x04)== 0x04, lastR, lastR, R0, lastG, lastG, G0, lastB, lastB, B0); // 4,5,6,7,12,13,14,15,20...                            if(littleEndian)                                currPixel = (lastR<<16) + (lastG<<8) + lastB;                            else if(bigEndian)                                currPixel = (lastR<<24) + (lastG<<16) + (lastB<<8);#if kMemWritesOptimize == 0                            put4Pixel(currPtr, -3, currPixel);                            put4Pixel(currPtr, -2, currPixel);                            put4Pixel(currPtr, -1, currPixel);                            put4Pixel(currPtr, 0, currPixel);#else                            put4Pixel(currPtr, -3, currPixel);#endif                            flagsPtr[-3] = (flagsPtr[-3] & ~eNorths) | e41ni;                            flagsPtr[-2] = (flagsPtr[-2] & ~eNorths) | e41n;                            flagsPtr[-1] = (flagsPtr[-1] & ~eNorths) | e41n;                            flagsPtr[0] = (flagsPtr[0] & ~eNorths) | e41n;                        }                    }                    if (didNotBuild4by1) // Not a 4x1 so output 2x1.                    {                        ASSERT(!((flagsPtr[-1] | flagsPtr[0]) & eTheRest)); // no vertical blocks                        if(littleEndian)                            currPixel = (lastR<<16) + (lastG<<8) + lastB;                        else if(bigEndian)                            currPixel = (lastR<<24) + (lastG<<16) + (lastB<<8);#if kMemWritesOptimize == 0                        put4Pixel(currPtr, -1, currPixel);                        put4Pixel(currPtr, 0, currPixel);#else                        put4Pixel(currPtr, -1, currPixel);#endif                        flagsPtr[-1] = (flagsPtr[-1] & ~eNorths) | e21nw;                        flagsPtr[0] = (flagsPtr[0] & ~eNorths) | e21ne;                    }                }  // If DeltaE... Looking for two by one            }  // IsOdd(pixelNum)        }        else // no flag bits set.        {            lastPairAveraged = false; // EGW Fixes bug on business graphics. 11/24/97        }        currPtr += eBufferedPixelWidthInBytes;        flagsPtr++;    }      // for each pixel...}// Filter2RawRows:  Looks filter two raw rows together to form blocks.  Vertical// blocks are prefered over horizontal ones.  The routine will create 1x2 blocks// before it will create 4x1's.  In total this routine will create 1x2, 2x2, 4x2,// 4x1, and 2x1 blocks sizes, with the potential for two seperate 4x1's or 2x1's// in the upper and lower rasters.void TErnieFilter::Filter2RawRows(unsigned char *currPtr, unsigned char *upPtr, int rowWidthInPixels, unsigned int *flagsPtr){    ASSERT(currPtr);    ASSERT(upPtr);    ASSERT(rowWidthInPixels > 0);    int R0, G0, B0, R1, G1, B1, lastR, lastG, lastB;    const unsigned int maxErrorForFourPixels = fMaxErrorForTwoPixels / 2;    const unsigned int maxErrorForEightPixels = maxErrorForFourPixels / 2;//    int currPixel, upPixel, lastPixel;    uint32_t currPixel, upPixel, lastPixel;    bool lastPairAveraged = false;    bool last2by2Averaged = false;    for (int pixelNum = 0; pixelNum < rowWidthInPixels; pixelNum++)    {        if ((pixelNum & 0x03) == 0x00) // 0,4,8...        {            last2by2Averaged = false; // Reinitialize every four columns;        }        upPixel = get4Pixel(upPtr);        currPixel = get4Pixel(currPtr);        flagsPtr[0] = (e11n|e11s);  // Initialize in case nothing is found for this column        if (isWhite(upPixel) && isWhite(currPixel)) // both white?        {            flagsPtr[0] = eDone;#if kGatherStats == 1            blockStats[esWhiteFound]++;#endif        }        // Do vertical average on the current 2 pixel high column        // Currently we bail entirely if there is white. Later we may still do RLE on the non white pixel if one is present.        if (flagsPtr[0] == (e11n|e11s))        {            R1 = GetRed(currPixel);            G1 = GetGreen(currPixel);            B1 = GetBlue(currPixel);            R0 = GetRed(upPixel);            G0 = GetGreen(upPixel);            B0 = GetBlue(upPixel);            if ((fMaxErrorForTwoPixels >= 3) && (NewDeltaE(R0, R1, G0, G1, B0, B1, fMaxErrorForTwoPixels)))            {                /*   _                    | | build 1x2                    | |                     -                */                ASSERT(flagsPtr[0] == (e11n|e11s));                flagsPtr[0] = e12;#if kGatherStats == 1                blockStats[es12]++;#endif                R1 = GetRed(currPixel);                G1 = GetGreen(currPixel);                B1 = GetBlue(currPixel);                R0 = GetRed(upPixel);                G0 = GetGreen(upPixel);                B0 = GetBlue(upPixel);                AverageNRound(isOdd(pixelNum), R1, R1, R0, G1, G1, G0, B1, B1, B0);                // look for a 2x2 block average on every other column                if (isOdd(pixelNum))                {   // It looks like we are at the end of a 2x2 block                    if (lastPairAveraged)                    {                        // Last pair was averaged so it's ok to try to make a 2x2 block                        if ((maxErrorForFourPixels >= 3) && (NewDeltaE(lastR, R1, lastG, G1,lastB, B1, maxErrorForFourPixels)))                        {                            /* - -                              |   | build 2x2                              |   |                               - -                            */                            ASSERT(flagsPtr[-1] == e12);                            int didNotBuild4by2 = true;#if kGatherStats == 1                            blockStats[es22w]++;#endif                            flagsPtr[-1] = e22w;                            flagsPtr[0] = e22e;                            AverageNRound((pixelNum & 0x02) == 0x02, R1, R1, lastR, G1, G1, lastG, B1, B1, lastB); // 2,3,6,7... Alternate between rounding up and down for these 2x2 blocks                            if ((pixelNum & 0x03) == 0x03)  // 3,7,11,15... Looking for a 4x2 block to average                            {                                if (last2by2Averaged)                                {

⌨️ 快捷键说明

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