Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

962 lines
45 KiB

/****************************************************************************
CONVOLUT.C
$Log: S:\oiwh\display\convolut.c_v $
*
* Rev 1.1 06 Feb 1996 10:54:16 BLJ
* Added convolution functionality.
*
* Rev 1.0 31 Jan 1996 11:23:50 BLJ
* Added convolution functionality.
*
*
****************************************************************************/
#include "privdisp.h"
//
/****************************************************************************
FUNCTION: Convolution
PURPOSE: This routine performs a convolution on an image.
****************************************************************************/
int WINAPI Convolution(PIMAGE pImage, PCONVOLUTION pConvolution){
int nStatus = 0;
PIMG pSrceImg = 0;
PIMG pDestImg = 0;
PBYTE pLine1;
PBYTE pLine2;
PBYTE pLine3;
PBYTE pLine4;
PBYTE pLine5;
PBYTE pLine1L = 0;
PBYTE pLine2L = 0;
PBYTE pLine3L = 0;
PBYTE pLine4L = 0;
PBYTE pLine5L = 0;
PBYTE pDestLine;
int nLine1Data;
int nLine2Data;
int nLine3Data;
int nLine4Data;
int nLine5Data;
PBYTE pFirstByte;
PBYTE pLastByte;
int nWidthBytes;
int nLine;
int nByte;
PBYTE pTemp;
int nMask;
int nLine1Table[256];
int nLine2Table[256];
int nLine3Table[256];
int nLine4Table[256];
int nLine5Table[256];
int nLoop;
int nDestBit0;
int nDestBit1;
int nDestBit2;
int nDestBit3;
int nDestBit4;
int nDestBit5;
int nDestBit6;
int nDestBit7;
int nConvMatrix[31][25] = {{0}, /* Place holder for user defined matrix. */
{1,1,1,1,1,1,1,1,1}, /* CONVOLUTION_LOW_PASS1 */
{1,1,1,1,2,1,1,1,1}, /* CONVOLUTION_LOW_PASS2 */
{1,2,1,2,4,2,1,2,1}, /* CONVOLUTION_LOW_PASS3 */
{-1,-1,-1,-1,9,-1,-1,-1,-1}, /* CONVOLUTION_HIGH_PASS1 */
{0,-1,0,-1,5,-1,0,-1,0}, /* CONVOLUTION_HIGH_PASS2 */
{1,-2,1,-2,5,-2,1,-2,1}, /* CONVOLUTION_HIGH_PASS3 */
{0,0,0,-1,1,0,0,0,0}, /* CONVOLUTION_VERTICAL_EDGE1 */
{0,-1,0,1,0,0,-1,0,1,0,0,-1,0,1,0,0,-1,0,1,0,0,-1,0,1,0}, /* CONVOLUTION_VERTICAL_EDGE2 */
{0,-1,0,0,1,0,0,0,0}, /* CONVOLUTION_HORIZONTAL_EDGE1 */
{0,0,0,0,0,-1,-1,-1,-1,-1,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0}, /* CONVOLUTION_HORIZONTAL_EDGE2 */
{-1,0,0,0,1,0,0,0,0}, /* CONVOLUTION_HORZ_AND_VERT_EDGE */
{1,1,1,1,-2,1,-1,-1,-1}, /* CONVOLUTION_DIRECTIONAL_EDGE_N */
{1,1,1,-1,-2,1,-1,-1,1}, /* CONVOLUTION_DIRECTIONAL_EDGE_NE */
{-1,1,1,-1,-2,1,-1,1,1}, /* CONVOLUTION_DIRECTIONAL_EDGE_E */
{-1,-1,1,-1,-2,1,1,1,1}, /* CONVOLUTION_DIRECTIONAL_EDGE_SE */
{-1,-1,-1,1,-2,1,1,1,1}, /* CONVOLUTION_DIRECTIONAL_EDGE_S */
{1,-1,-1,1,-2,-1,1,1,1}, /* CONVOLUTION_DIRECTIONAL_EDGE_SW */
{1,1,-1,1,-2,-1,1,1,-1}, /* CONVOLUTION_DIRECTIONAL_EDGE_W */
{1,1,1,1,-2,-1,1,-1,-1}, /* CONVOLUTION_DIRECTIONAL_EDGE_NW */
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}, /* CONVOLUTION_BLUR */
{0,1,0,1,-4,1,0,1,0}, /* CONVOLUTION_LAPLACE_EDGE1 */
{-1,-1,-1,-1,8,-1,-1,-1,-1}, /* CONVOLUTION_LAPLACE_EDGE2 */
{-1,-1,-1,-1,9,-1,-1,-1,-1}, /* CONVOLUTION_LAPLACE_EDGE3 */
{1,-2,1,-2,4,-2,1,-2,1}, /* CONVOLUTION_LAPLACE_EDGE4 */
{1,0,0,0,1,0,0,0,0}, /* BW_EMBOLDEN1 */
{1,1,0,1,1,0,0,0,0}, /* BW_EMBOLDEN2 */
{1,1,1,1,1,1,1,1,1}, /* BW_EMBOLDEN3 */
{0,0,0,0,1,0,0,0,1}, /* BW_LIGHTEN1 */
{0,0,0,0,1,1,0,1,1}, /* BW_LIGHTEN2 */
{1,1,1,1,1,1,1,1,1}, /* BW_LIGHTEN3 */
};
int nConvSize[31] = {5,3,3,3,3,3,3,3,5,3, /* 0-9 */
5,3,3,3,3,3,3,3,3,3, /* 10-19 */
5,3,3,3,3,3,3,3,3,3, /* 20-29 */
3}; /* 30 */
int nConvDivider[31] = {0,9,10,16,1,1,1,1,1,1, /* 0-9 */
1,1,1,1,1,1,1,1,1,1, /* 10-19 */
25,1,1,1,1,1,1,1,1,1, /* 20-29 */
1}; /* 30 */
BOOL bConvAbsolute[31] = {0,0,0,0,0,0,0,1,1,1, /* 0-9 */
1,1,1,1,1,1,1,1,1,1, /* 10-19 */
0,1,1,0,1,0,0,0,0,0, /* 20-29 */
0}; /* 30 */
BOOL nConvAdder[31] = {0,0,0,0,0,0,0,0,0,0, /* 0-9 */
0,0,0,0,0,0,0,0,0,0, /* 10-19 */
0,0,0,0,0,-1,-3,-8,0,0, /* 20-29 */
0}; /* 30 */
int nMatrix[25];
BOOL bSize;
int nDivider;
int nHalfDividerPlusAdder;
BOOL bAbsolute;
int nAdder;
int nLineSize;
int nLineIndex;
if (!pConvolution){
nStatus = Error(DISPLAY_NULLPOINTERINVALID);
goto Exit;
}
if (!(pSrceImg = pImage->pImg)){
nStatus = Error(DISPLAY_IMAGETYPENOTSUPPORTED);
goto Exit;
}
switch (pSrceImg->nType){
case ITYPE_PAL4:
case ITYPE_CUSPAL8:
case ITYPE_COMPAL8:
nStatus = Error(DISPLAY_INVALIDOPFORPALIMAGE);
goto Exit;
case ITYPE_BI_LEVEL:
case ITYPE_GRAY4:
case ITYPE_GRAY8:
case ITYPE_RGB24:
case ITYPE_BGR24:
default:
break;
}
if (nStatus = CreateAnyImgBuf(&pDestImg, pSrceImg->nWidth,
pSrceImg->nHeight, pSrceImg->nType)){
goto Exit;
}
if (pConvolution->nType){ // If a predefined convolution.
memcpy(nMatrix, nConvMatrix[pConvolution->nType], sizeof(int) * 25);
nDivider = nConvDivider[pConvolution->nType];
bAbsolute = bConvAbsolute[pConvolution->nType];
nAdder = nConvAdder[pConvolution->nType];
bSize = nConvSize[pConvolution->nType];
}else{ // If user defined convolution.
memcpy(nMatrix, pConvolution->nMatrix, sizeof(int) * 25);
nDivider = pConvolution->nDivider;
bAbsolute = pConvolution->bAbsolute;
nAdder = pConvolution->nAdder;
if (!nMatrix[0] && !nMatrix[1] && !nMatrix[2] && !nMatrix[3] && !nMatrix[4]
&& !nMatrix[5] && !nMatrix[9] && !nMatrix[10] && !nMatrix[14] && !nMatrix[15] && !nMatrix[19]
&& !nMatrix[20] && !nMatrix[21] && !nMatrix[22] && !nMatrix[23] && !nMatrix[24]){
bSize = 3;
nMatrix[0] = nMatrix[6];
nMatrix[1] = nMatrix[7];
nMatrix[2] = nMatrix[8];
nMatrix[3] = nMatrix[11];
nMatrix[4] = nMatrix[12];
nMatrix[5] = nMatrix[13];
nMatrix[6] = nMatrix[16];
nMatrix[7] = nMatrix[17];
nMatrix[8] = nMatrix[18];
}else{
bSize = 5;
}
}
// To allow for roundoffs multiply everything by 256, and add 128 to the adder.
for (nLoop = 0; nLoop < 25; nLoop++){
nMatrix[nLoop] *= 256;
}
nHalfDividerPlusAdder = (((nDivider / 2) + nAdder) * 256) + 128;
nDivider *= 256;
switch (pSrceImg->nType){
/*
BW(){
*/
case ITYPE_BI_LEVEL:
// Operation must be performed a pixel at a time.
// Therefore the pixel in question will always be pixel 2 (0x20).
// Generate the pattern tables.
if (bSize == 3){
for (nLoop = 0; nLoop < 256; nLoop++){
if (nLoop & 0x40){
nLine2Table[nLoop] = nMatrix[0];
nLine3Table[nLoop] = nMatrix[3];
nLine4Table[nLoop] = nMatrix[6];
}else{
nLine2Table[nLoop] = 0;
nLine3Table[nLoop] = 0;
nLine4Table[nLoop] = 0;
}
if (nLoop & 0x20){
nLine2Table[nLoop] += nMatrix[1];
nLine3Table[nLoop] += nMatrix[4];
nLine4Table[nLoop] += nMatrix[7];
}
if (nLoop & 0x10){
nLine2Table[nLoop] += nMatrix[2];
nLine3Table[nLoop] += nMatrix[5];
nLine4Table[nLoop] += nMatrix[8];
}
}
}else{ // Conv size == 5.
for (nLoop = 0; nLoop < 256; nLoop++){
if (nLoop & 0x80){
nLine1Table[nLoop] = nMatrix[0];
nLine2Table[nLoop] = nMatrix[5];
nLine3Table[nLoop] = nMatrix[10];
nLine4Table[nLoop] = nMatrix[15];
nLine5Table[nLoop] = nMatrix[20];
}else{
nLine1Table[nLoop] = 0;
nLine2Table[nLoop] = 0;
nLine3Table[nLoop] = 0;
nLine4Table[nLoop] = 0;
nLine5Table[nLoop] = 0;
}
if (nLoop & 0x40){
nLine1Table[nLoop] += nMatrix[1];
nLine2Table[nLoop] += nMatrix[6];
nLine3Table[nLoop] += nMatrix[11];
nLine4Table[nLoop] += nMatrix[16];
nLine5Table[nLoop] += nMatrix[21];
}
if (nLoop & 0x20){
nLine1Table[nLoop] += nMatrix[2];
nLine2Table[nLoop] += nMatrix[7];
nLine3Table[nLoop] += nMatrix[12];
nLine4Table[nLoop] += nMatrix[17];
nLine5Table[nLoop] += nMatrix[22];
}
if (nLoop & 0x10){
nLine1Table[nLoop] += nMatrix[3];
nLine2Table[nLoop] += nMatrix[8];
nLine3Table[nLoop] += nMatrix[13];
nLine4Table[nLoop] += nMatrix[18];
nLine5Table[nLoop] += nMatrix[23];
}
if (nLoop & 0x08){
nLine1Table[nLoop] += nMatrix[4];
nLine2Table[nLoop] += nMatrix[9];
nLine3Table[nLoop] += nMatrix[14];
nLine4Table[nLoop] += nMatrix[19];
nLine5Table[nLoop] += nMatrix[24];
}
}
}
nWidthBytes = pSrceImg->nBytesPerLine;
pFirstByte = &pSrceImg->bImageData[0];
pLastByte = &pSrceImg->bImageData[0] + (nWidthBytes * pImage->nHeight) - 1;
// Set the unused data at the end of the line to white.
if (pImage->nWidth & 7){
switch (pImage->nWidth & 7){
case 1: nMask = 0x7f; break;
case 2: nMask = 0x3f; break;
case 3: nMask = 0x1f; break;
case 4: nMask = 0x0f; break;
case 5: nMask = 0x07; break;
case 6: nMask = 0x03; break;
case 7: nMask = 0x01; break;
}
for (nLine = 0; nLine < (int) pImage->nHeight; nLine++){
pTemp = &pSrceImg->bImageData[0] + (nWidthBytes * (nLine + 1)) - 1;
*pTemp |= nMask;
}
}
// Do the actual convolution.
if (bSize == 3){
for (nLine = 0; nLine < (int) pImage->nHeight; nLine++){
pLine3 = &pSrceImg->bImageData[0] + (nWidthBytes * nLine);
pLine2 = pLine3 - nWidthBytes;
pLine4 = pLine3 + nWidthBytes;
pDestLine = &pDestImg->bImageData[0] + (nWidthBytes * nLine);
// All pLine# variables may not point to valid data.
// Initialize all data to white.
if (pLine2 >= pFirstByte){
nLine2Data = *(pLine2++) | 0xffffff00;
}else{
nLine2Data = 0xffffffff;
}
nLine3Data = *(pLine3++) | 0xffffff00;
if (pLine4 <= pLastByte){
nLine4Data = *(pLine4++) | 0xffffff00;
}else{
nLine4Data = 0xffffffff;
}
for (nByte = nWidthBytes; nByte; nByte--){
if (pLine2 >= pFirstByte && nByte > 1){
nLine2Data = (nLine2Data << 8) | *(pLine2++);
}else{
nLine2Data = (nLine2Data << 8) | 0x0ff;
}
if (nByte > 1){
nLine3Data = (nLine3Data << 8) | *(pLine3++);
}else{
nLine3Data = (nLine3Data << 8) | 0x0ff;
}
if (pLine4 <= pLastByte && nByte > 1){
nLine4Data = (nLine4Data << 8) | *(pLine4++);
}else{
nLine4Data = (nLine4Data << 8) | 0x0ff;
}
// nLinexData = xxppccnn where: xx = garbage,
// pp = previous byte, cc=current byte, and nn = next byte.
nDestBit0 = nLine2Table[(nLine2Data >> 10) & 0x0ff]
+ nLine3Table[(nLine3Data >> 10) & 0x0ff]
+ nLine4Table[(nLine4Data >> 10) & 0x0ff];
nDestBit1 = nLine2Table[(nLine2Data >> 9) & 0x0ff]
+ nLine3Table[(nLine3Data >> 9) & 0x0ff]
+ nLine4Table[(nLine4Data >> 9) & 0x0ff];
nDestBit2 = nLine2Table[(nLine2Data >> 8) & 0x0ff]
+ nLine3Table[(nLine3Data >> 8) & 0x0ff]
+ nLine4Table[(nLine4Data >> 8) & 0x0ff];
nDestBit3 = nLine2Table[(nLine2Data >> 7) & 0x0ff]
+ nLine3Table[(nLine3Data >> 7) & 0x0ff]
+ nLine4Table[(nLine4Data >> 7) & 0x0ff];
nDestBit4 = nLine2Table[(nLine2Data >> 6) & 0x0ff]
+ nLine3Table[(nLine3Data >> 6) & 0x0ff]
+ nLine4Table[(nLine4Data >> 6) & 0x0ff];
nDestBit5 = nLine2Table[(nLine2Data >> 5) & 0x0ff]
+ nLine3Table[(nLine3Data >> 5) & 0x0ff]
+ nLine4Table[(nLine4Data >> 5) & 0x0ff];
nDestBit6 = nLine2Table[(nLine2Data >> 4) & 0x0ff]
+ nLine3Table[(nLine3Data >> 4) & 0x0ff]
+ nLine4Table[(nLine4Data >> 4) & 0x0ff];
nDestBit7 = nLine2Table[(nLine2Data >> 3) & 0x0ff]
+ nLine3Table[(nLine3Data >> 3) & 0x0ff]
+ nLine4Table[(nLine4Data >> 3) & 0x0ff];
if (bAbsolute){
nDestBit0 = abs(nDestBit0);
nDestBit1 = abs(nDestBit1);
nDestBit2 = abs(nDestBit2);
nDestBit3 = abs(nDestBit3);
nDestBit4 = abs(nDestBit4);
nDestBit5 = abs(nDestBit5);
nDestBit6 = abs(nDestBit6);
nDestBit7 = abs(nDestBit7);
}
nDestBit0 = max(0, min(1,((nDestBit0 + nHalfDividerPlusAdder) / nDivider) )) << 7;
nDestBit1 = max(0, min(1,((nDestBit1 + nHalfDividerPlusAdder) / nDivider) )) << 6;
nDestBit2 = max(0, min(1,((nDestBit2 + nHalfDividerPlusAdder) / nDivider) )) << 5;
nDestBit3 = max(0, min(1,((nDestBit3 + nHalfDividerPlusAdder) / nDivider) )) << 4;
nDestBit4 = max(0, min(1,((nDestBit4 + nHalfDividerPlusAdder) / nDivider) )) << 3;
nDestBit5 = max(0, min(1,((nDestBit5 + nHalfDividerPlusAdder) / nDivider) )) << 2;
nDestBit6 = max(0, min(1,((nDestBit6 + nHalfDividerPlusAdder) / nDivider) )) << 1;
nDestBit7 = max(0, min(1,((nDestBit7 + nHalfDividerPlusAdder) / nDivider) )) << 0;
*(pDestLine++) = nDestBit0 | nDestBit1 | nDestBit2 | nDestBit3
| nDestBit4 | nDestBit5 | nDestBit6 | nDestBit7;
}
}
}else{ // Conv size == 5.
for (nLine = 0; nLine < (int) pImage->nHeight; nLine++){
pLine3 = &pSrceImg->bImageData[0] + (nWidthBytes * nLine);
pLine1 = pLine3 - (nWidthBytes * 2);
pLine2 = pLine3 - nWidthBytes;
pLine4 = pLine3 + nWidthBytes;
pLine5 = pLine3 + (nWidthBytes * 2);
pDestLine = &pDestImg->bImageData[0] + (nWidthBytes * nLine);
// All pLine# variables may not point to valid data.
// Initialize all data to white.
if (pLine1 >= pFirstByte){
nLine1Data = *(pLine1++) | 0xffffff00;
}else{
nLine1Data = 0xffffffff;
}
if (pLine2 >= pFirstByte){
nLine2Data = *(pLine2++) | 0xffffff00;
}else{
nLine2Data = 0xffffffff;
}
nLine3Data = *(pLine3++) | 0xffffff00;
if (pLine4 <= pLastByte){
nLine4Data = *(pLine4++) | 0xffffff00;
}else{
nLine4Data = 0xffffffff;
}
if (pLine5 <= pLastByte){
nLine5Data = *(pLine5++) | 0xffffff00;
}else{
nLine5Data = 0xffffffff;
}
for (nByte = nWidthBytes; nByte; nByte--){
if (pLine1 >= pFirstByte && nByte > 1){
nLine1Data = (nLine1Data << 8) | *(pLine1++);
}else{
nLine1Data = (nLine1Data << 8) | 0x0ff;
}
if (pLine2 >= pFirstByte && nByte > 1){
nLine2Data = (nLine2Data << 8) | *(pLine2++);
}else{
nLine2Data = (nLine2Data << 8) | 0x0ff;
}
if (nByte > 1){
nLine3Data = (nLine3Data << 8) | *(pLine3++);
}else{
nLine3Data = (nLine3Data << 8) | 0x0ff;
}
if (pLine4 <= pLastByte && nByte > 1){
nLine4Data = (nLine4Data << 8) | *(pLine4++);
}else{
nLine4Data = (nLine4Data << 8) | 0x0ff;
}
if (pLine5 <= pLastByte && nByte > 1){
nLine5Data = (nLine5Data << 8) | *(pLine5++);
}else{
nLine5Data = (nLine5Data << 8) | 0x0ff;
}
// nLinexData = xxppccnn where: xx = garbage,
// pp = previous byte, cc=current byte, and nn = next byte.
nDestBit0 = nLine1Table[(nLine1Data >> 10) & 0x0ff]
+ nLine2Table[(nLine2Data >> 10) & 0x0ff]
+ nLine3Table[(nLine3Data >> 10) & 0x0ff]
+ nLine4Table[(nLine4Data >> 10) & 0x0ff]
+ nLine5Table[(nLine5Data >> 10) & 0x0ff];
nDestBit1 = nLine1Table[(nLine1Data >> 9) & 0x0ff]
+ nLine2Table[(nLine2Data >> 9) & 0x0ff]
+ nLine3Table[(nLine3Data >> 9) & 0x0ff]
+ nLine4Table[(nLine4Data >> 9) & 0x0ff]
+ nLine5Table[(nLine5Data >> 9) & 0x0ff];
nDestBit2 = nLine1Table[(nLine1Data >> 8) & 0x0ff]
+ nLine2Table[(nLine2Data >> 8) & 0x0ff]
+ nLine3Table[(nLine3Data >> 8) & 0x0ff]
+ nLine4Table[(nLine4Data >> 8) & 0x0ff]
+ nLine5Table[(nLine5Data >> 8) & 0x0ff];
nDestBit3 = nLine1Table[(nLine1Data >> 7) & 0x0ff]
+ nLine2Table[(nLine2Data >> 7) & 0x0ff]
+ nLine3Table[(nLine3Data >> 7) & 0x0ff]
+ nLine4Table[(nLine4Data >> 7) & 0x0ff]
+ nLine5Table[(nLine5Data >> 7) & 0x0ff];
nDestBit4 = nLine1Table[(nLine1Data >> 6) & 0x0ff]
+ nLine2Table[(nLine2Data >> 6) & 0x0ff]
+ nLine3Table[(nLine3Data >> 6) & 0x0ff]
+ nLine4Table[(nLine4Data >> 6) & 0x0ff]
+ nLine5Table[(nLine5Data >> 6) & 0x0ff];
nDestBit5 = nLine1Table[(nLine1Data >> 5) & 0x0ff]
+ nLine2Table[(nLine2Data >> 5) & 0x0ff]
+ nLine3Table[(nLine3Data >> 5) & 0x0ff]
+ nLine4Table[(nLine4Data >> 5) & 0x0ff]
+ nLine5Table[(nLine5Data >> 5) & 0x0ff];
nDestBit6 = nLine1Table[(nLine1Data >> 4) & 0x0ff]
+ nLine2Table[(nLine2Data >> 4) & 0x0ff]
+ nLine3Table[(nLine3Data >> 4) & 0x0ff]
+ nLine4Table[(nLine4Data >> 4) & 0x0ff]
+ nLine5Table[(nLine5Data >> 4) & 0x0ff];
nDestBit7 = nLine1Table[(nLine1Data >> 3) & 0x0ff]
+ nLine2Table[(nLine2Data >> 3) & 0x0ff]
+ nLine3Table[(nLine3Data >> 3) & 0x0ff]
+ nLine4Table[(nLine4Data >> 3) & 0x0ff]
+ nLine5Table[(nLine5Data >> 3) & 0x0ff];
if (bAbsolute){
nDestBit0 = abs(nDestBit0);
nDestBit1 = abs(nDestBit1);
nDestBit2 = abs(nDestBit2);
nDestBit3 = abs(nDestBit3);
nDestBit4 = abs(nDestBit4);
nDestBit5 = abs(nDestBit5);
nDestBit6 = abs(nDestBit6);
nDestBit7 = abs(nDestBit7);
}
nDestBit0 = max(0, min(1,((nDestBit0 + nHalfDividerPlusAdder) / nDivider) )) << 7;
nDestBit1 = max(0, min(1,((nDestBit1 + nHalfDividerPlusAdder) / nDivider) )) << 6;
nDestBit2 = max(0, min(1,((nDestBit2 + nHalfDividerPlusAdder) / nDivider) )) << 5;
nDestBit3 = max(0, min(1,((nDestBit3 + nHalfDividerPlusAdder) / nDivider) )) << 4;
nDestBit4 = max(0, min(1,((nDestBit4 + nHalfDividerPlusAdder) / nDivider) )) << 3;
nDestBit5 = max(0, min(1,((nDestBit5 + nHalfDividerPlusAdder) / nDivider) )) << 2;
nDestBit6 = max(0, min(1,((nDestBit6 + nHalfDividerPlusAdder) / nDivider) )) << 1;
nDestBit7 = max(0, min(1,((nDestBit7 + nHalfDividerPlusAdder) / nDivider) )) << 0;
*(pDestLine++) = nDestBit0 | nDestBit1 | nDestBit2 | nDestBit3
| nDestBit4 | nDestBit5 | nDestBit6 | nDestBit7;
}
}
}
break;
/*
Gray4(){
*/
case ITYPE_GRAY4:
nWidthBytes = pSrceImg->nBytesPerLine;
pFirstByte = &pSrceImg->bImageData[0];
pLastByte = &pSrceImg->bImageData[0] + (nWidthBytes * pImage->nHeight) - 1;
nLineSize = nWidthBytes + 2;
if (nStatus = AllocateMemory(nLineSize, (PPSTR) &pLine1L, NO_INIT)){
goto Exit;
}
if (nStatus = AllocateMemory(nLineSize, (PPSTR) &pLine2L, NO_INIT)){
goto Exit;
}
if (nStatus = AllocateMemory(nLineSize, (PPSTR) &pLine3L, NO_INIT)){
goto Exit;
}
if (nStatus = AllocateMemory(nLineSize, (PPSTR) &pLine4L, NO_INIT)){
goto Exit;
}
if (nStatus = AllocateMemory(nLineSize, (PPSTR) &pLine5L, NO_INIT)){
goto Exit;
}
memset(pLine1L, 0x0ff, nLineSize);
memset(pLine2L, 0x0ff, nLineSize);
memset(pLine3L, 0x0ff, nLineSize);
memset(pLine4L, 0x0ff, nLineSize);
memset(pLine5L, 0x0ff, nLineSize);
if (pImage->nHeight > 1){
memcpy(pLine4L + 1, &pSrceImg->bImageData[0], nWidthBytes);
}
if (pImage->nHeight > 1 && bSize == 5){
memcpy(pLine5L + 1, &pSrceImg->bImageData[0] + nWidthBytes, nWidthBytes);
}
nLineIndex = 0;
// Do the actual convolution.
if (bSize == 3){
for (nLine = 0; nLine < (int) pImage->nHeight; nLine++){
// Move the data into the local arrays.
switch (nLineIndex++){
case 0:
pLine2 = pLine3L;
pLine3 = pLine4L;
pLine4 = pLine2L;
nLineIndex = 1;
break;
case 1:
pLine2 = pLine4L;
pLine3 = pLine2L;
pLine4 = pLine3L;
nLineIndex = 2;
break;
case 2:
pLine2 = pLine2L;
pLine3 = pLine3L;
pLine4 = pLine4L;
nLineIndex = 0;
break;
}
if (nLine < (pImage->nHeight - 1)){
memcpy(pLine4 + 1, &pSrceImg->bImageData[0] + (nWidthBytes * (nLine + 1)), nWidthBytes);
}else{
memset(pLine4 + 1, 0x0ff, nWidthBytes);
}
pDestLine = &pDestImg->bImageData[0] + (nWidthBytes * nLine);
for (nByte = nWidthBytes; nByte; nByte--){
nDestBit0 = (((*(pLine2 ) ) & 0x0f) * nMatrix[0])
+ (((*(pLine2 + 1) >> 4) & 0x0f) * nMatrix[1])
+ (((*(pLine2 + 1) ) & 0x0f) * nMatrix[2])
+ (((*(pLine3 ) ) & 0x0f) * nMatrix[3])
+ (((*(pLine3 + 1) >> 4) & 0x0f) * nMatrix[4])
+ (((*(pLine3 + 1) ) & 0x0f) * nMatrix[5])
+ (((*(pLine4 ) ) & 0x0f) * nMatrix[6])
+ (((*(pLine4 + 1) >> 4) & 0x0f) * nMatrix[7])
+ (((*(pLine4 + 1) ) & 0x0f) * nMatrix[8]);
nDestBit1 = (((*(pLine2 + 1) >> 4) & 0x0f) * nMatrix[0])
+ (((*(pLine2 + 1) ) & 0x0f) * nMatrix[1])
+ (((*(pLine2 + 2) >> 4) & 0x0f) * nMatrix[2])
+ (((*(pLine3 + 1) >> 4) & 0x0f) * nMatrix[3])
+ (((*(pLine3 + 1) ) & 0x0f) * nMatrix[4])
+ (((*(pLine3 + 2) >> 4) & 0x0f) * nMatrix[5])
+ (((*(pLine4 + 1) >> 4) & 0x0f) * nMatrix[6])
+ (((*(pLine4 + 1) ) & 0x0f) * nMatrix[7])
+ (((*(pLine4 + 2) >> 4) & 0x0f) * nMatrix[8]);
pLine2++;
pLine3++;
pLine4++;
if (bAbsolute){
nDestBit0 = abs(nDestBit0);
nDestBit1 = abs(nDestBit1);
}
*(pDestLine++) = ((max(0, min(15,((nDestBit0 + nHalfDividerPlusAdder) / nDivider))) << 4) & 0xf0)
| ((max(0, min(15,((nDestBit1 + nHalfDividerPlusAdder) / nDivider)))) & 0x0f);
}
}
}else{ // Conv size == 5.
for (nLine = 0; nLine < (int) pImage->nHeight; nLine++){
// Move the data into the local arrays.
switch (nLineIndex++){
case 0:
pLine1 = pLine2L;
pLine2 = pLine3L;
pLine3 = pLine4L;
pLine4 = pLine5L;
pLine5 = pLine1L;
nLineIndex = 1;
break;
case 1:
pLine1 = pLine3L;
pLine2 = pLine4L;
pLine3 = pLine5L;
pLine4 = pLine1L;
pLine5 = pLine2L;
nLineIndex = 2;
break;
case 2:
pLine1 = pLine4L;
pLine2 = pLine5L;
pLine3 = pLine1L;
pLine4 = pLine2L;
pLine5 = pLine3L;
nLineIndex = 3;
break;
case 3:
pLine1 = pLine5L;
pLine2 = pLine1L;
pLine3 = pLine2L;
pLine4 = pLine3L;
pLine5 = pLine4L;
nLineIndex = 4;
case 4:
pLine1 = pLine1L;
pLine2 = pLine2L;
pLine3 = pLine3L;
pLine4 = pLine4L;
pLine5 = pLine5L;
nLineIndex = 0;
}
if (nLine < (pImage->nHeight - 2)){
memcpy(pLine5 + 1, &pSrceImg->bImageData[0] + (nWidthBytes * (nLine + 2)), nWidthBytes);
}else{
memset(pLine5 + 1, 0x0ff, nWidthBytes);
}
pDestLine = &pDestImg->bImageData[0] + (nWidthBytes * nLine);
for (nByte = nWidthBytes; nByte; nByte--){
nDestBit0 = (((*(pLine1 ) >> 4) & 0x0f) * nMatrix[0])
+ (((*(pLine1 ) ) & 0x0f) * nMatrix[1])
+ (((*(pLine1 + 1) >> 4) & 0x0f) * nMatrix[2])
+ (((*(pLine1 + 1) ) & 0x0f) * nMatrix[3])
+ (((*(pLine1 + 2) >> 4) & 0x0f) * nMatrix[4])
+ (((*(pLine2 ) >> 4) & 0x0f) * nMatrix[5])
+ (((*(pLine2 ) ) & 0x0f) * nMatrix[6])
+ (((*(pLine2 + 1) >> 4) & 0x0f) * nMatrix[7])
+ (((*(pLine2 + 1) ) & 0x0f) * nMatrix[8])
+ (((*(pLine2 + 2) >> 4) & 0x0f) * nMatrix[9])
+ (((*(pLine3 ) >> 4) & 0x0f) * nMatrix[10])
+ (((*(pLine3 ) ) & 0x0f) * nMatrix[11])
+ (((*(pLine3 + 1) >> 4) & 0x0f) * nMatrix[12])
+ (((*(pLine3 + 1) ) & 0x0f) * nMatrix[13])
+ (((*(pLine3 + 2) >> 4) & 0x0f) * nMatrix[14])
+ (((*(pLine4 ) >> 4) & 0x0f) * nMatrix[15])
+ (((*(pLine4 ) ) & 0x0f) * nMatrix[16])
+ (((*(pLine4 + 1) >> 4) & 0x0f) * nMatrix[17])
+ (((*(pLine4 + 1) ) & 0x0f) * nMatrix[18])
+ (((*(pLine4 + 2) >> 4) & 0x0f) * nMatrix[19])
+ (((*(pLine5 ) >> 4) & 0x0f) * nMatrix[20])
+ (((*(pLine5 ) ) & 0x0f) * nMatrix[21])
+ (((*(pLine5 + 1) >> 4) & 0x0f) * nMatrix[22])
+ (((*(pLine5 + 1) ) & 0x0f) * nMatrix[23])
+ (((*(pLine5 + 2) >> 4) & 0x0f) * nMatrix[24]);
nDestBit1 = (((*(pLine1 ) ) & 0x0f) * nMatrix[0])
+ (((*(pLine1 + 1) >> 4) & 0x0f) * nMatrix[1])
+ (((*(pLine1 + 1) ) & 0x0f) * nMatrix[2])
+ (((*(pLine1 + 2) >> 4) & 0x0f) * nMatrix[3])
+ (((*(pLine1 + 2) ) & 0x0f) * nMatrix[4])
+ (((*(pLine2 ) ) & 0x0f) * nMatrix[5])
+ (((*(pLine2 + 1) >> 4) & 0x0f) * nMatrix[6])
+ (((*(pLine2 + 1) ) & 0x0f) * nMatrix[7])
+ (((*(pLine2 + 2) >> 4) & 0x0f) * nMatrix[8])
+ (((*(pLine2 + 2) ) & 0x0f) * nMatrix[9])
+ (((*(pLine3 ) ) & 0x0f) * nMatrix[10])
+ (((*(pLine3 + 1) >> 4) & 0x0f) * nMatrix[11])
+ (((*(pLine3 + 1) ) & 0x0f) * nMatrix[12])
+ (((*(pLine3 + 2) >> 4) & 0x0f) * nMatrix[13])
+ (((*(pLine3 + 2) ) & 0x0f) * nMatrix[14])
+ (((*(pLine4 ) ) & 0x0f) * nMatrix[15])
+ (((*(pLine4 + 1) >> 4) & 0x0f) * nMatrix[16])
+ (((*(pLine4 + 1) ) & 0x0f) * nMatrix[17])
+ (((*(pLine4 + 2) >> 4) & 0x0f) * nMatrix[18])
+ (((*(pLine4 + 2) ) & 0x0f) * nMatrix[19])
+ (((*(pLine5 ) ) & 0x0f) * nMatrix[20])
+ (((*(pLine5 + 1) >> 4) & 0x0f) * nMatrix[21])
+ (((*(pLine5 + 1) ) & 0x0f) * nMatrix[22])
+ (((*(pLine5 + 2) >> 4) & 0x0f) * nMatrix[23]);
+ (((*(pLine5 + 2) ) & 0x0f) * nMatrix[24]);
pLine1++;
pLine2++;
pLine3++;
pLine4++;
pLine5++;
if (bAbsolute){
nDestBit0 = abs(nDestBit0);
nDestBit1 = abs(nDestBit1);
}
*(pDestLine++) = ((max(0, min(15,((nDestBit0 + nHalfDividerPlusAdder) / nDivider))) << 4) & 0xf0)
| ((max(0, min(15,((nDestBit1 + nHalfDividerPlusAdder) / nDivider)))) & 0x0f);
}
}
}
break;
/*
Gray8(){
*/
case ITYPE_GRAY8:
nWidthBytes = pSrceImg->nBytesPerLine;
pFirstByte = &pSrceImg->bImageData[0];
pLastByte = &pSrceImg->bImageData[0] + (nWidthBytes * pImage->nHeight) - 1;
nLineSize = nWidthBytes + 4;
if (nStatus = AllocateMemory(nLineSize, (PPSTR) &pLine1L, NO_INIT)){
goto Exit;
}
if (nStatus = AllocateMemory(nLineSize, (PPSTR) &pLine2L, NO_INIT)){
goto Exit;
}
if (nStatus = AllocateMemory(nLineSize, (PPSTR) &pLine3L, NO_INIT)){
goto Exit;
}
if (nStatus = AllocateMemory(nLineSize, (PPSTR) &pLine4L, NO_INIT)){
goto Exit;
}
if (nStatus = AllocateMemory(nLineSize, (PPSTR) &pLine5L, NO_INIT)){
goto Exit;
}
memset(pLine1L, 0x0ff, nLineSize);
memset(pLine2L, 0x0ff, nLineSize);
memset(pLine3L, 0x0ff, nLineSize);
memset(pLine4L, 0x0ff, nLineSize);
memset(pLine5L, 0x0ff, nLineSize);
if (pImage->nHeight > 1){
memcpy(pLine4L + 2, &pSrceImg->bImageData[0], nWidthBytes);
}
if (pImage->nHeight > 1 && bSize == 5){
memcpy(pLine5L + 2, &pSrceImg->bImageData[0] + nWidthBytes, nWidthBytes);
}
nLineIndex = 0;
// Do the actual convolution.
if (bSize == 3){
for (nLine = 0; nLine < (int) pImage->nHeight; nLine++){
// Move the data into the local arrays.
switch (nLineIndex++){
case 0:
pLine2 = pLine3L + 1;
pLine3 = pLine4L + 1;
pLine4 = pLine2L + 1;
nLineIndex = 1;
break;
case 1:
pLine2 = pLine4L + 1;
pLine3 = pLine2L + 1;
pLine4 = pLine3L + 1;
nLineIndex = 2;
break;
case 2:
pLine2 = pLine2L + 1;
pLine3 = pLine3L + 1;
pLine4 = pLine4L + 1;
nLineIndex = 0;
break;
}
if (nLine < (pImage->nHeight - 1)){
memcpy(pLine4 + 1, &pSrceImg->bImageData[0] + (nWidthBytes * (nLine + 1)), nWidthBytes);
}else{
memset(pLine4 + 1, 0x0ff, nWidthBytes);
}
pDestLine = &pDestImg->bImageData[0] + (nWidthBytes * nLine);
for (nByte = nWidthBytes; nByte; nByte--){
nDestBit0 = (*pLine2 * nMatrix[0])
+ (*(pLine2 + 1) * nMatrix[1])
+ (*(pLine2 + 2) * nMatrix[2])
+ (*pLine3 * nMatrix[3])
+ (*(pLine3 + 1) * nMatrix[4])
+ (*(pLine3 + 2) * nMatrix[5])
+ (*pLine4 * nMatrix[6])
+ (*(pLine4 + 1) * nMatrix[7])
+ (*(pLine4 + 2) * nMatrix[8]);
pLine2++;
pLine3++;
pLine4++;
if (bAbsolute){
nDestBit0 = abs(nDestBit0);
}
*(pDestLine++) = max(0, min(255,((nDestBit0 + nHalfDividerPlusAdder) / nDivider) ));
}
}
}else{ // Conv size == 5.
for (nLine = 0; nLine < (int) pImage->nHeight; nLine++){
// Move the data into the local arrays.
switch (nLineIndex++){
case 0:
pLine1 = pLine2L;
pLine2 = pLine3L;
pLine3 = pLine4L;
pLine4 = pLine5L;
pLine5 = pLine1L;
nLineIndex = 1;
break;
case 1:
pLine1 = pLine3L;
pLine2 = pLine4L;
pLine3 = pLine5L;
pLine4 = pLine1L;
pLine5 = pLine2L;
nLineIndex = 2;
break;
case 2:
pLine1 = pLine4L;
pLine2 = pLine5L;
pLine3 = pLine1L;
pLine4 = pLine2L;
pLine5 = pLine3L;
nLineIndex = 3;
break;
case 3:
pLine1 = pLine5L;
pLine2 = pLine1L;
pLine3 = pLine2L;
pLine4 = pLine3L;
pLine5 = pLine4L;
nLineIndex = 4;
case 4:
pLine1 = pLine1L;
pLine2 = pLine2L;
pLine3 = pLine3L;
pLine4 = pLine4L;
pLine5 = pLine5L;
nLineIndex = 0;
}
if (nLine < (pImage->nHeight - 2)){
memcpy(pLine5 + 2, &pSrceImg->bImageData[0] + (nWidthBytes * (nLine + 2)), nWidthBytes);
}else{
memset(pLine5 + 2, 0x0ff, nWidthBytes);
}
pDestLine = &pDestImg->bImageData[0] + (nWidthBytes * nLine);
for (nByte = nWidthBytes; nByte; nByte--){
nDestBit0 = (*pLine1 * nMatrix[0])
+ (*(pLine1 + 1) * nMatrix[1])
+ (*(pLine1 + 2) * nMatrix[2])
+ (*(pLine1 + 3) * nMatrix[3])
+ (*(pLine1 + 4) * nMatrix[4])
+ (*pLine2 * nMatrix[5])
+ (*(pLine2 + 1) * nMatrix[6])
+ (*(pLine2 + 2) * nMatrix[7])
+ (*(pLine2 + 3) * nMatrix[8])
+ (*(pLine2 + 4) * nMatrix[9])
+ (*pLine3 * nMatrix[10])
+ (*(pLine3 + 1) * nMatrix[11])
+ (*(pLine3 + 2) * nMatrix[12])
+ (*(pLine3 + 3) * nMatrix[13])
+ (*(pLine3 + 4) * nMatrix[14])
+ (*pLine4 * nMatrix[15])
+ (*(pLine4 + 1) * nMatrix[16])
+ (*(pLine4 + 2) * nMatrix[17])
+ (*(pLine4 + 3) * nMatrix[18])
+ (*(pLine4 + 4) * nMatrix[19])
+ (*pLine5 * nMatrix[20])
+ (*(pLine5 + 1) * nMatrix[21])
+ (*(pLine5 + 2) * nMatrix[22])
+ (*(pLine5 + 3) * nMatrix[23])
+ (*(pLine5 + 4) * nMatrix[24]);
pLine1++;
pLine2++;
pLine3++;
pLine4++;
pLine5++;
if (bAbsolute){
nDestBit0 = abs(nDestBit0);
}
*(pDestLine++) = max(0, min(255,((nDestBit0 + nHalfDividerPlusAdder) / nDivider) ));
}
}
}
break;
case ITYPE_PAL4:
case ITYPE_CUSPAL8:
case ITYPE_COMPAL8:
case ITYPE_RGB24:
case ITYPE_BGR24:
default:
break;
}
FreeImgBuf(&pImage->pImg);
MoveImage(&pDestImg, &pImage->pImg);
pSrceImg = 0;
pDestImg = 0;
Exit:
FreeImgBuf(&pDestImg);
FreeMemory((PPSTR) &pLine1L);
FreeMemory((PPSTR) &pLine2L);
FreeMemory((PPSTR) &pLine3L);
FreeMemory((PPSTR) &pLine4L);
FreeMemory((PPSTR) &pLine5L);
return nStatus;
}