//----------------------------------------------------------------------------- // FILE NAME : FUMH2.c // FUNCTION : MH Compress and MH2 Compress // AUTHER : 1996.08.08 FPL)Y.YUTANI // NOTE : for Windows NT V4.0 // MODIFY : Reduce data size Oct.31,1996 H.Ishida // MODIFY : for NT5.0 Minidriver Sep.3,1997 H.Ishida(FPL) //----------------------------------------------------------------------------- // COPYRIGHT(C) FUJITSU LIMITED 1996-1997 #include #include "fuxl.h" #include "fumhdef.h" // NTRAID#NTBUG9-589500-2002/03/29-v-kkon-: Remove dead codes //----------------------------------------------------------------------------- // BOOL SameLineCheck // PBYTE pSrc Pointer of sources bits image // DWORD cSrcX Width size of sources image(byte) // Return code : TRUE Same image line // FALSE Not same image line //----------------------------------------------------------------------------- BOOL SameLineCheck( PBYTE pSrc, DWORD cSrcX ) { DWORD i; PBYTE pLine1, pLine2; pLine1 = pSrc; pLine2 = pSrc + cSrcX; for( i = 0; i < cSrcX; i++ ) { if( *pLine1 != *pLine2 ) return FALSE; pLine1++; pLine2++; } return TRUE; } //----------------------------------------------------------------------------- // DWORD SamePatternCheck // BYTE *pTmp Pointer of sources bits image // DWORD cBitsTmp Bit number from top of sources bits image // DWORD cBitsMax Maximam bit of sources bits image // PATNINFO *pInfo Pointer of Same pattern finormation struction // Rerutn code : Sources bit number //----------------------------------------------------------------------------- DWORD SamePatternCheck( BYTE *pTmp, DWORD cBitsTmp, DWORD cBitsMax, PATNINFO *pInfo ) { DWORD cBits, k; BYTE ptn1, ptn2; DWORD dwPtn; // Initial same pattern number pInfo->dwPatnNum = 1; // Nothing remain bits if( cBitsTmp >= cBitsMax ) return cBitsTmp; // Caluclation sources bytes and bits pTmp += (cBitsTmp / 8); k = cBitsTmp % 8; // If remain bits bolow 16bits, return function if( ( cBitsTmp + 16 ) > cBitsMax ) return cBitsTmp; // Get Top 8bits(bit number is byte baundary?) // NTRAID#NTBUG9-589500-2002/03/29-v-kkon-: Remove dead codes if( k != 0 ) { ptn1 = *pTmp << k; ptn1 |= *(pTmp+1) >> ( 8 - k ); } else { ptn1 = *pTmp; } // If 8bits image is all white or black, return function if( ptn1 == ALL_BLACK || ptn1 == ALL_WHITE ) return cBitsTmp; // Compare top 8bits image and next 8bits image // (Careful same pattern number maximam) for (cBits = cBitsTmp + 8; (cBits + 7 < cBitsMax) && (pInfo->dwPatnNum < SAMEPATN_MAX); cBits += 8 ) { pTmp++; // NTRAID#NTBUG9-589500-2002/03/29-v-kkon-: Remove dead codes if( k != 0 ) { ptn2 = *pTmp << k; ptn2 |= *(pTmp+1) >> ( 8 - k ); } else { ptn2 = *pTmp; } // If top image not iqual next image, stop counting same pattern if( ptn1 != ptn2 ) break; // Same pattern number addition pInfo->dwPatnNum++; } // Nothing same pattern if( pInfo->dwPatnNum == 1 ) return cBitsTmp; // Set pattern pInfo->dwPatn = (DWORD)ptn1; // If bits remain, check joint bit's color and set if( cBits < cBitsMax ) { if ( (*pTmp & (1 << (7 - k)) ) == 0 ) { pInfo->dwNextColor = NEXT_COLOR_WHITE; } else { pInfo->dwNextColor = NEXT_COLOR_BLACK; } } else { pInfo->dwNextColor = NEXT_COLOR_WHITE; } return cBits; } //----------------------------------------------------------------------------- // DWORD Mh2Compress // BYTE *pDest Pointer of destinaition area // DWORD cDestN Size of destination area(byte) // BYTE *pSrc Pointer of sources area // DWORD cSrcN Size of sources area(byte) // DWORD cSrcX Sources image x width // DWORD cSrcY Sources image y height // Return code : Writing size to destination area //----------------------------------------------------------------------------- DWORD Mh2Compress( BYTE *pDest, DWORD cDestN, BYTE *pSrc, DWORD cSrcN, DWORD cSrcX, DWORD cSrcY ) { DWORD cBitsSrc, cBitsSrcMax; DWORD cBitsDest, cBitsDestMax, cBitsDestMark; DWORD cBitsRun; DWORD dwCode, cBits; DWORD i; DWORD dwSameLine; PBYTE pSrcLine; PATNINFO ptnInfo; cBitsDest = 0; cBitsSrc = 0; dwSameLine = 1; cBitsDestMax = cDestN * 8; for (i = 0; i < cSrcY; i++) { // Set initial color ptnInfo.dwNextColor = NEXT_COLOR_WHITE; // Top pointer of now line pSrcLine = pSrc + ( i * cSrcX ); // Now line equal next line image?(No check last line) if( i != ( cSrcY - 1 ) ) { if( SameLineCheck( pSrcLine, cSrcX ) ) { dwSameLine++; cBitsSrc += ( cSrcX * 8 ); if( dwSameLine < SAMELINE_MAX ) continue; } } // Top EOL if (cBitsDest + CBITS_EOL_CODE > cBitsDestMax) return 0; FjBitsCopy(pDest, cBitsDest, EOL_CODE, CBITS_EOL_CODE); cBitsDest += CBITS_EOL_CODE; // There are same lines if( dwSameLine > 1 ) { if (cBitsDest + CBITS_SAMELINE > cBitsDestMax) return 0; // Set same line code FjBitsCopy( pDest, cBitsDest, SAMELINE_CODE, CBITS_SAMELINE_CODE ); cBitsDest += CBITS_SAMELINE_CODE; // Set same line number FjBitsCopy( pDest, cBitsDest, dwSameLine << 8, CBITS_SAMELINE_NUM ); cBitsDest += CBITS_SAMELINE_NUM; // Initial same line number dwSameLine = 1; } // vvv Oct.31,1996 H.Ishida cBitsDestMark = cBitsDest; // ^^^ Oct.31,1996 H.Ishida // Encode cBitsSrcMax = cBitsSrc + (cSrcX * 8); // Compress one line image while ( cBitsSrc < cBitsSrcMax ) { // Check same pattern cBitsSrc = SamePatternCheck( pSrc, cBitsSrc, cBitsSrcMax, &ptnInfo ); // there are same patterns if( ptnInfo.dwPatnNum > 1 ) { if ( ( cBitsDest + CBITS_SAMEPATN ) > cBitsDestMax) return 0; // Set same pattern code FjBitsCopy(pDest, cBitsDest, SAMEPATN_CODE, CBITS_SAMEPATN_CODE ); cBitsDest += CBITS_SAMEPATN_CODE; // Set same pattern image FjBitsCopy(pDest, cBitsDest, ptnInfo.dwPatn << 8, CBITS_SAMEPATN_BYTE ); cBitsDest += CBITS_SAMEPATN_BYTE; ptnInfo.dwPatnNum <<= 5; ptnInfo.dwPatnNum |= ptnInfo.dwNextColor; // Set same pattern number & next run color FjBitsCopy(pDest, cBitsDest, ptnInfo.dwPatnNum, CBITS_SAMEPATN_NUM ); cBitsDest += CBITS_SAMEPATN_NUM; // Unknown same pattern on after here continue; } // Next run is white if( ptnInfo.dwNextColor == NEXT_COLOR_WHITE ) { // Count white bits cBitsRun = FjCountBits(pSrc, cBitsSrc, (cBitsSrcMax - cBitsSrc), TRUE); cBitsSrc += cBitsRun; // vvv Oct.31,1996 H.Ishida // reduce data size if(cBitsSrc >= cBitsSrcMax){ if(cBitsDest > cBitsDestMark) break; cBitsRun = 2; // Whole white line is convert to white 2 dots:Minimun MH data. } // ^^^ Oct.31,1996 H.Ishida // Careful, white run length over maximam while( cBitsRun > RUNLENGTH_MAX ) { dwCode = WhiteMakeUpTable[MAKEUP_TABLE_MAX - 1].wCode; cBits = WhiteMakeUpTable[MAKEUP_TABLE_MAX - 1].cBits; if (cBitsDest + cBits > cBitsDestMax) return 0; FjBitsCopy(pDest, cBitsDest, dwCode, cBits); cBitsDest += cBits; cBitsRun -= RUNLENGTH_MAX; } if (cBitsRun >= 64) { dwCode = WhiteMakeUpTable[(cBitsRun / TERMINATE_MAX) - 1].wCode; cBits = WhiteMakeUpTable[(cBitsRun / TERMINATE_MAX) - 1].cBits; if (cBitsDest + cBits > cBitsDestMax) return 0; FjBitsCopy(pDest, cBitsDest, dwCode, cBits); cBitsDest += cBits; } dwCode = WhiteTerminateTable[cBitsRun % TERMINATE_MAX].wCode; cBits = WhiteTerminateTable[cBitsRun % TERMINATE_MAX].cBits; if (cBitsDest + cBits > cBitsDestMax) return 0; FjBitsCopy(pDest, cBitsDest, dwCode, cBits); cBitsDest += cBits; ptnInfo.dwNextColor = NEXT_COLOR_BLACK; } else { // Black bits cBitsRun = FjCountBits(pSrc, cBitsSrc, (cBitsSrcMax - cBitsSrc), FALSE); cBitsSrc += cBitsRun; // Careful, black run length over maximam while( cBitsRun > RUNLENGTH_MAX ) { dwCode = BlackMakeUpTable[MAKEUP_TABLE_MAX - 1].wCode; cBits = BlackMakeUpTable[MAKEUP_TABLE_MAX - 1].cBits; if (cBitsDest + cBits > cBitsDestMax) return 0; FjBitsCopy(pDest, cBitsDest, dwCode, cBits); cBitsDest += cBits; cBitsRun -= RUNLENGTH_MAX; } if (cBitsRun >= 64) { dwCode = BlackMakeUpTable[(cBitsRun / TERMINATE_MAX) - 1].wCode; cBits = BlackMakeUpTable[(cBitsRun / TERMINATE_MAX) - 1].cBits; if (cBitsDest + cBits > cBitsDestMax) return 0; FjBitsCopy(pDest, cBitsDest, dwCode, cBits); cBitsDest += cBits; } dwCode = BlackTerminateTable[cBitsRun % TERMINATE_MAX].wCode; cBits = BlackTerminateTable[cBitsRun % TERMINATE_MAX].cBits; if (cBitsDest + cBits > cBitsDestMax) return 0; FjBitsCopy(pDest, cBitsDest, dwCode, cBits); cBitsDest += cBits; ptnInfo.dwNextColor = NEXT_COLOR_WHITE; } } // End of one raster } // Last EOL. if (cBitsDest + CBITS_EOL_CODE > cBitsDestMax) return 0; FjBitsCopy(pDest, cBitsDest, EOL_CODE, CBITS_EOL_CODE); cBitsDest += CBITS_EOL_CODE; // Pad with 0 until byte boundary if ((cBits = (8 - (cBitsDest % 8)) % 8) != 0) { if (cBitsDest + cBits > cBitsDestMax) return 0; FjBitsCopy(pDest, cBitsDest, FILL_CODE, cBits); cBitsDest += cBits; } return cBitsDest / 8; } // end of FUMH2.c