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.
 
 
 
 
 
 

467 lines
20 KiB

/****************************************************************************
SCBWDEC.C
$Log: S:\products\wangview\oiwh\display\scbwdec.c_v $
*
* Rev 1.7 21 Mar 1996 10:50:24 RC
* Changed the way lrrect was passed into functions from value to
* reference (the power pc compiler couldnt handle those cases)
*
* Rev 1.6 02 Jan 1996 09:58:02 BLJ
* Changed alot of UINTs to ints.
* Changed IMG structure to include the image data.
* Changed lp prefix to p.
*
* Rev 1.5 19 May 1995 13:50:54 BLJ
* Fixed Clipboard paste.
* Fixed SelectByPointOrRect initial fudge before move.
* Fixed GlobalAlloc/FreeMemory conflicts.
* Deleted FAR, far, and huge.
*
* Rev 1.4 05 May 1995 14:06:40 BLJ
* Now working with 32 bit filing.
*
* Rev 1.3 01 May 1995 09:10:44 BLJ
* Fixed negative coordinate translations.
*
* Rev 1.2 12 Apr 1995 13:46:00 BLJ
* Jason's changes for 32 bit.
*
* Rev 1.1 06 Apr 1995 15:08:54 BLJ
* Intermediate checkin.
*
* Rev 1.0 17 Mar 1995 13:58:02 BLJ
* Initial entry
*
****************************************************************************/
#include "privdisp.h"
/****************************************************************************
FUNCTION: Scale1BPPDecimate
PURPOSE: Scales 1 BPP (Bit Per Pixel) images nsing decimation.
*****************************************************************************/
int WINAPI Scale1BPPDecimate(PIMG pSourceImg, PIMG pDestImg,
int nHScale, int nVScale,
int nHDestOffset, int nVDestOffset, LRECT *plrDestRect){
int nStatus = 0;
typedef struct tagBWDecimateScaleTable{
int nByte;
int nMask;
} BW_DECIMATE_SCALE_TABLE, *PBW_DECIMATE_SCALE_TABLE;
BW_DECIMATE_SCALE_TABLE ScaleTable[MAX_PIXELS_HANDLED];
int nDestWidth;
int nDestHeight;
int nDestLine;
PBYTE pSourceLine; // The address of the start of the source line.
PBYTE pSourceByte; // The address of the source byte currently being processed.
PBYTE pDestLine; // The address of the start of the dest line.
PBYTE pDestByte; // The address of the dest byte currently being processed.
long lSourcePixel;
int nScaleDenominator;
int nStartingDestPixels;
int nMiddleLoopCount;
int nEndingDestPixels;
int nScaleTable1[256]; // Table for scaling.
int nScaleTable2[256]; // Table for scaling.
int nScaleTable3[256]; // Table for scaling.
int nScaleTable4[256]; // Table for scaling.
int nScaleTable5[256]; // Table for scaling.
int nLeftShiftAmount;
long lSourceWidth;
BOOL bUseLeftShift;
// Loop variables.
int nLoop;
int nIndex;
int nDestByte;
int nSourceByte;
int nShift1;
int nShift2;
int nPixelMask;
int nDestWord;
LRECT lrDestRect ;
CopyRect (lrDestRect, *plrDestRect) ;
if (pSourceImg->nType != ITYPE_BI_LEVEL || pDestImg->nType != ITYPE_BI_LEVEL){
nStatus = Error(DISPLAY_INVALID_OPTIONS);
goto Exit;
}
if (nHScale == 62 || nHScale == 31){
nScaleDenominator = 992;
}else{
nScaleDenominator = SCALE_DENOMINATOR;
}
nDestWidth = (int)(lrDestRect.right - lrDestRect.left);
nDestHeight = (int)(lrDestRect.bottom - lrDestRect.top);
if (nDestWidth > MAX_PIXELS_HANDLED || nDestHeight > MAX_PIXELS_HANDLED){
nStatus = Error(DISPLAY_INVALIDRECT);
goto Exit;
}
// Produce scale table.
lSourceWidth = pSourceImg->nWidth;
// Pixel 0 = 0x80, pixel 7 = 0x01. 0 = black, 1 = white.
for (nLoop = 0;nLoop < nDestWidth;nLoop++){
lSourcePixel = ((nLoop + nHDestOffset + lrDestRect.left) * nScaleDenominator) / nHScale;
if (lSourcePixel >= lSourceWidth){
lSourcePixel = lSourceWidth - 1;
}
ScaleTable[nLoop].nByte = (int) (lSourcePixel >> 3);
switch (lSourcePixel & 7){
case 0: ScaleTable[nLoop].nMask = 0x80;break;
case 1: ScaleTable[nLoop].nMask = 0x40;break;
case 2: ScaleTable[nLoop].nMask = 0x20;break;
case 3: ScaleTable[nLoop].nMask = 0x10;break;
case 4: ScaleTable[nLoop].nMask = 0x08;break;
case 5: ScaleTable[nLoop].nMask = 0x04;break;
case 6: ScaleTable[nLoop].nMask = 0x02;break;
case 7: ScaleTable[nLoop].nMask = 0x01;break;
}
}
// Put stuff you do only once here.
bUseLeftShift = FALSE;
switch (nHScale){
case 4000:
nStartingDestPixels = min(nDestWidth, max(((int)lrDestRect.left + 7) & 0x18,
0x20 - (( (int)nHDestOffset + (int)lrDestRect.left) & 0x18)));
nMiddleLoopCount = (nDestWidth - nStartingDestPixels) >> 5;
nEndingDestPixels = nDestWidth - (nStartingDestPixels + (nMiddleLoopCount << 5));
// Generate special scaling tables.
nShift1 = nHDestOffset & 7;
nShift2 = 8 - nShift1;
for (nLoop = 0;nLoop < 256;nLoop++){
nScaleTable1[nLoop] = (cBWDecimateUp40[nLoop] << nShift1)
| (cBWDecimateUp41[nLoop] >> nShift2);
nScaleTable2[nLoop] = (cBWDecimateUp41[nLoop] << nShift1)
| (cBWDecimateUp42[nLoop] >> nShift2);
nScaleTable3[nLoop] = (cBWDecimateUp42[nLoop] << nShift1)
| (cBWDecimateUp43[nLoop] >> nShift2);
nScaleTable4[nLoop] = cBWDecimateUp43[nLoop] << nShift1;
nScaleTable5[nLoop] = cBWDecimateUp40[nLoop] >> nShift2;
}
break;
case 2000:
nStartingDestPixels = min(nDestWidth, max(((int)lrDestRect.left + 7) & 0x08,
0x10 - (( (int)nHDestOffset + (int)lrDestRect.left) & 0x08)));
nMiddleLoopCount = (nDestWidth - nStartingDestPixels) >> 4;
nEndingDestPixels = nDestWidth - (nStartingDestPixels + (nMiddleLoopCount << 4));
// Generate special scaling tables.
nShift1 = nHDestOffset & 7;
nShift2 = 8 - nShift1;
for (nLoop = 0;nLoop < 256;nLoop++){
nScaleTable1[nLoop] = (cBWDecimateUp20[nLoop] << nShift1)
| (cBWDecimateUp21[nLoop] >> nShift2);
nScaleTable2[nLoop] = cBWDecimateUp21[nLoop] << nShift1;
nScaleTable3[nLoop] = cBWDecimateUp20[nLoop] >> nShift2;
}
break;
case 1000:
nStartingDestPixels = min(nDestWidth, (int)lrDestRect.left & 7);
nMiddleLoopCount = (nDestWidth - nStartingDestPixels) >> 3;
nEndingDestPixels = nDestWidth - (nStartingDestPixels + (nMiddleLoopCount << 3));
break;
case 500:
nStartingDestPixels = min(nDestWidth, (int)lrDestRect.left & 7);
nMiddleLoopCount = (nDestWidth - nStartingDestPixels) >> 3;
nEndingDestPixels = nDestWidth - (nStartingDestPixels + (nMiddleLoopCount << 3));
// Generate special scaling tables.
nShift1 = nHDestOffset & 3;
nShift2 = 4 - nShift1;
for (nLoop = 0;nLoop < 256;nLoop++){
nScaleTable1[nLoop] = cBWDecimateDn20[nLoop] << nShift1;
nScaleTable2[nLoop] = cBWDecimateDn21[nLoop] << nShift1;
nScaleTable3[nLoop] = cBWDecimateDn21[nLoop] >> nShift2;
}
break;
case 250:
nStartingDestPixels = min(nDestWidth, (int)lrDestRect.left & 7);
nMiddleLoopCount = (nDestWidth - nStartingDestPixels) >> 3;
nEndingDestPixels = nDestWidth - (nStartingDestPixels + (nMiddleLoopCount << 3));
// Generate special scaling tables.
nShift1 = nHDestOffset & 1;
nShift2 = 2 - nShift1;
for (nLoop = 0;nLoop < 256;nLoop++){
nScaleTable1[nLoop] = cBWDecimateDn40[nLoop] << nShift1;
nScaleTable2[nLoop] = cBWDecimateDn41[nLoop] << nShift1;
nScaleTable3[nLoop] = cBWDecimateDn42[nLoop] << nShift1;
nScaleTable4[nLoop] = cBWDecimateDn43[nLoop] << nShift1;
nScaleTable5[nLoop] = cBWDecimateDn43[nLoop] >> nShift2;
}
break;
case 125:
nStartingDestPixels = min(nDestWidth, (int)lrDestRect.left & 7);
nMiddleLoopCount = (nDestWidth - nStartingDestPixels) >> 3;
nEndingDestPixels = nDestWidth - (nStartingDestPixels + (nMiddleLoopCount << 3));
break;
default:
// Do all pixels via the variable scale method.
nStartingDestPixels = min(nDestWidth, (int)lrDestRect.left & 7);
nMiddleLoopCount = (nDestWidth - nStartingDestPixels) >> 3;
nEndingDestPixels = nDestWidth - (nStartingDestPixels + (nMiddleLoopCount << 3));
break;
}
nLeftShiftAmount = (8 - ((int)lrDestRect.left & 7) - nStartingDestPixels) & 7;
// *** Everything inside of this 'for' loop is time critical. ***
for (nDestLine = (int)lrDestRect.top;nDestLine < (int)lrDestRect.bottom;nDestLine++){
pDestLine = &pDestImg->bImageData[0] + ((nDestLine) * pDestImg->nBytesPerLine);
pDestByte = pDestLine + (lrDestRect.left >> 3);
pSourceLine = &pSourceImg->bImageData[0] + (((int)(((nDestLine + nVDestOffset)
* SCALE_DENOMINATOR) / nVScale)) * pSourceImg->nBytesPerLine);
pSourceByte = pSourceLine + ScaleTable[0].nByte;
// Do first few pixels via a slow variable scale algorithm.
switch (lrDestRect.left & 7){
case 0: nPixelMask = 0x80;nLeftShiftAmount = 15;break;
case 1: nPixelMask = 0x40;nLeftShiftAmount = 14;break;
case 2: nPixelMask = 0x20;nLeftShiftAmount = 13;break;
case 3: nPixelMask = 0x10;nLeftShiftAmount = 12;break;
case 4: nPixelMask = 0x08;nLeftShiftAmount = 11;break;
case 5: nPixelMask = 0x04;nLeftShiftAmount = 10;break;
case 6: nPixelMask = 0x02;nLeftShiftAmount = 9;break;
case 7: nPixelMask = 0x01;nLeftShiftAmount = 8;break;
}
for (nLoop = 0; nLoop < nStartingDestPixels; nLoop++){
if (*(pSourceLine + ScaleTable[nLoop].nByte) & ScaleTable[nLoop].nMask){
*pDestByte |= nPixelMask;
}else{
*pDestByte &= ~nPixelMask;
}
nLeftShiftAmount--;
nPixelMask >>= 1;
if (!nPixelMask){
pDestByte++;
nPixelMask = 0x80;
}
}
// Do fast loop for middle part.
pSourceByte = pSourceLine + ScaleTable[nStartingDestPixels].nByte;
if (bUseLeftShift){
switch (nLeftShiftAmount){
case 15: nDestWord = 0;break;
case 14: nDestWord = (*(pDestByte) & 0x80) << 8;break;
case 13: nDestWord = (*(pDestByte) & 0xc0) << 8;break;
case 12: nDestWord = (*(pDestByte) & 0xe0) << 8;break;
case 11: nDestWord = (*(pDestByte) & 0xf0) << 8;break;
case 10: nDestWord = (*(pDestByte) & 0xf8) << 8;break;
case 9: nDestWord = (*(pDestByte) & 0xfc) << 8;break;
case 8: nDestWord = (*(pDestByte) & 0xfe) << 8;break;
}
}
if (nMiddleLoopCount){
switch (nHScale){
case 4000:
if (!(nHDestOffset & 7)){
for (nLoop = nMiddleLoopCount;nLoop;nLoop--){
nSourceByte = *(pSourceByte++);
*(pDestByte) = nScaleTable1[nSourceByte];
*(pDestByte + 1) = nScaleTable2[nSourceByte];
*(pDestByte + 2) = nScaleTable3[nSourceByte];
*(pDestByte + 3) = nScaleTable4[nSourceByte];
pDestByte += 4;
}
}else{
nSourceByte = *(pSourceByte++);
for (nLoop = nMiddleLoopCount;nLoop;nLoop--){
*(pDestByte) = nScaleTable1[nSourceByte];
*(pDestByte + 1) = nScaleTable2[nSourceByte];
*(pDestByte + 2) = nScaleTable3[nSourceByte];
*(pDestByte + 3) = nScaleTable4[nSourceByte] | nScaleTable5[*pSourceByte];
nSourceByte = *(pSourceByte++);
pDestByte += 4;
}
}
break;
case 2000:
if (!(nHDestOffset & 7)){
for (nLoop = nMiddleLoopCount;nLoop;nLoop--){
nSourceByte = *(pSourceByte++);
*(pDestByte) = nScaleTable1[nSourceByte];
*(pDestByte + 1) = nScaleTable2[nSourceByte];
pDestByte += 2;
}
}else{
nSourceByte = *(pSourceByte++);
for (nLoop = nMiddleLoopCount;nLoop;nLoop--){
*(pDestByte) = nScaleTable1[nSourceByte];
*(pDestByte + 1) = nScaleTable2[nSourceByte] | nScaleTable3[*pSourceByte];
nSourceByte = *(pSourceByte++);
pDestByte += 2;
}
}
break;
case 1000:
nShift1 = nHDestOffset & 7;
nShift2 = 8 - nShift1;
if (!nShift1){
memcpy(pDestByte, pSourceByte, nMiddleLoopCount);
pDestByte += nMiddleLoopCount;
}else{
for (nLoop = nMiddleLoopCount;nLoop;nLoop--){
*(pDestByte++) = (*pSourceByte << nShift1) | (*(pSourceByte + 1) >> nShift2);
pSourceByte++;
}
}
break;
case 500:
if (!nShift1){
for (nLoop = nMiddleLoopCount;nLoop;nLoop--){
*(pDestByte++) = nScaleTable1[*pSourceByte] | nScaleTable2[*(pSourceByte + 1)];
pSourceByte += 2;
}
}else{
for (nLoop = nMiddleLoopCount;nLoop;nLoop--){
*(pDestByte++) = nScaleTable1[*pSourceByte]
| nScaleTable2[*(pSourceByte + 1)] | nScaleTable3[*(pSourceByte + 2)];
pSourceByte += 2;
}
}
break;
case 250:
if (!nShift1){
for (nLoop = nMiddleLoopCount;nLoop;nLoop--){
*(pDestByte++) = nScaleTable1[*pSourceByte] | nScaleTable2[*(pSourceByte + 1)]
| nScaleTable3[*(pSourceByte + 2)] | nScaleTable4[*(pSourceByte + 3)];
pSourceByte += 4;
}
}else{
for (nLoop = nMiddleLoopCount;nLoop;nLoop--){
*(pDestByte++) = nScaleTable1[*pSourceByte] | nScaleTable2[*(pSourceByte + 1)]
| nScaleTable3[*(pSourceByte + 2)] | nScaleTable4[*(pSourceByte + 3)]
| nScaleTable5[*(pSourceByte + 4)];
pSourceByte += 4;
}
}
break;
case 125:
for (nLoop = nMiddleLoopCount;nLoop;nLoop--){
*(pDestByte++) = (*pSourceByte & 0x80) | ((*(pSourceByte + 1) & 0x80) >> 1)
| ((*(pSourceByte + 2) & 0x80) >> 2) | ((*(pSourceByte + 3) & 0x80) >> 3)
| ((*(pSourceByte + 4) & 0x80) >> 4) | ((*(pSourceByte + 5) & 0x80) >> 5)
| ((*(pSourceByte + 6) & 0x80) >> 6) | ((*(pSourceByte + 7) & 0x80) >> 7);
pSourceByte += 8;
}
break;
default: // Variable scale.
for (nIndex = 0, nLoop = nMiddleLoopCount; nLoop; nIndex += 8, nLoop--){
if (*(pSourceLine + ScaleTable[nIndex].nByte) & ScaleTable[nIndex].nMask){
nDestByte = 0x80;
}else{
nDestByte = 0;
}
if (*(pSourceLine + ScaleTable[nIndex + 1].nByte) & ScaleTable[nIndex + 1].nMask){
nDestByte |= 0x40;
}
if (*(pSourceLine + ScaleTable[nIndex + 2].nByte) & ScaleTable[nIndex + 2].nMask){
nDestByte |= 0x20;
}
if (*(pSourceLine + ScaleTable[nIndex + 3].nByte) & ScaleTable[nIndex + 3].nMask){
nDestByte |= 0x10;
}
if (*(pSourceLine + ScaleTable[nIndex + 4].nByte) & ScaleTable[nIndex + 4].nMask){
nDestByte |= 0x08;
}
if (*(pSourceLine + ScaleTable[nIndex + 5].nByte) & ScaleTable[nIndex + 5].nMask){
nDestByte |= 0x04;
}
if (*(pSourceLine + ScaleTable[nIndex + 6].nByte) & ScaleTable[nIndex + 6].nMask){
nDestByte |= 0x02;
}
if (*(pSourceLine + ScaleTable[nIndex + 7].nByte) & ScaleTable[nIndex + 7].nMask){
nDestByte |= 0x01;
}
*(pDestByte++) = nDestByte;
}
break;
}
}
// Do last few pixels via a slow variable scale algorithm.
if (bUseLeftShift){
switch (nLeftShiftAmount){
case 15:
nPixelMask = 0x80;
break;
case 14:
*(pDestByte) = (HIBYTE(nDestWord) & 0x80) | (*(pDestByte) & 0x7f);
nPixelMask = 0x40;
break;
case 13:
*(pDestByte) = (HIBYTE(nDestWord) & 0xc0) | (*(pDestByte) & 0x3f);
nPixelMask = 0x20;
break;
case 12:
*(pDestByte) = (HIBYTE(nDestWord) & 0xe0) | (*(pDestByte) & 0x1f);
nPixelMask = 0x10;
break;
case 11:
*(pDestByte) = (HIBYTE(nDestWord) & 0xf0) | (*(pDestByte) & 0x0f);
nPixelMask = 0x08;
break;
case 10:
*(pDestByte) = (HIBYTE(nDestWord) & 0xf8) | (*(pDestByte) & 0x07);
nPixelMask = 0x04;
break;
case 9:
*(pDestByte) = (HIBYTE(nDestWord) & 0xfc) | (*(pDestByte) & 0x03);
nPixelMask = 0x02;
break;
case 8:
*(pDestByte) = (HIBYTE(nDestWord) & 0xfe) | (*(pDestByte) & 0x01);
nPixelMask = 0x01;
break;
}
}else{
nPixelMask = 0x80;
}
for (nLoop = nDestWidth - nEndingDestPixels; nLoop < nDestWidth; nLoop++){
if (*(pSourceLine + ScaleTable[nLoop].nByte) & ScaleTable[nLoop].nMask){
*pDestByte |= nPixelMask;
}else{
*pDestByte &= ~nPixelMask;
}
nPixelMask = nPixelMask >> 1;
if (!nPixelMask){
pDestByte++;
nPixelMask = 0x80;
}
}
}
Exit:
return(nStatus);
}