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.
4015 lines
120 KiB
4015 lines
120 KiB
/*++
|
|
|
|
Copyright (c) 1990-1991 Microsoft Corporation
|
|
|
|
|
|
Module Name:
|
|
|
|
htalias.c
|
|
|
|
|
|
Abstract:
|
|
|
|
This module contains all low levels halftone rendering functions.
|
|
|
|
|
|
Author:
|
|
|
|
22-Jan-1991 Tue 12:49:03 created -by- Daniel Chou (danielc)
|
|
|
|
|
|
[Environment:]
|
|
|
|
GDI Device Driver - Halftone.
|
|
|
|
|
|
[Notes:]
|
|
|
|
|
|
Revision History:
|
|
|
|
|
|
--*/
|
|
|
|
#define DBGP_VARNAME dbgpHTAlias
|
|
|
|
|
|
|
|
#include "htp.h"
|
|
#include "htmapclr.h"
|
|
#include "limits.h"
|
|
#include "htpat.h"
|
|
#include "htalias.h"
|
|
#include "htstret.h"
|
|
#include "htrender.h"
|
|
#include "htgetbmp.h"
|
|
#include "htsetbmp.h"
|
|
|
|
|
|
#define DBGP_BUILD 0x00000001
|
|
#define DBGP_BUILD2 0x00000002
|
|
#define DBGP_BUILD3 0x00000004
|
|
#define DBGP_EXPMATRIX 0x00000008
|
|
#define DBGP_EXP 0x00000010
|
|
#define DBGP_AAHEADER 0x00000020
|
|
#define DBGP_OUTAA 0x00000040
|
|
#define DBGP_FUNC 0x00000080
|
|
#define DBGP_AAHT 0x00000100
|
|
#define DBGP_AAHT_MEM 0x00000200
|
|
#define DBGP_AAHT_TIME 0x00000400
|
|
#define DBGP_AAHTPAT 0x00000800
|
|
#define DBGP_FIXUPDIB 0x00001000
|
|
#define DBGP_INPUT 0x00002000
|
|
#define DBGP_VGA256XLATE 0x00004000
|
|
#define DBGP_EXPAND 0x00008000
|
|
#define DBGP_GETFIXUP 0x00010000
|
|
#define DBGP_PSD 0x00020000
|
|
#define DBGP_MASK 0x00040000
|
|
#define DBGP_PALETTE 0x00080000
|
|
#define DBGP_PAL_CHKSUM 0x00100000
|
|
#define DBGP_LUT_MAP 0x00200000
|
|
|
|
|
|
DEF_DBGPVAR(BIT_IF(DBGP_BUILD, 0) |
|
|
BIT_IF(DBGP_BUILD2, 0) |
|
|
BIT_IF(DBGP_BUILD3, 0) |
|
|
BIT_IF(DBGP_EXPMATRIX, 0) |
|
|
BIT_IF(DBGP_EXP, 0) |
|
|
BIT_IF(DBGP_AAHEADER, 0) |
|
|
BIT_IF(DBGP_OUTAA, 0) |
|
|
BIT_IF(DBGP_FUNC, 0) |
|
|
BIT_IF(DBGP_AAHT, 0) |
|
|
BIT_IF(DBGP_AAHT_MEM, 0) |
|
|
BIT_IF(DBGP_AAHT_TIME, 0) |
|
|
BIT_IF(DBGP_AAHTPAT, 0) |
|
|
BIT_IF(DBGP_FIXUPDIB, 0) |
|
|
BIT_IF(DBGP_INPUT, 0) |
|
|
BIT_IF(DBGP_VGA256XLATE, 0) |
|
|
BIT_IF(DBGP_EXPAND, 0) |
|
|
BIT_IF(DBGP_GETFIXUP, 0) |
|
|
BIT_IF(DBGP_PSD, 0) |
|
|
BIT_IF(DBGP_MASK, 0) |
|
|
BIT_IF(DBGP_PALETTE, 0) |
|
|
BIT_IF(DBGP_PAL_CHKSUM, 0) |
|
|
BIT_IF(DBGP_LUT_MAP, 0))
|
|
|
|
|
|
extern CONST RGBORDER SrcOrderTable[];
|
|
extern DWORD dwABPreMul[256];
|
|
|
|
#define SIZE_AAINFO _ALIGN_MEM(sizeof(AAINFO))
|
|
|
|
|
|
//
|
|
// Following computation is based on
|
|
//
|
|
// NTSC_R_INT = 299000
|
|
// NTSC_G_INT = 587000
|
|
// NTSC_B_INT = 114000
|
|
// GRAY_MAX_IDX = 0xFFFF
|
|
//
|
|
// NTSC_R_GRAY_MAX = (((NTSC_R_INT * GRAY_MAX_IDX) + 500000) / 1000000)
|
|
// NTSC_B_GRAY_MAX = (((NTSC_B_INT * GRAY_MAX_IDX) + 500000) / 1000000)
|
|
// NTSC_G_GRAY_MAX = (GRAY_MAX_IDX - NTSC_R_GRAY_MAX - NTSC_B_GRAY_MAX)
|
|
//
|
|
|
|
#define NTSC_R_GRAY_MAX (DWORD)0x4c8b
|
|
#define NTSC_B_GRAY_MAX (DWORD)0x1d2f
|
|
#define NTSC_G_GRAY_MAX (DWORD)(0xFFFF - NTSC_R_GRAY_MAX - NTSC_B_GRAY_MAX)
|
|
|
|
|
|
|
|
VOID
|
|
HTENTRY
|
|
SetGrayColorTable(
|
|
PLONG pIdxBGR,
|
|
PAASURFINFO pAASI
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
|
|
|
|
|
|
Arguments:
|
|
|
|
pIdxBGR - Pointer to how to translate from RGB to gray scale, typically
|
|
this pointer is computed with NTSC gray standard plus any
|
|
device transform or color adjustment, but if this pointer is
|
|
NULL then we are reading from the device (1bpp, 8bpp) so we
|
|
will only do NTSC standard mapping.
|
|
|
|
|
|
Return Value:
|
|
|
|
|
|
|
|
|
|
Author:
|
|
|
|
19-Feb-1999 Fri 13:14:01 created -by- Daniel Chou (danielc)
|
|
|
|
|
|
Revision History:
|
|
|
|
08-Aug-2000 Tue 18:34:22 updated -by- Daniel Chou (danielc)
|
|
Fixing bug for alpha blending, in gray scale mode, the destination
|
|
can only be 1bpp or 8bpp mask mono, so when we read back from the
|
|
destination to do alpha blending, it will double color mapping pixels.
|
|
In gray scale mode, the input function will map the source RGB value
|
|
to gray value with the current device transform, color adjustment and
|
|
so on, so if we read back from destination then this transform is not
|
|
desired.
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
PRGB4B prgb4b;
|
|
LONG cSrcTable;
|
|
|
|
|
|
ASSERT(NTSC_R_INT == 299000);
|
|
ASSERT(NTSC_G_INT == 587000);
|
|
ASSERT(NTSC_B_INT == 114000);
|
|
ASSERT(GRAY_MAX_IDX == 0xFFFF);
|
|
|
|
|
|
if (cSrcTable = (LONG)pAASI->cClrTable) {
|
|
|
|
prgb4b = pAASI->pClrTable;
|
|
|
|
if (pIdxBGR) {
|
|
|
|
//
|
|
// This is a reading from the source
|
|
//
|
|
|
|
ASSERT(pAASI->Flags & AASIF_GRAY);
|
|
ASSERT(pAASI->pIdxBGR == pIdxBGR);
|
|
|
|
while (cSrcTable--) {
|
|
|
|
prgb4b++->a = IDXBGR_2_GRAY_BYTE(pIdxBGR,
|
|
prgb4b->b,
|
|
prgb4b->g,
|
|
prgb4b->r);
|
|
}
|
|
|
|
} else {
|
|
|
|
//
|
|
// We are reading from the destination so only do NTSC standard,
|
|
// since the destination surface alreay halftoned.
|
|
//
|
|
|
|
while (cSrcTable--) {
|
|
|
|
prgb4b++->a = (BYTE)((((DWORD)prgb4b->r * NTSC_R_GRAY_MAX) +
|
|
((DWORD)prgb4b->g * NTSC_G_GRAY_MAX) +
|
|
((DWORD)prgb4b->b * NTSC_B_GRAY_MAX) +
|
|
(0x7FFF)) / 0xFFFF);
|
|
}
|
|
}
|
|
|
|
} else if (pIdxBGR != pAASI->pIdxBGR) {
|
|
|
|
//
|
|
// This is the source surface info, we will see if this is the
|
|
// gray color table
|
|
//
|
|
|
|
ASSERT(pAASI->Flags & AASIF_GRAY);
|
|
ASSERT(pIdxBGR);
|
|
ASSERT(pAASI->pIdxBGR);
|
|
|
|
DBGP_IF(DBGP_INPUT,
|
|
DBGP("Copy pIdxBGR [BGR] order from 012 to %ld%ld%ld"
|
|
ARGDW(pAASI->AABFData.MaskRGB[2])
|
|
ARGDW(pAASI->AABFData.MaskRGB[1])
|
|
ARGDW(pAASI->AABFData.MaskRGB[0])));
|
|
|
|
CopyMemory(&pAASI->pIdxBGR[pAASI->AABFData.MaskRGB[2] * 256],
|
|
&pIdxBGR[0 * 256], sizeof(LONG) * 256);
|
|
CopyMemory(&pAASI->pIdxBGR[pAASI->AABFData.MaskRGB[1] * 256],
|
|
&pIdxBGR[1 * 256], sizeof(LONG) * 256);
|
|
CopyMemory(&pAASI->pIdxBGR[pAASI->AABFData.MaskRGB[0] * 256],
|
|
&pIdxBGR[2 * 256], sizeof(LONG) * 256);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
HTENTRY
|
|
ComputeInputColorInfo(
|
|
LPBYTE pSrcTable,
|
|
UINT cPerTable,
|
|
UINT PrimaryOrder,
|
|
PBFINFO pBFInfo,
|
|
PAASURFINFO pAASI
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
|
|
|
|
|
|
Arguments:
|
|
|
|
|
|
|
|
|
|
Return Value:
|
|
|
|
|
|
|
|
|
|
Author:
|
|
|
|
19-Feb-1999 Fri 13:14:01 created -by- Daniel Chou (danielc)
|
|
|
|
|
|
Revision History:
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
PRGB4B prgb4b;
|
|
PAABFDATA pAABFData;
|
|
LONG cSrcTable;
|
|
LONG Count;
|
|
LONG LS;
|
|
LONG RS;
|
|
BYTE Mask;
|
|
|
|
|
|
pAABFData = &pAASI->AABFData;
|
|
|
|
if ((pSrcTable) &&
|
|
(Count = cSrcTable = (LONG)pAASI->cClrTable)) {
|
|
|
|
UINT iR;
|
|
UINT iG;
|
|
UINT iB;
|
|
|
|
prgb4b = pAASI->pClrTable;
|
|
iR = SrcOrderTable[PrimaryOrder].Order[0];
|
|
iG = SrcOrderTable[PrimaryOrder].Order[1];
|
|
iB = SrcOrderTable[PrimaryOrder].Order[2];
|
|
|
|
switch (pAABFData->Format) {
|
|
|
|
case BMF_1BPP:
|
|
|
|
pAASI->InputFunc = (AAINPUTFUNC)Input1BPPToAA24;
|
|
break;
|
|
|
|
case BMF_4BPP_VGA16:
|
|
case BMF_4BPP:
|
|
|
|
pAASI->InputFunc = (AAINPUTFUNC)Input4BPPToAA24;
|
|
break;
|
|
|
|
case BMF_8BPP_VGA256:
|
|
case BMF_8BPP:
|
|
|
|
pAASI->InputFunc = (AAINPUTFUNC)Input8BPPToAA24;
|
|
break;
|
|
|
|
default:
|
|
|
|
DBGP("ComputeInputColorInfo() Invalid Bitmap Format=%ld"
|
|
ARGDW(pAABFData->Format));
|
|
|
|
break;
|
|
}
|
|
|
|
while (Count--) {
|
|
|
|
prgb4b->r = *(pSrcTable + iR);
|
|
prgb4b->g = *(pSrcTable + iG);
|
|
prgb4b->b = *(pSrcTable + iB);
|
|
|
|
DBGP_IF(DBGP_PALETTE,
|
|
DBGP("Source Pal [%3ld] = %3ld:%3ld:%3ld"
|
|
ARGDW((LONG)cSrcTable - Count - 1) ARGDW(prgb4b->r)
|
|
ARGDW(prgb4b->g) ARGDW(prgb4b->b)));
|
|
|
|
++prgb4b;
|
|
pSrcTable += cPerTable;
|
|
}
|
|
|
|
} else {
|
|
|
|
pAASI->InputFunc = InputAABFDATAToAA24;
|
|
|
|
if (pBFInfo->Flags & BFIF_RGB_888) {
|
|
|
|
pAABFData->Flags |= AABF_MASK_IS_ORDER;
|
|
pAABFData->MaskRGB[0] = (BYTE)pBFInfo->RGBOrder.Order[0];
|
|
pAABFData->MaskRGB[1] = (BYTE)pBFInfo->RGBOrder.Order[1];
|
|
pAABFData->MaskRGB[2] = (BYTE)pBFInfo->RGBOrder.Order[2];
|
|
|
|
} else {
|
|
|
|
//
|
|
// This is bitfield, figure out how to do it, we want to lshift to
|
|
// to edge then right shift to 8bpp then mask off the unwanted bit
|
|
//
|
|
//
|
|
|
|
cSrcTable = 3;
|
|
|
|
while (cSrcTable--) {
|
|
|
|
LS = 0;
|
|
RS = (LONG)pBFInfo->BitStart[cSrcTable];
|
|
Count = (LONG)pBFInfo->BitCount[cSrcTable];
|
|
|
|
if (Count >= 8) {
|
|
|
|
RS += (Count - 8);
|
|
Mask = 0xFF;
|
|
|
|
} else {
|
|
|
|
LS = 8 - Count;
|
|
Mask = (0xFF << LS);
|
|
|
|
if ((RS -= LS) < 0) {
|
|
|
|
LS = -RS;
|
|
RS = 0;
|
|
|
|
} else {
|
|
|
|
LS = 0;
|
|
}
|
|
}
|
|
|
|
pAABFData->MaskRGB[cSrcTable] = (BYTE)Mask;
|
|
pAABFData->LShiftRGB[cSrcTable] = (BYTE)LS;
|
|
pAABFData->RShiftRGB[cSrcTable] = (BYTE)RS;
|
|
|
|
DBGP_IF(DBGP_FUNC | DBGP_PALETTE,
|
|
DBGP("BFData[%ld]: Bits=%08lx, LS=%2ld, RS=%2ld, Mask=%02lx -->%02lx"
|
|
ARGDW(cSrcTable)
|
|
ARGDW(pBFInfo->BitsRGB[cSrcTable])
|
|
ARGDW(LS) ARGDW(RS) ARGDW(Mask)
|
|
ARGDW(((pBFInfo->BitsRGB[cSrcTable] >> RS) << LS) & Mask)));
|
|
}
|
|
}
|
|
|
|
switch (pBFInfo->BitmapFormat) {
|
|
|
|
case BMF_16BPP:
|
|
case BMF_16BPP_555:
|
|
case BMF_16BPP_565:
|
|
|
|
pAABFData->cbSrcInc = 2;
|
|
break;
|
|
|
|
case BMF_24BPP:
|
|
|
|
ASSERT(pAABFData->Flags & AABF_MASK_IS_ORDER);
|
|
|
|
if (pBFInfo->RGBOrder.Index == PRIMARY_ORDER_BGR) {
|
|
|
|
ASSERT((pAABFData->MaskRGB[0] == 2) &&
|
|
(pAABFData->MaskRGB[1] == 1) &&
|
|
(pAABFData->MaskRGB[2] == 0));
|
|
|
|
pAABFData->Flags |= AABF_SRC_IS_BGR8;
|
|
}
|
|
|
|
pAABFData->cbSrcInc = 3;
|
|
|
|
break;
|
|
|
|
case BMF_32BPP:
|
|
|
|
if (pAASI->Flags & AASIF_AB_PREMUL_SRC) {
|
|
|
|
ASSERT(pAABFData->Flags & AABF_MASK_IS_ORDER);
|
|
ASSERT(dwABPreMul[0] == 0);
|
|
|
|
switch (pBFInfo->RGBOrder.Index) {
|
|
|
|
case PRIMARY_ORDER_BGR:
|
|
|
|
ASSERT((pAABFData->MaskRGB[0] == 2) &&
|
|
(pAABFData->MaskRGB[1] == 1) &&
|
|
(pAABFData->MaskRGB[2] == 0));
|
|
|
|
pAABFData->Flags |= AABF_SRC_IS_BGR_ALPHA;
|
|
break;
|
|
|
|
case PRIMARY_ORDER_RGB:
|
|
|
|
ASSERT((pAABFData->MaskRGB[0] == 0) &&
|
|
(pAABFData->MaskRGB[1] == 1) &&
|
|
(pAABFData->MaskRGB[2] == 2));
|
|
|
|
pAABFData->Flags |= AABF_SRC_IS_RGB_ALPHA;
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
}
|
|
|
|
if (dwABPreMul[0] == 0) {
|
|
|
|
pAASI->InputFunc = InputPreMul32BPPToAA24;
|
|
}
|
|
}
|
|
|
|
pAABFData->cbSrcInc = 4;
|
|
break;
|
|
|
|
default:
|
|
|
|
DBGP("ERROR: Invalid BFInfo Format=%ld" ARGDW(pBFInfo->BitmapFormat));
|
|
break;
|
|
}
|
|
|
|
DBGP_IF(DBGP_FUNC,
|
|
DBGP("Flags=%02lx. cbSrcInc=%ld, Mask=%02lx:%02lx:%02lx, LS=%2ld:%2ld:%2ld, RS=%2ld:%2ld:%2ld"
|
|
ARGDW(pAABFData->Flags)
|
|
ARGDW(pAABFData->cbSrcInc)
|
|
ARGDW(pAABFData->MaskRGB[0])
|
|
ARGDW(pAABFData->MaskRGB[1])
|
|
ARGDW(pAABFData->MaskRGB[2])
|
|
ARGDW(pAABFData->LShiftRGB[0])
|
|
ARGDW(pAABFData->LShiftRGB[1])
|
|
ARGDW(pAABFData->LShiftRGB[2])
|
|
ARGDW(pAABFData->RShiftRGB[0])
|
|
ARGDW(pAABFData->RShiftRGB[1])
|
|
ARGDW(pAABFData->RShiftRGB[2])));
|
|
}
|
|
|
|
DBGP_IF(DBGP_FUNC,
|
|
DBGP("+++++ InputFunc = %hs(SrcFmt=%ld), cClrTable=%ld\n"
|
|
ARGPTR(GetAAInputFuncName(pAASI->InputFunc))
|
|
ARGDW(pBFInfo->BitmapFormat) ARGDW(pAASI->cClrTable)));
|
|
}
|
|
|
|
|
|
|
|
PAAINFO
|
|
HTENTRY
|
|
BuildTileAAInfo(
|
|
PDEVICECOLORINFO pDCI,
|
|
DWORD AAHFlags,
|
|
PLONG piSrcBeg,
|
|
PLONG piSrcEnd,
|
|
LONG SrcSize,
|
|
LONG IdxDst,
|
|
LONG IdxDstEnd,
|
|
PLONG piDstBeg,
|
|
PLONG piDstEnd,
|
|
LONG cbExtra
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
|
|
|
|
|
|
Arguments:
|
|
|
|
piSrcBeg - Passed in as begining source index, When return this is the
|
|
real source begining index. This always well ordered
|
|
|
|
piSrcEnd - Passed in as ending source index, When return this is the
|
|
real source ending index. This always well ordered
|
|
|
|
SrcSize - The real size of source in pixel
|
|
|
|
IdxDst - Starting index of destination pixel
|
|
|
|
IdxDstEnd - Ending index of destination pixel, the iDxdst and IdxDstEnd
|
|
must be well ordered.
|
|
|
|
piDstBeg - Clipped destination start index when passed in, at return
|
|
it adjusted to the real destination starting index.
|
|
|
|
piDstEnd - Clipped destination end index when passed in, at return
|
|
it adjusted to the real destination ending index.
|
|
|
|
cbExtra - Extra byte count to be allocated
|
|
|
|
NOTE: 1) piDstBeg/piDstEnd When passed in this must be well ordered, and
|
|
when it returned this is well ordered.
|
|
|
|
|
|
Return Value:
|
|
|
|
At enter of this function, the *piSrcEnd, *piDstEnd is exclusive but when
|
|
return from this function the *piSrcEnd and *piDstEnd is inclusive
|
|
|
|
*piSrcBeg, *piSrcEnd, *piDstBeg, *piDstEnd are updated if return value
|
|
is not NULL
|
|
|
|
Author:
|
|
|
|
22-Mar-1998 Sun 18:36:28 created -by- Daniel Chou (danielc)
|
|
|
|
|
|
Revision History:
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
PAAINFO pAAInfo;
|
|
PEXPDATA pED;
|
|
LONG cMatrix;
|
|
LONG cM;
|
|
LONG cIn;
|
|
LONG cOut;
|
|
LONG IdxSrc;
|
|
LONG iSrcBeg;
|
|
LONG iSrcEnd;
|
|
LONG iDstBeg;
|
|
LONG iDstEnd;
|
|
LONG jSrcBeg;
|
|
LONG jSrcEnd;
|
|
LONG jDstBeg;
|
|
LONG jDstEnd;
|
|
LONG cLoop;
|
|
LONG cAAData;
|
|
|
|
|
|
|
|
iSrcBeg = *piSrcBeg;
|
|
iSrcEnd = *piSrcEnd;
|
|
|
|
//
|
|
// The source always clipped to the visiable surface area
|
|
//
|
|
|
|
if (iSrcBeg < 0) {
|
|
|
|
iSrcBeg = 0;
|
|
}
|
|
|
|
if (iSrcEnd > SrcSize) {
|
|
|
|
iSrcEnd = SrcSize;
|
|
}
|
|
|
|
cIn = iSrcEnd - (IdxSrc = iSrcBeg);
|
|
cOut = IdxDstEnd - IdxDst;
|
|
|
|
if (cIn <= 0) {
|
|
|
|
return(NULL);
|
|
}
|
|
|
|
ASSERT(cOut > 0);
|
|
|
|
iDstBeg = *piDstBeg;
|
|
iDstEnd = *piDstEnd;
|
|
jSrcBeg = -1;
|
|
|
|
ASSERT(iDstBeg < iDstEnd);
|
|
|
|
DBGP_IF(DBGP_BUILD,
|
|
DBGP("\nTile(%ld-%ld): iSrc=%ld-%ld, cSrc=%ld, iDst=%ld-%ld, Idx=%ld:%ld"
|
|
ARGDW(cIn) ARGDW(cOut) ARGDW(iSrcBeg) ARGDW(iSrcEnd)
|
|
ARGDW(SrcSize) ARGDW(iDstBeg)
|
|
ARGDW(iDstEnd) ARGDW(IdxSrc) ARGDW(IdxDst)));
|
|
|
|
ALIGN_MEM(cbExtra, cbExtra);
|
|
|
|
if (pAAInfo = (PAAINFO)HTAllocMem((LPVOID)pDCI,
|
|
HTMEM_BLTAA,
|
|
LPTR,
|
|
SIZE_AAINFO + cbExtra)) {
|
|
|
|
SETDBGVAR(pAAInfo->cbAlloc, SIZE_AAINFO + cbExtra);
|
|
|
|
pAAInfo->pbExtra = (LPBYTE)pAAInfo + SIZE_AAINFO;
|
|
cLoop = cOut;
|
|
|
|
while (cLoop--) {
|
|
|
|
if ((IdxSrc >= iSrcBeg) && (IdxSrc < iSrcEnd) &&
|
|
(IdxDst >= iDstBeg) && (IdxDst < iDstEnd)) {
|
|
|
|
if (jSrcBeg == -1) {
|
|
|
|
jSrcBeg = IdxSrc;
|
|
jDstBeg = IdxDst;
|
|
}
|
|
|
|
jSrcEnd = IdxSrc;
|
|
jDstEnd = IdxDst;
|
|
|
|
} else if (jSrcBeg != -1) {
|
|
|
|
break;
|
|
}
|
|
|
|
if (++IdxSrc >= iSrcEnd) {
|
|
|
|
IdxSrc = iSrcBeg;
|
|
}
|
|
|
|
++IdxDst;
|
|
}
|
|
|
|
if (jSrcBeg == -1) {
|
|
|
|
HTFreeMem(pAAInfo);
|
|
return(NULL);
|
|
}
|
|
|
|
pAAInfo->iSrcBeg = jSrcBeg - iSrcBeg;
|
|
jSrcBeg = iSrcBeg;
|
|
jSrcEnd = iSrcEnd - 1;
|
|
pAAInfo->Mask.iBeg =
|
|
*piSrcBeg = jSrcBeg;
|
|
*piSrcEnd = jSrcEnd;
|
|
*piDstBeg = jDstBeg;
|
|
*piDstEnd = jDstEnd;
|
|
pAAInfo->Mask.iSize =
|
|
pAAInfo->cIn = jSrcEnd - jSrcBeg + 1;
|
|
pAAInfo->cOut = jDstEnd - jDstBeg + 1;
|
|
pAAInfo->cAAData =
|
|
pAAInfo->cAALoad = (DWORD)pAAInfo->cOut;
|
|
pAAInfo->Mask.cIn = cIn;
|
|
pAAInfo->Mask.cOut = cOut;
|
|
|
|
DBGP_IF(DBGP_BUILD,
|
|
DBGP("TILE(%ld->%ld): iSrc=%ld:%ld (%ld), iDst=%ld:%ld, cAAData=%ld, cbExtra=%ld, Flags=%04lx"
|
|
ARGDW(pAAInfo->cIn) ARGDW(pAAInfo->cOut)
|
|
ARGDW(*piSrcBeg) ARGDW(*piSrcEnd)
|
|
ARGDW(pAAInfo->iSrcBeg) ARGDW(*piDstBeg)
|
|
ARGDW(*piDstEnd) ARGDW(pAAInfo->cAAData)
|
|
ARGDW(cbExtra) ARGDW(pAAInfo->Flags)));
|
|
}
|
|
|
|
return(pAAInfo);
|
|
}
|
|
|
|
|
|
|
|
|
|
PAAINFO
|
|
HTENTRY
|
|
BuildBltAAInfo(
|
|
PDEVICECOLORINFO pDCI,
|
|
DWORD AAHFlags,
|
|
PLONG piSrcBeg,
|
|
PLONG piSrcEnd,
|
|
LONG SrcSize,
|
|
LONG IdxDst,
|
|
LONG IdxDstEnd,
|
|
PLONG piDstBeg,
|
|
PLONG piDstEnd,
|
|
LONG cbExtra
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
|
|
|
|
|
|
Arguments:
|
|
|
|
piSrcBeg - Passed in as begining source index, When return this is the
|
|
real source begining index. This always well ordered
|
|
|
|
piSrcEnd - Passed in as ending source index, When return this is the
|
|
real source ending index. This always well ordered
|
|
|
|
SrcSize - The real size of source in pixel
|
|
|
|
IdxDst - Starting index of destination pixel
|
|
|
|
IdxDstEnd - Ending index of destination pixel, the iDxdst and IdxDstEnd
|
|
must be well ordered.
|
|
|
|
piDstBeg - Clipped destination start index when passed in, at return
|
|
it adjusted to the real destination starting index.
|
|
|
|
piDstEnd - Clipped destination end index when passed in, at return
|
|
it adjusted to the real destination ending index.
|
|
|
|
cbExtra - Extra byte count to be allocated
|
|
|
|
NOTE: 1) piDstBeg/piDstEnd When passed in this must be well ordered, and
|
|
when it returned this is well ordered.
|
|
|
|
|
|
Return Value:
|
|
|
|
At enter of this function, the *piSrcEnd, *piDstEnd is exclusive but when
|
|
return from this function the *piSrcEnd and *piDstEnd is inclusive
|
|
|
|
*piSrcBeg, *piSrcEnd, *piDstBeg, *piDstEnd are updated if return value
|
|
is not NULL
|
|
|
|
Author:
|
|
|
|
22-Mar-1998 Sun 18:36:28 created -by- Daniel Chou (danielc)
|
|
|
|
|
|
Revision History:
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
PAAINFO pAAInfo;
|
|
PEXPDATA pED;
|
|
LONG cMatrix;
|
|
LONG cM;
|
|
LONG cIn;
|
|
LONG cOut;
|
|
LONG IdxSrc;
|
|
LONG iSrcBeg;
|
|
LONG iSrcEnd;
|
|
LONG iDstBeg;
|
|
LONG iDstEnd;
|
|
LONG jSrcBeg;
|
|
LONG jSrcEnd;
|
|
LONG jDstBeg;
|
|
LONG jDstEnd;
|
|
LONG cLoop;
|
|
LONG cAAData;
|
|
|
|
|
|
|
|
cIn = (LONG)((iSrcEnd = *piSrcEnd) - (iSrcBeg = IdxSrc = *piSrcBeg));
|
|
cOut = IdxDstEnd - IdxDst;
|
|
|
|
ASSERT(cOut > 0);
|
|
|
|
if (iSrcBeg < 0) {
|
|
|
|
iSrcBeg = 0;
|
|
}
|
|
|
|
if (iSrcEnd > SrcSize) {
|
|
|
|
iSrcEnd = SrcSize;
|
|
}
|
|
|
|
iDstBeg = *piDstBeg;
|
|
iDstEnd = *piDstEnd;
|
|
jSrcBeg = -1;
|
|
|
|
ASSERT(iDstBeg < iDstEnd);
|
|
ASSERT(cIn == cOut);
|
|
|
|
DBGP_IF(DBGP_BUILD,
|
|
DBGP("\nBlt(%ld-%ld): iSrc=%ld-%ld, cSrc=%ld, iDst=%ld-%ld, Idx=%ld:%ld"
|
|
ARGDW(cIn) ARGDW(cOut) ARGDW(iSrcBeg) ARGDW(iSrcEnd)
|
|
ARGDW(SrcSize) ARGDW(iDstBeg)
|
|
ARGDW(iDstEnd) ARGDW(IdxSrc) ARGDW(IdxDst)));
|
|
|
|
ALIGN_MEM(cbExtra, cbExtra);
|
|
|
|
if (pAAInfo = (PAAINFO)HTAllocMem((LPVOID)pDCI,
|
|
HTMEM_BLTAA,
|
|
LPTR,
|
|
SIZE_AAINFO + cbExtra)) {
|
|
|
|
SETDBGVAR(pAAInfo->cbAlloc, SIZE_AAINFO + cbExtra);
|
|
|
|
pAAInfo->pbExtra = (LPBYTE)pAAInfo + SIZE_AAINFO;
|
|
cLoop = cOut;
|
|
|
|
while (cLoop--) {
|
|
|
|
if ((IdxSrc >= iSrcBeg) && (IdxSrc < iSrcEnd) &&
|
|
(IdxDst >= iDstBeg) && (IdxDst < iDstEnd)) {
|
|
|
|
if (jSrcBeg == -1) {
|
|
|
|
jSrcBeg = IdxSrc;
|
|
jDstBeg = IdxDst;
|
|
}
|
|
|
|
jSrcEnd = IdxSrc;
|
|
jDstEnd = IdxDst;
|
|
|
|
} else if (jSrcBeg != -1) {
|
|
|
|
break;
|
|
}
|
|
|
|
++IdxSrc;
|
|
++IdxDst;
|
|
}
|
|
|
|
if (jSrcBeg == -1) {
|
|
|
|
HTFreeMem(pAAInfo);
|
|
return(NULL);
|
|
}
|
|
|
|
pAAInfo->Mask.iBeg =
|
|
*piSrcBeg = jSrcBeg;
|
|
*piSrcEnd = jSrcEnd;
|
|
*piDstBeg = jDstBeg;
|
|
*piDstEnd = jDstEnd;
|
|
pAAInfo->Mask.iSize =
|
|
pAAInfo->cIn = jSrcEnd - jSrcBeg + 1;
|
|
pAAInfo->cOut = jDstEnd - jDstBeg + 1;
|
|
pAAInfo->cAAData =
|
|
pAAInfo->cAALoad = (DWORD)pAAInfo->cOut;
|
|
pAAInfo->Mask.cIn = cIn;
|
|
pAAInfo->Mask.cOut = cOut;
|
|
|
|
DBGP_IF(DBGP_BUILD,
|
|
DBGP("BLT(%ld->%ld): iSrc=%ld:%ld, iDst=%ld:%ld, cAAData=%ld, cbExtra=%ld, Flags=%4lx"
|
|
ARGDW(pAAInfo->cIn) ARGDW(pAAInfo->cOut)
|
|
ARGDW(*piSrcBeg) ARGDW(*piSrcEnd) ARGDW(*piDstBeg)
|
|
ARGDW(*piDstEnd) ARGDW(pAAInfo->cAAData)
|
|
ARGDW(cbExtra) ARGDW(pAAInfo->Flags)));
|
|
}
|
|
|
|
return(pAAInfo);
|
|
}
|
|
|
|
|
|
|
|
#define _MATRIX_POW (FD6)1414214
|
|
|
|
#if DBG
|
|
FD6 MATRIX_POWER = _MATRIX_POW;
|
|
#else
|
|
#define MATRIX_POWER _MATRIX_POW
|
|
#endif
|
|
|
|
|
|
|
|
|
|
BOOL
|
|
HTENTRY
|
|
BuildRepData(
|
|
PSRCBLTINFO pSBInfo,
|
|
LONG IdxSrc,
|
|
LONG IdxDst
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
|
|
|
|
|
|
Arguments:
|
|
|
|
piSrcBeg - Passed in as begining source index, When return this is the
|
|
real source begining index. This always well ordered
|
|
|
|
piSrcEnd - Passed in as ending source index, When return this is the
|
|
real source ending index. This always well ordered
|
|
|
|
SrcSize - The real size of source in pixel
|
|
|
|
IdxDst - Starting index of destination pixel
|
|
|
|
IdxDstEnd - Ending index of destination pixel, the iDxdst and IdxDstEnd
|
|
must be well ordered. (exclusive)
|
|
|
|
piDstBeg - Clipped destination start index when passed in, at return
|
|
it adjusted to the real destination starting index.
|
|
|
|
piDstEnd - Clipped destination end index when passed in, at return
|
|
it adjusted to the real destination ending index.
|
|
|
|
cbExtra - Extra byte count to be allocated
|
|
|
|
NOTE: 1) piDstBeg/piDstEnd When passed in this must be well ordered, and
|
|
when it returned this is well ordered.
|
|
|
|
|
|
Return Value:
|
|
|
|
At enter of this function, the *piSrcEnd, *piDstEnd is exclusive but when
|
|
return from this function the *piSrcEnd and *piDstEnd is inclusive
|
|
|
|
*piSrcBeg, *piSrcEnd, *piDstBeg, *piDstEnd are updated if return value
|
|
is not NULL
|
|
|
|
Author:
|
|
|
|
22-Mar-1998 Sun 18:36:28 created -by- Daniel Chou (danielc)
|
|
|
|
|
|
Revision History:
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
PREPDATA pRep;
|
|
PREPDATA pRepEnd;
|
|
SRCBLTINFO SBInfo;
|
|
PLONG pSrcInc;
|
|
PLONG pDstInc;
|
|
LONG MinRep;
|
|
LONG MaxRep;
|
|
LONG cRem;
|
|
LONG iRep;
|
|
LONG cRep;
|
|
LONG cTot;
|
|
LONG cIn;
|
|
LONG cOut;
|
|
LONG jSrcBeg;
|
|
LONG jSrcEnd;
|
|
LONG jDstBeg;
|
|
LONG jDstEnd;
|
|
UINT cPrevSrc;
|
|
UINT cNextSrc;
|
|
|
|
|
|
SBInfo = *pSBInfo;
|
|
pRep = SBInfo.pRep;
|
|
pRepEnd = SBInfo.pRepEnd;
|
|
jSrcBeg = -1;
|
|
|
|
if (SBInfo.cIn < SBInfo.cOut) {
|
|
|
|
//
|
|
// Expanding
|
|
//
|
|
|
|
cIn = SBInfo.cIn;
|
|
cOut = SBInfo.cOut;
|
|
pSrcInc = &IdxSrc;
|
|
pDstInc = &IdxDst;
|
|
|
|
} else if (SBInfo.cIn > SBInfo.cOut) {
|
|
|
|
//
|
|
// Shrinking
|
|
//
|
|
|
|
cIn = SBInfo.cOut;
|
|
cOut = SBInfo.cIn;
|
|
pSrcInc = &IdxDst;
|
|
pDstInc = &IdxSrc;
|
|
|
|
} else {
|
|
|
|
ASSERT(SBInfo.cIn != SBInfo.cOut);
|
|
return(FALSE);
|
|
}
|
|
|
|
MinRep = cOut / cIn;
|
|
MaxRep = MinRep + 1;
|
|
|
|
DBGP_IF(DBGP_BUILD,
|
|
DBGP("\nEXPREP(%ld-%ld): iSrc=%ld-%ld, iDst=%ld-%ld, Idx=%ld:%ld"
|
|
ARGDW(SBInfo.cIn) ARGDW(SBInfo.cOut)
|
|
ARGDW(SBInfo.iSrcBeg) ARGDW(SBInfo.iSrcEnd)
|
|
ARGDW(SBInfo.iDstBeg)
|
|
ARGDW(SBInfo.iDstEnd) ARGDW(IdxSrc) ARGDW(IdxDst)));
|
|
|
|
SBInfo.cFirstSkip =
|
|
SBInfo.cLastSkip = 0;
|
|
iRep =
|
|
cRep =
|
|
cTot = 0;
|
|
|
|
//
|
|
// Multiply In/Out by 2, so we do not have run down/up problem, the
|
|
// cRem will be initialized with extra 0.5 for rounding.
|
|
//
|
|
|
|
cRem = (cOut <<= 1) + cIn;
|
|
cIn <<= 1;
|
|
|
|
while (IdxDst < SBInfo.iDstEnd) {
|
|
|
|
if ((cRem -= cIn) < 0) {
|
|
|
|
++*pSrcInc;
|
|
|
|
if (jSrcBeg != -1) {
|
|
|
|
ASSERT(pRep < pRepEnd);
|
|
ASSERT(cRep > 0);
|
|
ASSERT(cRep <= MaxRep);
|
|
|
|
pRep++->c = (WORD)cRep;
|
|
cTot += cRep;
|
|
|
|
DBGP_IF(DBGP_BUILD2,
|
|
DBGP(" Src=%4ld [%4ld-%4ld], Dst=%4ld [%4ld-%4ld], Rep %4ld=%3ld [%4ld -> %4ld, Rem=%4ld, cTot=%4ld]"
|
|
ARGDW(IdxSrc) ARGDW(SBInfo.iSrcBeg) ARGDW(SBInfo.iSrcEnd)
|
|
ARGDW(IdxDst) ARGDW(SBInfo.iDstBeg) ARGDW(SBInfo.iDstEnd)
|
|
ARGDW(pRep - SBInfo.pRep) ARGDW(cRep)
|
|
ARGDW(cIn) ARGDW(cOut) ARGDW(cRem) ARGDW(cTot)));
|
|
}
|
|
|
|
DBGP_IF(DBGP_BUILD3,
|
|
DBGP("IdxSrc=%4ld, IdxDst=%4ld, Rep=%3ld / %3ld, Rem=%5ld, cIn=%5ld"
|
|
ARGDW(IdxSrc) ARGDW(IdxDst)
|
|
ARGDW(cRep) ARGDW(1) ARGDW(cRem) ARGDW(cIn)));
|
|
|
|
cRem += cOut;
|
|
iRep =
|
|
cRep = 0;
|
|
|
|
} else {
|
|
|
|
DBGP_IF(DBGP_BUILD3,
|
|
DBGP("IdxSrc=%4ld, IdxDst=%4ld, Rep=%3ld / %3ld, Rem=%5ld, cIn=%5ld"
|
|
ARGDW(IdxSrc) ARGDW(IdxDst)
|
|
ARGDW(cRep) ARGDW(iRep + 1) ARGDW(cRem) ARGDW(cIn)));
|
|
|
|
}
|
|
|
|
++iRep;
|
|
|
|
if ((IdxSrc >= SBInfo.iSrcBeg) && (IdxSrc < SBInfo.iSrcEnd) &&
|
|
(IdxDst >= SBInfo.iDstBeg) && (IdxDst < SBInfo.iDstEnd)) {
|
|
|
|
++cRep;
|
|
|
|
if (jSrcBeg == -1) {
|
|
|
|
//
|
|
// Any iRep will be the first pixel on the destination that
|
|
// corresponding to the current source, so minus 1 is the
|
|
// total count to be skip for this group of destination
|
|
//
|
|
|
|
jSrcBeg = IdxSrc;
|
|
jDstBeg = IdxDst;
|
|
SBInfo.cFirstSkip = (BYTE)(iRep - 1);
|
|
|
|
DBGP_IF(DBGP_BUILD3,
|
|
DBGP(" @@@ Set cFirstSkip=%ld at IdxDst=%ld @@@"
|
|
ARGDW(SBInfo.cFirstSkip) ARGDW(IdxDst)));
|
|
}
|
|
|
|
jSrcEnd = IdxSrc;
|
|
jDstEnd = IdxDst;
|
|
|
|
} else if (jSrcBeg != -1) {
|
|
|
|
break;
|
|
}
|
|
|
|
++*pDstInc;
|
|
}
|
|
|
|
if (jSrcBeg == -1) {
|
|
|
|
DBGP_IF(DBGP_BUILD3,
|
|
DBGP(" Nothing in the source is on the destination"));
|
|
|
|
return(FALSE);
|
|
}
|
|
|
|
|
|
if (cRep) {
|
|
|
|
ASSERT(pRep < pRepEnd);
|
|
|
|
pRep++->c = (WORD)cRep;
|
|
cTot += cRep;
|
|
|
|
DBGP_IF(DBGP_BUILD2,
|
|
DBGP(" ****** Total pRep=%ld, Last cRep=%ld, cTot=%ld"
|
|
ARGDW(pRep - SBInfo.pRep)
|
|
ARGDW(cRep) ARGDW(cTot)));
|
|
}
|
|
|
|
while ((cRem -= cIn) >= 0) {
|
|
|
|
++SBInfo.cLastSkip;
|
|
|
|
DBGP_IF(DBGP_BUILD3,
|
|
DBGP(" @@@ Set cLastSkip=%4ld, cRem=%5ld @@@"
|
|
ARGDW(SBInfo.cLastSkip) ARGDW(cRem)));
|
|
|
|
}
|
|
|
|
if (SBInfo.cIn < SBInfo.cOut) {
|
|
|
|
//
|
|
// Expanding, checking for maximum 2 sourcs pixels on each side
|
|
//
|
|
|
|
cPrevSrc =
|
|
cNextSrc = 2;
|
|
|
|
} else {
|
|
|
|
//
|
|
// Shrinking, checking only cFirstSkip and cLastSkip
|
|
//
|
|
|
|
cPrevSrc = (UINT)SBInfo.cFirstSkip;
|
|
cNextSrc = (UINT)SBInfo.cLastSkip;
|
|
}
|
|
|
|
//
|
|
// Check src begin
|
|
//
|
|
|
|
IdxSrc = jSrcBeg;
|
|
|
|
while ((cPrevSrc) && (IdxSrc > SBInfo.iSrcBeg)) {
|
|
|
|
--IdxSrc;
|
|
--cPrevSrc;
|
|
}
|
|
|
|
SBInfo.cPrevSrc = (BYTE)(jSrcBeg - IdxSrc);
|
|
IdxSrc = jSrcEnd;
|
|
|
|
while ((cNextSrc) && (IdxSrc < (SBInfo.iSrcEnd - 1))) {
|
|
|
|
++IdxSrc;
|
|
--cNextSrc;
|
|
}
|
|
|
|
SBInfo.cNextSrc = (BYTE)(IdxSrc - jSrcEnd);
|
|
|
|
DBGP_IF(DBGP_BUILD3,
|
|
DBGP("cFirstSkip=%ld (%ld), cLastSkip=%ld (%ld), cPrevSrc=%ld, cNextSrc=%ld"
|
|
ARGDW(SBInfo.cFirstSkip) ARGDW(SBInfo.pRep->c)
|
|
ARGDW(SBInfo.cLastSkip) ARGDW((pRep - 1)->c)
|
|
ARGDW(SBInfo.cPrevSrc) ARGDW(SBInfo.cNextSrc)));
|
|
|
|
// Bug 27036: ensure SBInfo.iSrcEnd is always exclusive
|
|
|
|
SBInfo.iBeg =
|
|
SBInfo.iSrcBeg = jSrcBeg;
|
|
SBInfo.iSrcEnd = jSrcEnd + 1;
|
|
SBInfo.iDstBeg = jDstBeg;
|
|
SBInfo.iDstEnd = jDstEnd + 1;
|
|
SBInfo.iSize = jSrcEnd - jSrcBeg + 1;
|
|
SBInfo.pRepEnd = pRep;
|
|
SBInfo.cRep = 1;
|
|
|
|
DBGP_IF((DBGP_BUILD | DBGP_BUILD2 | DBGP_BUILD3),
|
|
DBGP("EXPREP(%ld->%ld): iSrc=%ld-%ld, iDst=%ld-%ld, iRepSize=%ld"
|
|
ARGDW(SBInfo.cIn) ARGDW(SBInfo.cOut)
|
|
ARGDW(SBInfo.iSrcBeg) ARGDW(SBInfo.iSrcEnd)
|
|
ARGDW(SBInfo.iDstBeg) ARGDW(SBInfo.iDstEnd)
|
|
ARGDW(SBInfo.pRepEnd - SBInfo.pRep)));
|
|
|
|
*pSBInfo = SBInfo;
|
|
|
|
return(TRUE);
|
|
}
|
|
|
|
|
|
|
|
|
|
PAAINFO
|
|
HTENTRY
|
|
BuildExpandAAInfo(
|
|
PDEVICECOLORINFO pDCI,
|
|
DWORD AAHFlags,
|
|
PLONG piSrcBeg,
|
|
PLONG piSrcEnd,
|
|
LONG SrcSize,
|
|
LONG IdxDst,
|
|
LONG IdxDstEnd,
|
|
PLONG piDstBeg,
|
|
PLONG piDstEnd,
|
|
LONG cbExtra
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
|
|
|
|
|
|
Arguments:
|
|
|
|
piSrcBeg - Passed in as begining source index, When return this is the
|
|
real source begining index. This always well ordered
|
|
|
|
piSrcEnd - Passed in as ending source index, When return this is the
|
|
real source ending index. This always well ordered
|
|
|
|
SrcSize - The real size of source in pixel
|
|
|
|
IdxDst - Starting index of destination pixel
|
|
|
|
IdxDstEnd - Ending index of destination pixel, the iDxdst and IdxDstEnd
|
|
must be well ordered. (exclusive)
|
|
|
|
piDstBeg - Clipped destination start index when passed in, at return
|
|
it adjusted to the real destination starting index.
|
|
|
|
piDstEnd - Clipped destination end index when passed in, at return
|
|
it adjusted to the real destination ending index.
|
|
|
|
cbExtra - Extra byte count to be allocated
|
|
|
|
NOTE: 1) piDstBeg/piDstEnd When passed in this must be well ordered, and
|
|
when it returned this is well ordered.
|
|
|
|
|
|
Return Value:
|
|
|
|
At enter of this function, the *piSrcEnd, *piDstEnd is exclusive but when
|
|
return from this function the *piSrcEnd and *piDstEnd is inclusive
|
|
|
|
*piSrcBeg, *piSrcEnd, *piDstBeg, *piDstEnd are updated if return value
|
|
is not NULL
|
|
|
|
Author:
|
|
|
|
22-Mar-1998 Sun 18:36:28 created -by- Daniel Chou (danielc)
|
|
|
|
|
|
Revision History:
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
PAAINFO pAAInfo;
|
|
PEXPDATA pED;
|
|
LONG cMatrix;
|
|
LONG cM;
|
|
LONG cIn;
|
|
LONG cOut;
|
|
LONG IdxSrc;
|
|
LONG iSrcBeg;
|
|
LONG iSrcEnd;
|
|
LONG iDstBeg;
|
|
LONG iDstEnd;
|
|
LONG jSrcBeg;
|
|
LONG jSrcEnd;
|
|
LONG jDstBeg;
|
|
LONG jDstEnd;
|
|
LONGLONG cTot;
|
|
LONG MulAdd;
|
|
LONG Mul;
|
|
DWORD cAALoad;
|
|
LONG cbRep;
|
|
LONG cRem;
|
|
DWORD cbED;
|
|
|
|
|
|
cIn = (LONG)((iSrcEnd = *piSrcEnd) - (iSrcBeg = IdxSrc = *piSrcBeg));
|
|
cOut = IdxDstEnd - IdxDst;
|
|
|
|
ASSERT(cOut > 0);
|
|
|
|
if (iSrcBeg < 0) {
|
|
|
|
iSrcBeg = 0;
|
|
}
|
|
|
|
if (iSrcEnd > SrcSize) {
|
|
|
|
iSrcEnd = SrcSize;
|
|
}
|
|
|
|
iDstBeg = *piDstBeg;
|
|
iDstEnd = *piDstEnd;
|
|
jSrcBeg = -1;
|
|
cAALoad = 0;
|
|
|
|
ASSERT(iDstBeg < iDstEnd);
|
|
ASSERT(cIn < cOut);
|
|
|
|
DBGP_IF(DBGP_BUILD,
|
|
DBGP("\nEXP(%ld-%ld): iSrc=%ld-%ld, cSrc=%ld, iDst=%ld-%ld, Idx=%ld:%ld"
|
|
ARGDW(cIn) ARGDW(cOut) ARGDW(iSrcBeg) ARGDW(iSrcEnd)
|
|
ARGDW(SrcSize) ARGDW(iDstBeg)
|
|
ARGDW(iDstEnd) ARGDW(IdxSrc) ARGDW(IdxDst)));
|
|
|
|
if (AAHFlags & (AAHF_HAS_MASK |
|
|
AAHF_ALPHA_BLEND |
|
|
AAHF_FAST_EXP_AA |
|
|
AAHF_BBPF_AA_OFF)) {
|
|
|
|
ALIGN_MEM(cbRep, (iSrcEnd - iSrcBeg + 3) * sizeof(REPDATA));
|
|
|
|
} else {
|
|
|
|
cbRep = 0;
|
|
}
|
|
|
|
if (AAHFlags & (AAHF_BBPF_AA_OFF | AAHF_FAST_EXP_AA)) {
|
|
|
|
cMatrix =
|
|
cbED =
|
|
cM = 0;
|
|
|
|
} else {
|
|
|
|
cMatrix = (LONG)((((cOut + (cIn - 1)) / cIn) << 1) - 1);
|
|
cM = sizeof(DWORD) * cMatrix;
|
|
|
|
ALIGN_MEM(cbED, (iDstEnd - iDstBeg) * sizeof(EXPDATA));
|
|
}
|
|
|
|
DBGP_IF(DBGP_BUILD,
|
|
DBGP("BuildEXP(%ld, %ld), cMatrix=%ld, cb=%ld+%ld+%ld=%ld"
|
|
ARGDW(cIn) ARGDW(cOut) ARGDW(cMatrix)
|
|
ARGDW(cbRep) ARGDW(cbED) ARGDW(cM)
|
|
ARGDW(cbRep + cbED + cM)));
|
|
|
|
ALIGN_MEM(cbExtra, cbExtra);
|
|
|
|
if (pAAInfo = (PAAINFO)HTAllocMem((LPVOID)pDCI,
|
|
HTMEM_EXPAA,
|
|
LPTR,
|
|
cbRep + cbED +
|
|
cbExtra + cM + SIZE_AAINFO)) {
|
|
|
|
LPBYTE pbExtra;
|
|
|
|
SETDBGVAR(pAAInfo->cbAlloc, cbRep + cbED + cbExtra + cM + SIZE_AAINFO);
|
|
|
|
pbExtra = (LPBYTE)pAAInfo + SIZE_AAINFO;
|
|
|
|
if (cbExtra) {
|
|
|
|
pAAInfo->pbExtra = (LPBYTE)pbExtra;
|
|
pbExtra += cbExtra;
|
|
}
|
|
|
|
if (cbRep) {
|
|
|
|
pAAInfo->Src.cIn = cIn;
|
|
pAAInfo->Src.cOut = cOut;
|
|
pAAInfo->Src.iSrcBeg = iSrcBeg;
|
|
pAAInfo->Src.iSrcEnd = iSrcEnd;
|
|
pAAInfo->Src.iDstBeg = iDstBeg;
|
|
pAAInfo->Src.iDstEnd = iDstEnd;
|
|
pAAInfo->Src.pRep = (PREPDATA)pbExtra;
|
|
pAAInfo->Src.pRepEnd = pAAInfo->Src.pRep + (iSrcEnd - iSrcBeg);
|
|
pbExtra += cbRep;
|
|
|
|
if (!BuildRepData(&(pAAInfo->Src), IdxSrc, IdxDst)) {
|
|
|
|
HTFreeMem(pAAInfo);
|
|
return(NULL);
|
|
}
|
|
|
|
pAAInfo->AB =
|
|
pAAInfo->Mask = pAAInfo->Src;
|
|
|
|
if (AAHFlags & AAHF_FAST_EXP_AA) {
|
|
|
|
pAAInfo->Src.iSrcBeg -= pAAInfo->Src.cPrevSrc;
|
|
pAAInfo->Src.iSrcEnd += pAAInfo->Src.cNextSrc;
|
|
}
|
|
}
|
|
|
|
if (cbED) {
|
|
|
|
PEXPDATA pED;
|
|
PEXPDATA pEDEnd;
|
|
LPDWORD pM;
|
|
LPDWORD pM1;
|
|
LPDWORD pM2;
|
|
LONG cRem2;
|
|
LONG MincM;
|
|
LONGLONG ExpMul[4];
|
|
EXPDATA ed;
|
|
WORD EDFlags;
|
|
LONGLONG cNum;
|
|
LONG cLoop;
|
|
LONG cMul0;
|
|
LONG cMul1;
|
|
LONG cMaskRem;
|
|
LONG iMaskBeg;
|
|
LONG iMaskEnd;
|
|
|
|
pED = (PEXPDATA)pbExtra;
|
|
pAAInfo->pAAData = (LPVOID)pED;
|
|
pM = (LPDWORD)((LPBYTE)pED + cbED);
|
|
pM1 = pM;
|
|
pM2 = pM1 + cMatrix - 1;
|
|
cTot = 0;
|
|
|
|
DBGP_IF(DBGP_BUILD,
|
|
DBGP("Allocate cbExtra=%ld, pbExtra=%p:%p"
|
|
ARGDW(cbExtra) ARGPTR(pAAInfo->pbExtra)
|
|
ARGPTR((LPBYTE)pAAInfo->pbExtra + cbExtra)));
|
|
|
|
pM2 = (pM1 += (cMatrix >> 1));
|
|
cTot = (LONGLONG)(*pM1 = FD6_1);
|
|
|
|
if (AAHFlags & AAHF_BBPF_AA_OFF) {
|
|
|
|
pAAInfo->Flags |= AAIF_EXP_NO_SHARPEN;
|
|
|
|
} else {
|
|
|
|
MulAdd = cOut;
|
|
|
|
while (((MulAdd -= cIn) > 0) && (--pM1 >= pM)) {
|
|
|
|
Mul = (LONG)DivFD6(MulAdd, cOut);
|
|
|
|
if (Mul != 500000) {
|
|
|
|
Mul = (LONG)RaisePower((FD6)Mul,
|
|
MATRIX_POWER,
|
|
(WORD)((Mul <= 500000) ?
|
|
0 : RPF_RADICAL));
|
|
}
|
|
|
|
DBGP_IF(DBGP_EXPMATRIX,
|
|
DBGP("(%4ld, %4ld) = %s ^ %s = %s"
|
|
ARGDW(MulAdd) ARGDW(cOut)
|
|
ARGFD6((DivFD6(MulAdd, cOut)), 1, 6)
|
|
ARGFD6(MATRIX_POWER, 1, 6) ARGFD6(Mul, 1, 6)));
|
|
|
|
*pM1 =
|
|
*(++pM2) = Mul;
|
|
cTot += (Mul << 1);
|
|
}
|
|
}
|
|
|
|
#if DBG
|
|
{
|
|
FD6 PMPrev = FD6_0;
|
|
FD6 PMCur;
|
|
|
|
|
|
pM1 = pM;
|
|
cLoop = (LONG)cMatrix;
|
|
|
|
while (cLoop--) {
|
|
|
|
PMCur = DivFD6(*pM1, (FD6)cTot);
|
|
|
|
DBGP_IF(DBGP_EXPMATRIX, DBGP("%3ld: %7ld [%s], Dif=%s, cTot=%ld"
|
|
ARGDW((pM1 - pM) + 1) ARGDW(*pM1)
|
|
ARGFD6(PMCur, 1, 6) ARGFD6((PMCur - PMPrev), 1, 6)
|
|
ARGDW(cTot)));
|
|
|
|
PMPrev = PMCur;
|
|
++pM1;
|
|
}
|
|
}
|
|
#endif
|
|
cTot *= (LONGLONG)cIn;
|
|
cRem = cOut + (cIn * (LONG)(cMatrix >> 1));
|
|
cLoop = cOut;
|
|
cMul0 =
|
|
cMul1 = 0;
|
|
|
|
while (cLoop--) {
|
|
|
|
cRem2 = cRem;
|
|
|
|
if ((cRem -= cIn) <= 0) {
|
|
|
|
cRem += cOut;
|
|
}
|
|
|
|
pM1 = pM;
|
|
cM = cMatrix;
|
|
MincM = (cMatrix >> 1) - cLoop;
|
|
EDFlags = 0;
|
|
|
|
ZeroMemory(ExpMul, sizeof(ExpMul));
|
|
|
|
while (cM--) {
|
|
|
|
LONG cMul;
|
|
|
|
|
|
Mul = *pM1++;
|
|
|
|
if ((cRem2 < cIn) && (cM >= MincM)) {
|
|
|
|
if (cMul = cRem2) {
|
|
|
|
ExpMul[3] += (LONGLONG)cRem2 * (LONGLONG)Mul;
|
|
}
|
|
|
|
cRem2 -= cIn;
|
|
|
|
ASSERTMSG("BuildEXP: Shift more than 3 times", !ExpMul[0]);
|
|
|
|
CopyMemory(&ExpMul[0], &ExpMul[1], sizeof(ExpMul[0]) * 3);
|
|
|
|
ExpMul[3] = (LONGLONG)-cRem2 * (LONGLONG)Mul;
|
|
cRem2 += cOut;
|
|
|
|
if (!cM) {
|
|
|
|
if ((++IdxSrc >= iSrcBeg) && (IdxSrc < iSrcEnd)) {
|
|
|
|
EDFlags |= EDF_LOAD_PIXEL;
|
|
|
|
++cAALoad;
|
|
++IdxSrc;
|
|
|
|
if ((IdxSrc < iSrcBeg) ||
|
|
(IdxSrc >= iSrcEnd)) {
|
|
|
|
EDFlags |= EDF_NO_NEWSRC;
|
|
}
|
|
|
|
--IdxSrc;
|
|
}
|
|
}
|
|
|
|
} else {
|
|
|
|
ExpMul[3] += (LONGLONG)(cMul = cIn) * (LONGLONG)Mul;
|
|
cRem2 -= cIn;
|
|
}
|
|
|
|
DBGP_IF(DBGP_BUILD3,
|
|
DBGP("%5ld-%7ld:%7ld:%7ld:%7ld, %4ld+, cRem2=%4ld, cM=%5ld:%5ld, cMul=%5ldx%5ld%hs%hs"
|
|
ARGDW(cOut - cLoop - 1) ARGDW(ExpMul[0])
|
|
ARGDW(ExpMul[1]) ARGDW(ExpMul[2]) ARGDW(ExpMul[3])
|
|
ARGDW(cMul * Mul) ARGDW(cRem2) ARGDW(cM)
|
|
ARGDW(MincM) ARGDW(cMul) ARGDW(Mul)
|
|
ARGPTR((EDFlags & EDF_LOAD_PIXEL) ? ", Load Pixel" : "")
|
|
ARGPTR((EDFlags & EDF_NO_NEWSRC) ? ", NO New Src" : "")));
|
|
}
|
|
|
|
if ((IdxSrc >= iSrcBeg) && (IdxSrc < iSrcEnd) &&
|
|
(IdxDst >= iDstBeg) && (IdxDst < iDstEnd)) {
|
|
|
|
GET_FIRST_EDMUL(ed.Mul[3], ExpMul[3], cNum, cTot);
|
|
GET_NEXT_EDMUL( ed.Mul[2], ExpMul[2], cNum, cTot);
|
|
|
|
if (ExpMul[1]) {
|
|
|
|
++cMul1;
|
|
|
|
GET_NEXT_EDMUL(ed.Mul[1], ExpMul[1], cNum, cTot);
|
|
|
|
if (ExpMul[0]) {
|
|
|
|
++cMul0;
|
|
|
|
GET_NEXT_EDMUL(ed.Mul[0], ExpMul[0], cNum, cTot);
|
|
|
|
} else {
|
|
|
|
ed.Mul[0] = 0;
|
|
}
|
|
|
|
} else {
|
|
|
|
ed.Mul[1] =
|
|
ed.Mul[0] = 0;
|
|
}
|
|
|
|
ASSERTMSG("ed.Mul[0] > DI_MAX_NUM", ed.Mul[0] <= DI_MAX_NUM);
|
|
ASSERTMSG("ed.Mul[1] > DI_MAX_NUM", ed.Mul[1] <= DI_MAX_NUM);
|
|
ASSERTMSG("ed.Mul[2] > DI_MAX_NUM", ed.Mul[2] <= DI_MAX_NUM);
|
|
ASSERTMSG("ed.Mul[3] > DI_MAX_NUM", ed.Mul[3] <= DI_MAX_NUM);
|
|
|
|
DBGP_IF(DBGP_BUILD2,
|
|
DBGP("--%5ld=%7ld:%7ld:%7ld:%7ld, IdxSrc=%5ld --%hs%hs--"
|
|
ARGDW(IdxDst) ARGDW(ed.Mul[0])
|
|
ARGDW(ed.Mul[1]) ARGDW(ed.Mul[2])
|
|
ARGDW(ed.Mul[3]) ARGDW(IdxSrc)
|
|
ARGPTR((EDFlags & EDF_LOAD_PIXEL) ? ", Load Pixel" : "")
|
|
ARGPTR((EDFlags & EDF_NO_NEWSRC) ? ", NO New Src" : "")));
|
|
|
|
ed.Mul[0] |= EDFlags;
|
|
*pED++ = ed;
|
|
|
|
if (jSrcBeg == -1) {
|
|
|
|
iMaskBeg = (cOut - cLoop - 1);
|
|
jSrcBeg = IdxSrc;
|
|
jDstBeg = IdxDst;
|
|
}
|
|
|
|
jSrcEnd = IdxSrc;
|
|
jDstEnd = IdxDst;
|
|
|
|
} else if (jSrcBeg != -1) {
|
|
|
|
break;
|
|
}
|
|
|
|
++IdxDst;
|
|
}
|
|
|
|
if (jSrcBeg == -1) {
|
|
|
|
HTFreeMem(pAAInfo);
|
|
return(NULL);
|
|
}
|
|
|
|
//
|
|
// 10-Jun-1998 Wed 08:41:16 updated -by- Daniel Chou (danielc)
|
|
// Fixed for the problem that we need to read extra source for the
|
|
// last loaded pixel because before expand we will sharpen the pixel
|
|
// by its 4 neighbors, this will make sure Last+1 pixel/scan line
|
|
// got read it for sharpen purpose
|
|
//
|
|
// BEGIN FIX
|
|
//
|
|
|
|
++jSrcEnd;
|
|
|
|
if ((jSrcEnd < iSrcBeg) || (jSrcEnd >= iSrcEnd)) {
|
|
|
|
--jSrcEnd;
|
|
}
|
|
|
|
//
|
|
// END FIX
|
|
//
|
|
|
|
IdxSrc =
|
|
*piSrcBeg = jSrcBeg;
|
|
*piSrcEnd = jSrcEnd;
|
|
*piDstBeg = jDstBeg;
|
|
*piDstEnd = jDstEnd;
|
|
pEDEnd = pED;
|
|
pED = (PEXPDATA)(pAAInfo->pAAData);
|
|
pAAInfo->cAAData = (DWORD)(pEDEnd - pED);
|
|
pAAInfo->cAALoad = cAALoad;
|
|
pAAInfo->cMaxMul = (DWORD)((cMul1) ? ((cMul0) ? 4 : 3) : 2);
|
|
ed = *pED;
|
|
cLoop = 4;
|
|
|
|
if (ed.Mul[0] & EDF_LOAD_PIXEL) {
|
|
|
|
--IdxSrc;
|
|
--cLoop;
|
|
|
|
} else {
|
|
|
|
++IdxSrc;
|
|
|
|
if ((IdxSrc < iSrcBeg) || (IdxSrc >= iSrcEnd)) {
|
|
|
|
pAAInfo->Flags |= AAIF_EXP_NO_LAST_RIGHT;
|
|
}
|
|
|
|
--IdxSrc;
|
|
}
|
|
|
|
cMul0 = 0;
|
|
|
|
while ((cMul0 < cLoop) &&
|
|
(!(ed.Mul[cMul0] & ~(EDF_LOAD_PIXEL | EDF_NO_NEWSRC)))) {
|
|
|
|
++cMul0;
|
|
}
|
|
|
|
DBGP_IF(DBGP_BUILD,
|
|
DBGP("cMul0=%ld, cLoop=%ld, IdxSrc=%ld, iSrcBeg=%ld, iSrcEnd=%ld"
|
|
ARGDW(cMul0) ARGDW(cLoop) ARGDW(IdxSrc)
|
|
ARGDW(iSrcBeg) ARGDW(iSrcEnd)));
|
|
|
|
while (cLoop-- > cMul0) {
|
|
|
|
if ((IdxSrc >= iSrcBeg) && (IdxSrc < iSrcEnd)) {
|
|
|
|
*piSrcBeg = IdxSrc;
|
|
pAAInfo->cPreLoad += 0x01;
|
|
|
|
} else {
|
|
|
|
pAAInfo->cPreLoad += 0x10;
|
|
}
|
|
|
|
--IdxSrc;
|
|
}
|
|
|
|
if (pAAInfo->cPreLoad) {
|
|
|
|
if ((IdxSrc >= iSrcBeg) && (IdxSrc < iSrcEnd)) {
|
|
|
|
*piSrcBeg = IdxSrc;
|
|
pAAInfo->Flags |= AAIF_EXP_HAS_1ST_LEFT;
|
|
}
|
|
}
|
|
|
|
if (!(pAAInfo->cPreLoad)) {
|
|
|
|
DBGP("*** cPreLOAD=0, BuildExpandAAInfo [%04lx:%04lx:%04lx:%04lx], cPreload=0x%02lx, Flags=0x%04lx"
|
|
ARGDW(ed.Mul[0]) ARGDW(ed.Mul[1]) ARGDW(ed.Mul[2]) ARGDW(ed.Mul[3])
|
|
ARGDW(pAAInfo->cPreLoad) ARGDW(pAAInfo->Flags));
|
|
}
|
|
|
|
} else {
|
|
|
|
// Bug 27036: ensure jSrcEnd is less than iSrcEnd
|
|
*piSrcBeg = pAAInfo->Src.iSrcBeg;
|
|
*piSrcEnd = pAAInfo->Src.iSrcEnd - 1;
|
|
*piDstBeg = pAAInfo->Src.iDstBeg;
|
|
*piDstEnd = pAAInfo->Src.iDstEnd - 1;
|
|
}
|
|
|
|
pAAInfo->cIn = *piSrcEnd - *piSrcBeg + 1;
|
|
pAAInfo->cOut = *piDstEnd - *piDstBeg + 1;
|
|
|
|
DBGP_IF((DBGP_BUILD | DBGP_BUILD2 | DBGP_BUILD3),
|
|
DBGP("EXP(%ld->%ld): iSrc=%ld-%ld, iDst=%ld-%ld, cAAData=%ld, cPreLoad=0x%02lx, Flags=0x%04lx"
|
|
ARGDW(pAAInfo->cIn) ARGDW(pAAInfo->cOut)
|
|
ARGDW(*piSrcBeg) ARGDW(*piSrcEnd) ARGDW(*piDstBeg)
|
|
ARGDW(*piDstEnd) ARGDW(pAAInfo->cAAData)
|
|
ARGDW(pAAInfo->cPreLoad) ARGDW(pAAInfo->Flags)));
|
|
}
|
|
|
|
return(pAAInfo);
|
|
}
|
|
|
|
|
|
|
|
PAAINFO
|
|
HTENTRY
|
|
BuildShrinkAAInfo(
|
|
PDEVICECOLORINFO pDCI,
|
|
DWORD AAHFlags,
|
|
PLONG piSrcBeg,
|
|
PLONG piSrcEnd,
|
|
LONG SrcSize,
|
|
LONG IdxDst,
|
|
LONG IdxDstEnd,
|
|
PLONG piDstBeg,
|
|
PLONG piDstEnd,
|
|
LONG cbExtra
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
|
|
|
|
|
|
Arguments:
|
|
|
|
piSrcBeg - Passed in as begining source index, When return this is the
|
|
real source begining index. This always well ordered
|
|
|
|
piSrcEnd - Passed in as ending source index, When return this is the
|
|
real source ending index. This always well ordered
|
|
|
|
SrcSize - The real size of source in pixel
|
|
|
|
IdxDst - Starting index of destination pixel
|
|
|
|
IdxDstEnd - Ending index of destination pixel, the iDxdst and IdxDstEnd
|
|
must be well ordered.
|
|
|
|
piDstBeg - Clipped destination start index when passed in, at return
|
|
it adjusted to the real destination starting index.
|
|
|
|
piDstEnd - Clipped destination end index when passed in, at return
|
|
it adjusted to the real destination ending index.
|
|
|
|
cbExtra - Extra byte count to be allocated
|
|
|
|
NOTE: 1) piDstBeg/piDstEnd When passed in this must be well ordered, and
|
|
when it returned this is well ordered.
|
|
|
|
Return Value:
|
|
|
|
PSHRINKINFO, if NULL then memory allocation failed
|
|
|
|
|
|
Author:
|
|
|
|
20-Mar-1998 Fri 12:29:17 created -by- Daniel Chou (danielc)
|
|
|
|
|
|
Revision History:
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
PAAINFO pAAInfo;
|
|
PLONG pMap;
|
|
PLONG pMapEnd;
|
|
PSHRINKDATA pSD;
|
|
PSHRINKDATA pSDEnd;
|
|
LONG cIn;
|
|
LONG cOut;
|
|
LONG IdxSrc;
|
|
LONG IdxDstOrg;
|
|
LONG iSrcBeg;
|
|
LONG iSrcEnd;
|
|
LONG iDstBeg;
|
|
LONG iDstEnd;
|
|
LONG jSrcBeg;
|
|
LONG jSrcEnd;
|
|
LONG jDstBeg;
|
|
LONG jDstEnd;
|
|
LONG cLoop;
|
|
LONG cbRep;
|
|
LONG Mul;
|
|
LONG NextMul;
|
|
LONG CurMul;
|
|
LONG cCur;
|
|
LONG MinPixel;
|
|
DWORD cAAData;
|
|
DWORD cAADone;
|
|
LONGLONG cNum;
|
|
|
|
|
|
|
|
cIn = (LONG)((iSrcEnd = *piSrcEnd) - (iSrcBeg = IdxSrc = *piSrcBeg));
|
|
cOut = IdxDstEnd - (IdxDstOrg = IdxDst);
|
|
|
|
ASSERT(cOut > 0);
|
|
|
|
if (iSrcBeg < 0) {
|
|
|
|
iSrcBeg = 0;
|
|
}
|
|
|
|
if (iSrcEnd > SrcSize) {
|
|
|
|
iSrcEnd = SrcSize;
|
|
}
|
|
|
|
//
|
|
// For shrinking we will enlarge the destination by 1 on both side to
|
|
// obtained the source pixel that for sharpening purpose
|
|
//
|
|
|
|
iDstBeg = *piDstBeg - 1;
|
|
iDstEnd = *piDstEnd;
|
|
jSrcBeg = -1;
|
|
cAADone = 0;
|
|
|
|
ASSERT(iDstBeg < iDstEnd);
|
|
ASSERT(cIn > cOut);
|
|
|
|
DBGP_IF(DBGP_BUILD,
|
|
DBGP("\nSRK(%ld-%ld): iSrc=%ld-%ld, cSrc=%ld, iDst=%ld-%ld (%ld-%ld), Idx=%ld:%ld"
|
|
ARGDW(cIn) ARGDW(cOut) ARGDW(iSrcBeg) ARGDW(iSrcEnd)
|
|
ARGDW(SrcSize) ARGDW(iDstBeg) ARGDW(iDstEnd)
|
|
ARGDW(*piDstBeg) ARGDW(*piDstEnd)
|
|
ARGDW(IdxSrc) ARGDW(IdxDst)));
|
|
|
|
//
|
|
// Firstable figure out how may SHRINKDATA needed
|
|
//
|
|
cAAData = (DWORD)((((iDstEnd - iDstBeg + 1) * cIn) + (cOut-1)) / cOut) + 4;
|
|
|
|
if ((LONG)cAAData > cIn) {
|
|
|
|
(LONG)cAAData = cIn;
|
|
}
|
|
|
|
|
|
DBGP_IF(DBGP_BUILD,
|
|
DBGP("BuildShrink(%ld-%ld): cSD estimated=%ld (%ld), iDst=%ld-%ld=%ld"
|
|
ARGDW(cIn) ARGDW(cOut) ARGDW(cAAData) ARGDW(cIn)
|
|
ARGDW(iDstBeg) ARGDW(iDstEnd) ARGDW(iDstEnd - iDstBeg)));
|
|
|
|
ALIGN_MEM(CurMul, 256 * 2 * sizeof(LONG));
|
|
ALIGN_MEM(cCur, (cAAData + 1) * sizeof(SHRINKDATA));
|
|
|
|
CurMul += cCur;
|
|
MinPixel = (LONG)(((LONGLONG)cOut * (LONGLONG)DI_MAX_NUM) / (LONGLONG)cIn);
|
|
|
|
if (AAHFlags & (AAHF_HAS_MASK |
|
|
AAHF_ALPHA_BLEND |
|
|
AAHF_FAST_EXP_AA |
|
|
AAHF_BBPF_AA_OFF)) {
|
|
|
|
ALIGN_MEM(cbRep, (iDstEnd - iDstBeg + 4) * sizeof(REPDATA));
|
|
|
|
if (AAHFlags & AAHF_BBPF_AA_OFF) {
|
|
|
|
CurMul = 0;
|
|
}
|
|
|
|
} else {
|
|
|
|
cbRep = 0;
|
|
}
|
|
|
|
ALIGN_MEM(cbExtra, cbExtra);
|
|
|
|
if (pAAInfo = (PAAINFO)HTAllocMem((LPVOID)pDCI,
|
|
HTMEM_SRKAA,
|
|
LPTR,
|
|
SIZE_AAINFO + CurMul +
|
|
cbRep + cbExtra)) {
|
|
|
|
LPBYTE pbExtra;
|
|
|
|
|
|
SETDBGVAR(pAAInfo->cbAlloc, SIZE_AAINFO + CurMul + cbRep + cbExtra);
|
|
|
|
pbExtra = (LPBYTE)pAAInfo + SIZE_AAINFO;
|
|
|
|
if (cbExtra) {
|
|
|
|
pAAInfo->pbExtra = (LPBYTE)pbExtra;
|
|
pbExtra += cbExtra;
|
|
}
|
|
|
|
if (cbRep) {
|
|
|
|
pAAInfo->Src.cIn = cIn;
|
|
pAAInfo->Src.cOut = cOut;
|
|
pAAInfo->Src.iSrcBeg = iSrcBeg;
|
|
pAAInfo->Src.iSrcEnd = iSrcEnd;
|
|
pAAInfo->Src.iDstBeg = iDstBeg + 1;
|
|
pAAInfo->Src.iDstEnd = iDstEnd;
|
|
pAAInfo->Src.pRep = (PREPDATA)pbExtra;
|
|
pAAInfo->Src.pRepEnd = pAAInfo->Src.pRep + (iDstEnd-iDstBeg+1);
|
|
pbExtra += cbRep;
|
|
|
|
if (!BuildRepData(&(pAAInfo->Src), IdxSrc, IdxDst)) {
|
|
|
|
HTFreeMem(pAAInfo);
|
|
return(NULL);
|
|
}
|
|
|
|
pAAInfo->AB =
|
|
pAAInfo->Mask = pAAInfo->Src;
|
|
}
|
|
|
|
if (CurMul) {
|
|
|
|
pAAInfo->cPreLoad = 1;
|
|
pMap =
|
|
pAAInfo->pMapMul = (PLONG)pbExtra;
|
|
pMapEnd = pMap + 256;
|
|
pSD = (PSHRINKDATA)(pMap + (256 * 2));
|
|
pSDEnd = pSD + cAAData;
|
|
pAAInfo->pAAData = (LPVOID)pSD;
|
|
Mul = -MinPixel;
|
|
CurMul = MinPixel + 1;
|
|
NextMul = -CurMul;
|
|
|
|
|
|
ASSERT_MEM_ALIGN(pAAInfo->pMapMul, sizeof(LONG));
|
|
|
|
//
|
|
// Build InMax 256 multiplication table
|
|
//
|
|
|
|
do {
|
|
|
|
pMap[ 0] = (Mul += MinPixel);
|
|
pMap[256] = (NextMul += CurMul);
|
|
|
|
} while (++pMap < pMapEnd);
|
|
|
|
//
|
|
// Build the SHRINKINFO table
|
|
//
|
|
|
|
|
|
CurMul = 0;
|
|
cCur =
|
|
cLoop = cIn;
|
|
cNum = (LONGLONG)0;
|
|
cAAData = 0;
|
|
--pSD;
|
|
|
|
while (cLoop--) {
|
|
|
|
WORD SDFlags;
|
|
|
|
if ((cCur -= cOut) <= 0) {
|
|
|
|
Mul = cCur + cOut;
|
|
NextMul = -cCur;
|
|
cCur += cIn;
|
|
SDFlags = SDF_DONE;
|
|
|
|
++IdxDst;
|
|
|
|
} else {
|
|
|
|
Mul = cOut;
|
|
SDFlags = 0;
|
|
}
|
|
|
|
if ((IdxDst >= (iDstBeg - 1)) && (IdxDst <= iDstEnd)) {
|
|
|
|
cNum += ((LONGLONG)Mul * (LONGLONG)DI_MAX_NUM);
|
|
|
|
if ((Mul = (LONG)(cNum / cIn)) > MinPixel) {
|
|
|
|
SDFlags |= SDF_LARGE_MUL;
|
|
}
|
|
|
|
CurMul += Mul;
|
|
cNum %= cIn;
|
|
|
|
if (SDFlags & SDF_DONE) {
|
|
|
|
cNum = (LONGLONG)NextMul * (LONGLONG)DI_MAX_NUM;
|
|
NextMul = (LONG)(cNum / cIn);
|
|
|
|
if ((Mul + NextMul) > MinPixel) {
|
|
|
|
SDFlags |= SDF_LARGE_MUL;
|
|
|
|
} else {
|
|
|
|
SDFlags &= ~SDF_LARGE_MUL;
|
|
}
|
|
|
|
cNum %= cIn;
|
|
CurMul = NextMul;
|
|
NextMul = 0;
|
|
}
|
|
}
|
|
|
|
if ((IdxDst >= iDstBeg) && (IdxDst <= iDstEnd)) {
|
|
|
|
if ((IdxSrc >= iSrcBeg) && (IdxSrc < iSrcEnd)) {
|
|
|
|
//
|
|
// Save it first
|
|
//
|
|
|
|
cAADone += (SDFlags & SDF_DONE) ? 1 : 0;
|
|
|
|
if (++pSD >= pSDEnd) {
|
|
|
|
DBGP("Error(1): cAAData Overrun of %ld, Fixed it"
|
|
ARGDW(++cAAData));
|
|
ASSERT(pSD < pSDEnd);
|
|
|
|
--pSD;
|
|
}
|
|
|
|
pSD->Mul = (WORD)Mul | SDFlags;
|
|
|
|
ASSERTMSG("sd.Mul > DI_MAX_NUM", Mul <= DI_MAX_NUM);
|
|
|
|
if (jSrcBeg == -1) {
|
|
|
|
jSrcBeg =
|
|
jSrcEnd = IdxSrc;
|
|
jDstBeg =
|
|
jDstEnd = IdxDst;
|
|
|
|
if (SDFlags & SDF_DONE) {
|
|
|
|
//
|
|
// If we just finished a pixel then we need to see
|
|
// if it is a source index or a detination index
|
|
// cause the output become valid
|
|
//
|
|
|
|
if (IdxDst == iDstBeg) {
|
|
|
|
//
|
|
// The destination just become valid now,
|
|
// PreMul is the start of current detination
|
|
// until next done pixel
|
|
//
|
|
|
|
DBGP_IF(DBGP_BUILD,
|
|
DBGP("@@ FIRST DEST: PreMul=CurMul=%ld, No PSD, IncSrc"
|
|
ARGDW(CurMul)));
|
|
|
|
pAAInfo->PreMul = (WORD)CurMul;
|
|
pAAInfo->PreSrcInc = 1;
|
|
--cAADone;
|
|
--pSD;
|
|
|
|
} else {
|
|
|
|
//
|
|
// The source just become valid now, need to
|
|
// PreMul all prev sources for this detination
|
|
// and save this pSD for done pixel
|
|
//
|
|
|
|
DBGP_IF(DBGP_BUILD,
|
|
DBGP("@@ FIRST SRC: PreMul=%ld - Mul (%ld)=%ld"
|
|
ARGDW(DI_MAX_NUM) ARGDW(Mul)
|
|
ARGDW(DI_MAX_NUM - Mul)));
|
|
|
|
pAAInfo->PreMul = (WORD)(DI_MAX_NUM - Mul);
|
|
|
|
--jDstBeg;
|
|
--jDstEnd;
|
|
|
|
ASSERTMSG("!!! Error: jDstBeg is WRONG",
|
|
(jDstBeg >= iDstBeg) &&
|
|
(jDstBeg <= iDstEnd));
|
|
}
|
|
|
|
} else {
|
|
|
|
//
|
|
// We are in the middle of compositions, so the
|
|
// source just become valid, notice that PreMul
|
|
// could be zero
|
|
//
|
|
|
|
DBGP_IF(DBGP_BUILD,
|
|
DBGP("@@ FIRST MIDDLE: PreMul=CurMul (%ld) - Mul (%ld)=%ld"
|
|
ARGDW(CurMul) ARGDW(Mul)
|
|
ARGDW(CurMul - Mul)));
|
|
|
|
pAAInfo->PreMul = (WORD)(CurMul - Mul);
|
|
}
|
|
|
|
} else {
|
|
|
|
jSrcEnd = IdxSrc;
|
|
jDstEnd = IdxDst;
|
|
}
|
|
|
|
} else if (jSrcBeg != -1) {
|
|
|
|
//
|
|
// Source got cut off early, so wrap it up now
|
|
//
|
|
|
|
DBGP_IF(DBGP_BUILD,
|
|
DBGP("@@ END SRC: Mul=%ld, CurMul=%ld"
|
|
ARGDW(Mul) ARGDW(CurMul)));
|
|
|
|
if (++pSD >= pSDEnd) {
|
|
|
|
DBGP("Error(2): cAAData Overrun of %ld, Fixed it"
|
|
ARGDW(++cAAData));
|
|
ASSERT(pSD < pSDEnd);
|
|
|
|
--pSD;
|
|
}
|
|
|
|
if (!(SDFlags & SDF_DONE)) {
|
|
|
|
Mul += (DI_MAX_NUM - CurMul);
|
|
}
|
|
|
|
pSD->Mul = (WORD)Mul | (SDFlags |= SDF_DONE);
|
|
cLoop = 0;
|
|
++cAADone;
|
|
|
|
ASSERTMSG("sd.Mul > DI_MAX_NUM", Mul <= DI_MAX_NUM);
|
|
}
|
|
|
|
} else if (jSrcBeg != -1) {
|
|
|
|
//
|
|
// we just pass the iDstEnd so this one MUST have SDF_DONE
|
|
// bit set and we need to save this one, if this one is not
|
|
// SDF_DONE then something is wrong
|
|
//
|
|
|
|
ASSERTMSG("End Dest but not SDF_DONE", SDFlags & SDF_DONE);
|
|
|
|
DBGP_IF(DBGP_BUILD,
|
|
DBGP("@@ PASS IdxDst: Mul=%ld, CurMul=%ld"
|
|
ARGDW(Mul) ARGDW(CurMul)));
|
|
|
|
if (++pSD >= pSDEnd) {
|
|
|
|
DBGP("Error(3): cAAData Overrun of %ld, Fixed it"
|
|
ARGDW(++cAAData));
|
|
ASSERT(pSD < pSDEnd);
|
|
|
|
--pSD;
|
|
}
|
|
|
|
jSrcEnd = IdxSrc;
|
|
Mul = DI_MAX_NUM - CurMul;
|
|
pSD->Mul = (WORD)Mul | (SDFlags = SDF_DONE);
|
|
cLoop = 0;
|
|
++cAADone;
|
|
|
|
ASSERTMSG("sd.Mul > DI_MAX_NUM", Mul <= DI_MAX_NUM);
|
|
}
|
|
#if DBG
|
|
if ((pSD >= (PSHRINKDATA)(pAAInfo->pAAData)) ||
|
|
(pAAInfo->PreSrcInc)) {
|
|
|
|
BOOL HasSD;
|
|
|
|
HasSD = (BOOL)(pSD >= (PSHRINKDATA)(pAAInfo->pAAData));
|
|
|
|
if (SDFlags & SDF_DONE) {
|
|
|
|
DBGP_IF(DBGP_BUILD2,
|
|
DBGP("%hscLoop=%5ld (%5ld/%5ld), iSrc=%5ld, Mul=%5ld [%5ld], Flags=0x%04lx%hs, Done Pixel"
|
|
ARGPTR((HasSD) ? "" : " >>")
|
|
ARGDW(cIn - cLoop - 1) ARGDW(IdxDst)
|
|
ARGDW(IdxDst - iDstBeg)
|
|
ARGDW(IdxSrc)
|
|
ARGDW((Mul) ? Mul :
|
|
((SDFlags & SDF_LARGE_MUL) ?
|
|
MinPixel + 1 : MinPixel))
|
|
ARGDW(CurMul)
|
|
ARGDW(SDFlags)
|
|
ARGPTR((SDFlags & SDF_LARGE_MUL) ? ", Large Mul" : "")));
|
|
|
|
} else {
|
|
|
|
DBGP_IF(DBGP_BUILD2,
|
|
DBGP("%hscLoop=%5ld iSrc=%5ld, Mul=%5ld [%5ld], Flags=0x%04lx%hs"
|
|
ARGPTR((HasSD) ? "" : " >>")
|
|
ARGDW(cIn - cLoop - 1)
|
|
ARGDW(IdxSrc)
|
|
ARGDW((Mul) ? Mul : ((SDFlags & SDF_LARGE_MUL) ?
|
|
MinPixel + 1 : MinPixel))
|
|
ARGDW(CurMul)
|
|
ARGDW(SDFlags)
|
|
ARGPTR((SDFlags & SDF_LARGE_MUL) ? ", Large Mul" : "")));
|
|
}
|
|
}
|
|
#endif
|
|
|
|
++IdxSrc;
|
|
}
|
|
|
|
//
|
|
// For the last one ZERO
|
|
//
|
|
|
|
++pSD;
|
|
|
|
if ((jSrcBeg == -1) || (pSD == (PSHRINKDATA)(pAAInfo->pAAData))) {
|
|
|
|
HTFreeMem(pAAInfo);
|
|
return(NULL);
|
|
}
|
|
|
|
++iDstBeg;
|
|
|
|
DBGP_IF(DBGP_BUILD,
|
|
DBGP("*** Final jDstBeg/End=%ld:%ld, REAL=(%ld:%ld)"
|
|
ARGDW(jDstBeg) ARGDW(jDstEnd) ARGDW(iDstBeg) ARGDW(iDstEnd)));
|
|
|
|
// Bug 27036: ensure jSrcEnd is less than iSrcEnd
|
|
if (jSrcEnd >= iSrcEnd)
|
|
{
|
|
jSrcEnd = iSrcEnd - 1;
|
|
}
|
|
|
|
if (jDstBeg < iDstBeg) {
|
|
|
|
++(pAAInfo->cPreLoad);
|
|
|
|
jDstBeg = iDstBeg;
|
|
}
|
|
|
|
if (jDstEnd >= iDstEnd) {
|
|
|
|
jDstEnd = iDstEnd - 1;
|
|
}
|
|
|
|
if ((pAAInfo->PreSrcInc) && (pAAInfo->PreMul == 0)) {
|
|
|
|
pAAInfo->PreSrcInc = 0;
|
|
++jSrcBeg;
|
|
}
|
|
#if 0
|
|
//
|
|
// 04-Aug-2000 Fri 15:31:03 updated -by- Daniel Chou (danielc)
|
|
// This assert does not applyed here when anti-aliasing will use
|
|
// surounding 3 pixels (L/T/R/B) if source available (when clipped
|
|
// source) but the Rep does not use suround pixels.
|
|
//
|
|
|
|
if (cbRep) {
|
|
|
|
ASSERT(jSrcBeg == pAAInfo->Mask.iBeg);
|
|
|
|
if (jSrcEnd != (pAAInfo->Mask.iBeg + pAAInfo->Mask.iSize - 1)) {
|
|
|
|
DBGP("jSrcEnd=%ld, Mask: iBeg=%ld, iSize=%ld"
|
|
ARGDW(jSrcEnd) ARGDW(pAAInfo->Mask.iBeg)
|
|
ARGDW(pAAInfo->Mask.iSize));
|
|
|
|
ASSERT(jSrcEnd == pAAInfo->Mask.iBeg + pAAInfo->Mask.iSize - 1);
|
|
}
|
|
}
|
|
#endif
|
|
pAAInfo->cAAData = (DWORD)(pSD - (PSHRINKDATA)(pAAInfo->pAAData));
|
|
pAAInfo->cAADone = cAADone;
|
|
pSD->Mul = 0;
|
|
|
|
} else {
|
|
|
|
ASSERT(cbRep);
|
|
|
|
// Bug 27036: ensure jSrcEnd is less than iSrcEnd
|
|
jSrcBeg = pAAInfo->Src.iSrcBeg;
|
|
jSrcEnd = pAAInfo->Src.iSrcEnd - 1;
|
|
jDstBeg = pAAInfo->Src.iDstBeg;
|
|
jDstEnd = pAAInfo->Src.iDstEnd - 1;
|
|
}
|
|
|
|
*piSrcBeg = jSrcBeg;
|
|
*piSrcEnd = jSrcEnd;
|
|
*piDstBeg = jDstBeg;
|
|
*piDstEnd = jDstEnd;
|
|
pAAInfo->cIn = jSrcEnd - jSrcBeg + 1;
|
|
pAAInfo->cOut = jDstEnd - jDstBeg + 1;
|
|
|
|
DBGP_IF(DBGP_BUILD,
|
|
DBGP("SRK(%ld->%ld): iSrc=%ld-%ld, iDst=%ld-%ld, cAAData=%ld, cAADone=%ld, PreMul=%4ld, PresrcInc=%ld, cPreLoad=%ld"
|
|
ARGDW(pAAInfo->cIn) ARGDW(pAAInfo->cOut)
|
|
ARGDW(jSrcBeg) ARGDW(jSrcEnd) ARGDW(jDstBeg) ARGDW(jDstEnd)
|
|
ARGDW(pAAInfo->cAAData) ARGDW(cAADone) ARGDW(pAAInfo->PreMul)
|
|
ARGDW(pAAInfo->PreSrcInc) ARGDW(pAAInfo->cPreLoad)));
|
|
}
|
|
|
|
return(pAAInfo);
|
|
}
|
|
|
|
|
|
|
|
#if DBG
|
|
BOOL ExpExp = TRUE;
|
|
BOOL SrkSrk = TRUE;
|
|
#endif
|
|
|
|
|
|
LONG
|
|
HTENTRY
|
|
ComputeAABBP(
|
|
PBITBLTPARAMS pBBP,
|
|
PHTSURFACEINFO pDstSI,
|
|
PAABBP pAABBP,
|
|
BOOL GrayFunc
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
|
|
|
|
|
|
Arguments:
|
|
|
|
|
|
|
|
|
|
Return Value:
|
|
|
|
|
|
|
|
|
|
Author:
|
|
|
|
01-Apr-1998 Wed 20:32:36 created -by- Daniel Chou (danielc)
|
|
|
|
|
|
Revision History:
|
|
|
|
05-Aug-1998 Wed 19:38:56 updated -by- Daniel Chou (danielc)
|
|
Fix banding problem
|
|
|
|
10-Aug-1998 Mon 16:05:32 updated -by- Daniel Chou (danielc)
|
|
Fix rectangle banding with flip (X or Y) computation, the computation
|
|
is done first by flip the Destination rectangles (Orginal and final)
|
|
first by compute from right to left for flipping X, and bottom to
|
|
top for flipping Y, after computation for stretch, we flip all the
|
|
rectangles back
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
BITBLTPARAMS BBP;
|
|
RECTL rclSurf;
|
|
RECTL rclPhyDst;
|
|
LONG cxIn;
|
|
LONG cyIn;
|
|
LONG cxOut;
|
|
LONG cyOut;
|
|
LONG Tmp;
|
|
DWORD AAHFlags;
|
|
|
|
|
|
BBP = *pBBP;
|
|
AAHFlags = pAABBP->AAHFlags;
|
|
|
|
DBGP_IF(DBGP_AAHEADER,
|
|
DBGP(" Input: rclSrc=(%6ld, %6ld)-(%6ld, %6ld)=%6ld x %6ld"
|
|
ARGDW(pBBP->rclSrc.left) ARGDW(pBBP->rclSrc.top)
|
|
ARGDW(pBBP->rclSrc.right) ARGDW(pBBP->rclSrc.bottom)
|
|
ARGDW(pBBP->rclSrc.right - pBBP->rclSrc.left)
|
|
ARGDW(pBBP->rclSrc.bottom - pBBP->rclSrc.top)));
|
|
|
|
DBGP_IF(DBGP_AAHEADER,
|
|
DBGP(" Input: rclDst=(%6ld, %6ld)-(%6ld, %6ld)=%6ld x %6ld"
|
|
ARGDW(pBBP->rclDest.left) ARGDW(pBBP->rclDest.top)
|
|
ARGDW(pBBP->rclDest.right) ARGDW(pBBP->rclDest.bottom)
|
|
ARGDW(pBBP->rclDest.right - pBBP->rclDest.left)
|
|
ARGDW(pBBP->rclDest.bottom - pBBP->rclDest.top)));
|
|
|
|
if (BBP.Flags & BBPF_HAS_DEST_CLIPRECT) {
|
|
|
|
DBGP_IF(DBGP_AAHEADER,
|
|
DBGP(" Input: rclClip=(%6ld, %6ld)-(%6ld, %6ld)=%6ld x %6ld"
|
|
ARGDW(pBBP->rclClip.left) ARGDW(pBBP->rclClip.top)
|
|
ARGDW(pBBP->rclClip.right) ARGDW(pBBP->rclClip.bottom)
|
|
ARGDW(pBBP->rclClip.right - pBBP->rclClip.left)
|
|
ARGDW(pBBP->rclClip.bottom - pBBP->rclClip.top)));
|
|
}
|
|
|
|
if (BBP.Flags & BBPF_HAS_BANDRECT) {
|
|
|
|
DBGP_IF(DBGP_AAHEADER,
|
|
DBGP(" Input: rclBand=(%6ld, %6ld)-(%6ld, %6ld)=%6ld x %6ld"
|
|
ARGDW(pBBP->rclBand.left) ARGDW(pBBP->rclBand.top)
|
|
ARGDW(pBBP->rclBand.right) ARGDW(pBBP->rclBand.bottom)
|
|
ARGDW(pBBP->rclBand.right - pBBP->rclBand.left)
|
|
ARGDW(pBBP->rclBand.bottom - pBBP->rclBand.top)));
|
|
}
|
|
|
|
DBGP_IF(DBGP_AAHEADER,
|
|
DBGP("Input: ptlBrushOrg=(%6ld, %6ld)"
|
|
ARGDW(pBBP->ptlBrushOrg.x) ARGDW(pBBP->ptlBrushOrg.y)));
|
|
|
|
DBGP_IF(DBGP_AAHEADER,
|
|
DBGP("Input: ptlSrcMask=(%6ld, %6ld)"
|
|
ARGDW(pBBP->ptlSrcMask.x) ARGDW(pBBP->ptlSrcMask.y)));
|
|
|
|
if (BBP.rclDest.right < BBP.rclDest.left) {
|
|
|
|
XCHG(BBP.rclDest.left, BBP.rclDest.right, Tmp);
|
|
AAHFlags |= AAHF_FLIP_X;
|
|
}
|
|
|
|
if (BBP.rclDest.bottom < BBP.rclDest.top) {
|
|
|
|
XCHG(BBP.rclDest.top, BBP.rclDest.bottom, Tmp);
|
|
AAHFlags |= AAHF_FLIP_Y;
|
|
}
|
|
|
|
//
|
|
// The source RECT is always well ordered
|
|
//
|
|
|
|
if (BBP.rclSrc.right < BBP.rclSrc.left) {
|
|
|
|
XCHG(BBP.rclSrc.left, BBP.rclSrc.right, Tmp);
|
|
AAHFlags ^= AAHF_FLIP_X;
|
|
}
|
|
|
|
if (BBP.rclSrc.bottom < BBP.rclSrc.top) {
|
|
|
|
XCHG(BBP.rclSrc.top, BBP.rclSrc.bottom, Tmp);
|
|
AAHFlags ^= AAHF_FLIP_Y;
|
|
}
|
|
|
|
if ((BBP.rclSrc.left >= BBP.rclSrc.right) ||
|
|
(BBP.rclSrc.top >= BBP.rclSrc.bottom)) {
|
|
|
|
DBGP_IF(DBGP_AAHEADER,
|
|
DBGP("EMPTY rclSrc: (%ld, %ld)-(%ld, %ld)=%ldx%ld"
|
|
ARGDW(BBP.rclSrc.left) ARGDW(BBP.rclSrc.top)
|
|
ARGDW(BBP.rclSrc.right) ARGDW(BBP.rclSrc.bottom)
|
|
ARGDW(BBP.rclSrc.right - BBP.rclSrc.left)
|
|
ARGDW(BBP.rclSrc.bottom - BBP.rclSrc.top)));
|
|
|
|
return(0);
|
|
}
|
|
|
|
if ((BBP.rclDest.left >= BBP.rclDest.right) ||
|
|
(BBP.rclDest.top >= BBP.rclDest.bottom)) {
|
|
|
|
DBGP_IF(DBGP_AAHEADER,
|
|
DBGP("EMPTY rclDest: (%ld, %ld)-(%ld, %ld)=%ldx%ld"
|
|
ARGDW(BBP.rclDest.left) ARGDW(BBP.rclDest.top)
|
|
ARGDW(BBP.rclDest.right) ARGDW(BBP.rclDest.bottom)
|
|
ARGDW(BBP.rclDest.right - BBP.rclDest.left)
|
|
ARGDW(BBP.rclDest.bottom - BBP.rclDest.top)));
|
|
|
|
return(0);
|
|
}
|
|
|
|
//
|
|
// set the cxIn, cyIn for no sign
|
|
//
|
|
|
|
cxIn = BBP.rclSrc.right - BBP.rclSrc.left;
|
|
cyIn = BBP.rclSrc.bottom - BBP.rclSrc.top;
|
|
cxOut = BBP.rclDest.right - BBP.rclDest.left;
|
|
cyOut = BBP.rclDest.bottom - BBP.rclDest.top;
|
|
pAABBP->ptlBrushOrg = BBP.ptlBrushOrg;
|
|
|
|
if (((((cxOut * 1000) + 500) / cxIn) > 667) &&
|
|
((((cyOut * 1000) + 500) / cyIn) > 667)) {
|
|
|
|
AAHFlags |= AAHF_DO_FIXUPDIB;
|
|
}
|
|
|
|
if ((cxOut * cyOut) < (cxIn * cyIn)) {
|
|
|
|
AAHFlags |= AAHF_SHRINKING;
|
|
AAHFlags |= AAHF_DO_DST_CLR_MAPPING;
|
|
|
|
} else {
|
|
|
|
AAHFlags |= AAHF_DO_SRC_CLR_MAPPING;
|
|
}
|
|
|
|
if (cyIn == cyOut) {
|
|
|
|
pAABBP->AAMaskCYFunc = BltMask_CY;
|
|
pAABBP->GetAVCYFunc = BltAV_CY;
|
|
pAABBP->AABuildCYFunc = BuildBltAAInfo;
|
|
pAABBP->CYFuncMode = AACYMODE_BLT;
|
|
|
|
} else if (cyIn < cyOut) {
|
|
|
|
pAABBP->AAMaskCYFunc = ExpandMask_CY;
|
|
pAABBP->GetAVCYFunc = ExpandAV_CY;
|
|
pAABBP->AABuildCYFunc = BuildExpandAAInfo;
|
|
|
|
if (cxOut > cxIn) {
|
|
|
|
if ((!(AAHFlags & AAHF_BBPF_AA_OFF)) &&
|
|
((cyIn * FAST_MAX_CY) >= cyOut) &&
|
|
((cxIn * FAST_MAX_CX) >= cxOut)) {
|
|
|
|
AAHFlags |= AAHF_FAST_EXP_AA;
|
|
}
|
|
|
|
pAABBP->CYFuncMode = AACYMODE_EXPAND_EXPCX;
|
|
|
|
} else {
|
|
|
|
pAABBP->CYFuncMode = AACYMODE_EXPAND;
|
|
}
|
|
|
|
#if DBG
|
|
if (!ExpExp) {
|
|
|
|
pAABBP->CYFuncMode = AACYMODE_EXPAND;
|
|
}
|
|
#endif
|
|
|
|
} else {
|
|
|
|
pAABBP->AAMaskCYFunc = ShrinkMask_CY;
|
|
pAABBP->GetAVCYFunc = ShrinkAV_CY;
|
|
pAABBP->AABuildCYFunc = BuildShrinkAAInfo;
|
|
pAABBP->CYFuncMode = ((cxOut < cxIn) && (!GrayFunc)) ?
|
|
AACYMODE_SHRINK_SRKCX : AACYMODE_SHRINK;
|
|
#if DBG
|
|
if (!SrkSrk) {
|
|
|
|
pAABBP->CYFuncMode = AACYMODE_SHRINK;
|
|
}
|
|
#endif
|
|
}
|
|
|
|
DBGP_IF(DBGP_FUNC, DBGP("\n+++++ AACYFuncMode = %ld"
|
|
ARGDW(pAABBP->CYFuncMode)));
|
|
|
|
if (cxIn == cxOut) {
|
|
|
|
pAABBP->CXFuncMode = AACXMODE_BLT;
|
|
pAABBP->AAMaskCXFunc = BltMask_CX;
|
|
pAABBP->GetAVCXFunc = BltAV_CX;
|
|
pAABBP->AABuildCXFunc = BuildBltAAInfo;
|
|
pAABBP->AACXFunc = (GrayFunc) ? (AACXFUNC)GrayCopyDIB_CX :
|
|
(AACXFUNC)CopyDIB_CX;
|
|
|
|
DBGP_IF(DBGP_FUNC, DBGP("+++++ AACXFunc = CopyDIB_CX()"));
|
|
|
|
} else if (cxIn < cxOut) {
|
|
|
|
pAABBP->CXFuncMode = AACXMODE_EXPAND;
|
|
pAABBP->AAMaskCXFunc = ExpandMask_CX;
|
|
pAABBP->GetAVCXFunc = ExpandAV_CX;
|
|
pAABBP->AABuildCXFunc = BuildExpandAAInfo;
|
|
pAABBP->AACXFunc = (GrayFunc) ? (AACXFUNC)GrayExpandDIB_CX :
|
|
(AACXFUNC)ExpandDIB_CX;
|
|
|
|
DBGP_IF(DBGP_FUNC, DBGP("+++++ AACXFunc = ExpandDIB_CX()"));
|
|
|
|
} else {
|
|
|
|
pAABBP->CXFuncMode = AACXMODE_SHRINK;
|
|
pAABBP->AAMaskCXFunc = ShrinkMask_CX;
|
|
AAHFlags |= AAHF_OR_AV;
|
|
pAABBP->GetAVCXFunc = ShrinkAV_CX;
|
|
pAABBP->AABuildCXFunc = BuildShrinkAAInfo;
|
|
pAABBP->AACXFunc = (GrayFunc) ? (AACXFUNC)GrayShrinkDIB_CX :
|
|
(AACXFUNC)ShrinkDIB_CX;
|
|
|
|
DBGP_IF(DBGP_FUNC, DBGP("+++++ AACXFunc = ShrinkDIB_CX()"));
|
|
}
|
|
|
|
if (BBP.Flags & BBPF_TILE_SRC) {
|
|
|
|
pAABBP->CYFuncMode = AACYMODE_TILE;
|
|
pAABBP->AAMaskCXFunc = BltMask_CX;
|
|
pAABBP->AAMaskCYFunc = BltMask_CY;
|
|
pAABBP->GetAVCXFunc = NULL;
|
|
pAABBP->GetAVCYFunc = TileAV_CY;
|
|
pAABBP->AABuildCYFunc =
|
|
pAABBP->AABuildCXFunc = BuildTileAAInfo;
|
|
pAABBP->AACXFunc = NULL;
|
|
|
|
DBGP_IF(DBGP_FUNC, DBGP("+++ TILE: TileBlt_CY(), AACXFunc = NULL"));
|
|
}
|
|
|
|
pAABBP->AAHFlags = AAHFlags;
|
|
pAABBP->rclSrc = BBP.rclSrc;
|
|
pAABBP->ptlMask.x = BBP.ptlSrcMask.x - BBP.rclSrc.left;
|
|
pAABBP->ptlMask.y = BBP.ptlSrcMask.y - BBP.rclSrc.top;
|
|
rclSurf = BBP.rclDest;
|
|
|
|
if (BBP.Flags & BBPF_HAS_DEST_CLIPRECT) {
|
|
|
|
if (!IntersectRECTL(&rclSurf, &BBP.rclClip)) {
|
|
|
|
DBGP_IF(DBGP_AAHEADER,
|
|
DBGP("rclClip=(%ld, %ld)-(%ld, %ld)=%ldx%ld < SURF=(%ld, %ld)-(%ld, %ld)=%ldx%ld"
|
|
ARGDW(BBP.rclClip.left) ARGDW(BBP.rclClip.top)
|
|
ARGDW(BBP.rclClip.right) ARGDW(BBP.rclClip.bottom)
|
|
ARGDW(BBP.rclClip.right - BBP.rclClip.left)
|
|
ARGDW(BBP.rclClip.bottom - BBP.rclClip.top)
|
|
ARGDW(rclSurf.left) ARGDW(rclSurf.top)
|
|
ARGDW(rclSurf.right) ARGDW(rclSurf.bottom)
|
|
ARGDW(rclSurf.right - rclSurf.left)
|
|
ARGDW(rclSurf.bottom - rclSurf.top)));
|
|
|
|
return(0);
|
|
}
|
|
}
|
|
|
|
if (BBP.Flags & BBPF_HAS_BANDRECT) {
|
|
|
|
ASSERT(BBP.rclBand.left >= 0);
|
|
ASSERT(BBP.rclBand.top >= 0);
|
|
ASSERT(BBP.rclBand.right > BBP.rclBand.left);
|
|
ASSERT(BBP.rclBand.bottom > BBP.rclBand.top);
|
|
|
|
if (!IntersectRECTL(&rclSurf, &BBP.rclBand)) {
|
|
|
|
DBGP_IF(DBGP_AAHEADER,
|
|
DBGP("rclBand=(%ld, %ld)-(%ld, %ld)=%ldx%ld < SURF=(%ld, %ld)-(%ld, %ld)=%ldx%ld"
|
|
ARGDW(BBP.rclBand.left) ARGDW(BBP.rclBand.top)
|
|
ARGDW(BBP.rclBand.right) ARGDW(BBP.rclBand.bottom)
|
|
ARGDW(BBP.rclBand.right - BBP.rclBand.left)
|
|
ARGDW(BBP.rclBand.bottom - BBP.rclBand.top)
|
|
ARGDW(rclSurf.left) ARGDW(rclSurf.top)
|
|
ARGDW(rclSurf.right) ARGDW(rclSurf.bottom)
|
|
ARGDW(rclSurf.right - rclSurf.left)
|
|
ARGDW(rclSurf.bottom - rclSurf.top)));
|
|
|
|
return(0);
|
|
}
|
|
|
|
//
|
|
// 05-Aug-1998 Wed 19:38:56 updated -by- Daniel Chou (danielc)
|
|
// Fixed the banding problem when mirrored or upside down stretch
|
|
// The fixes is simple by offset all the Dest rects for the left/top
|
|
// of the band, and reset the cx/cy destination size according to the
|
|
// band size and then offset the brush origin according the the band's
|
|
// left/top position, after these all other codes should run the same
|
|
// excpet we do not need to check BBPF_HAS_BANDRECT at later time.
|
|
//
|
|
|
|
BBP.rclDest.left -= BBP.rclBand.left;
|
|
BBP.rclDest.right -= BBP.rclBand.left;
|
|
BBP.rclDest.top -= BBP.rclBand.top;
|
|
BBP.rclDest.bottom -= BBP.rclBand.top;
|
|
rclSurf.left -= BBP.rclBand.left;
|
|
rclSurf.right -= BBP.rclBand.left;
|
|
rclSurf.top -= BBP.rclBand.top;
|
|
rclSurf.bottom -= BBP.rclBand.top;
|
|
pAABBP->ptlBrushOrg.x -= BBP.rclBand.left;
|
|
pAABBP->ptlBrushOrg.y -= BBP.rclBand.top;
|
|
|
|
ASSERT((BBP.rclBand.right - BBP.rclBand.left) <= pDstSI->Width);
|
|
ASSERT((BBP.rclBand.bottom - BBP.rclBand.top) <= pDstSI->Height);
|
|
|
|
DBGP_IF(DBGP_AAHEADER,
|
|
DBGP("BAND Output: Dest: %ld x %ld --> BAND: %ld x %ld"
|
|
ARGDW(pDstSI->Width) ARGDW(pDstSI->Height)
|
|
ARGDW(BBP.rclBand.right - BBP.rclBand.left)
|
|
ARGDW(BBP.rclBand.bottom - BBP.rclBand.top)));
|
|
}
|
|
|
|
rclPhyDst.left =
|
|
rclPhyDst.top = 0;
|
|
rclPhyDst.right = pDstSI->Width;
|
|
rclPhyDst.bottom = pDstSI->Height;
|
|
|
|
if (!IntersectRECTL(&rclSurf, &rclPhyDst)) {
|
|
|
|
DBGP_IF(DBGP_AAHEADER,
|
|
DBGP("PhyDest=(%ld, %ld)-(%ld, %ld)=%ldx%ld < SURF=(%ld, %ld)-(%ld, %ld)=%ldx%ld"
|
|
ARGDW(rclPhyDst.left) ARGDW(rclPhyDst.top)
|
|
ARGDW(rclPhyDst.right) ARGDW(rclPhyDst.bottom)
|
|
ARGDW(rclPhyDst.right - rclPhyDst.left)
|
|
ARGDW(rclPhyDst.bottom - rclPhyDst.top)
|
|
ARGDW(rclSurf.left) ARGDW(rclSurf.top)
|
|
ARGDW(rclSurf.right) ARGDW(rclSurf.bottom)
|
|
ARGDW(rclSurf.right - rclSurf.left)
|
|
ARGDW(rclSurf.bottom - rclSurf.top)));
|
|
|
|
return(0);
|
|
}
|
|
|
|
//
|
|
// 10-Aug-1998 Mon 16:09:13 updated -by- Daniel Chou (danielc)
|
|
// flipping X computation: When we flip in X direction, we will first
|
|
// compute the destination original rectangle and final destination
|
|
// rectangle by compute its offset from right hand side so later at
|
|
// stretch computation is easier, after finished stretch computation
|
|
// (BuildExpand or BuildShrink) we will flip the rectangle back by
|
|
// substract it from ptlFlip.x.
|
|
//
|
|
|
|
if (AAHFlags & AAHF_FLIP_X) {
|
|
|
|
DBGP_IF(DBGP_AAHEADER,
|
|
DBGP("*** FLIP X: rclDstOrg=(%6ld - %6ld)=%6ld"
|
|
ARGDW(BBP.rclDest.left) ARGDW(BBP.rclDest.right)
|
|
ARGDW(BBP.rclDest.right - BBP.rclDest.left)));
|
|
|
|
DBGP_IF(DBGP_AAHEADER,
|
|
DBGP("*** FLIP X: rclDst=(%6ld - %6ld)=%6ld, ptlFlip.x=%ld"
|
|
ARGDW(rclSurf.left) ARGDW(rclSurf.right)
|
|
ARGDW(rclSurf.right - rclSurf.left)
|
|
ARGDW(BBP.rclDest.right)));
|
|
|
|
Tmp = rclSurf.right - rclSurf.left;
|
|
rclSurf.left = BBP.rclDest.right - rclSurf.right;
|
|
rclSurf.right = rclSurf.left + Tmp;
|
|
pAABBP->ptlFlip.x = BBP.rclDest.right;
|
|
BBP.rclDest.right -= BBP.rclDest.left;
|
|
BBP.rclDest.left = 0;
|
|
}
|
|
|
|
//
|
|
// 10-Aug-1998 Mon 16:09:13 updated -by- Daniel Chou (danielc)
|
|
// flipping Y computation: When we flip in Y direction, we will first
|
|
// compute the destination original rectangle and final destination
|
|
// rectangle by compute its offset from bottom hand side so later at
|
|
// stretch computation is easier, after finished stretch computation
|
|
// (BuildExpand or BuildShrink) we will flip the rectangle back by
|
|
// substract it from ptlFlip.y.
|
|
//
|
|
|
|
if (AAHFlags & AAHF_FLIP_Y) {
|
|
|
|
DBGP_IF(DBGP_AAHEADER,
|
|
DBGP("*** FLIP Y: rclDstOrg=(%6ld - %6ld)=%6ld"
|
|
ARGDW(BBP.rclDest.top) ARGDW(BBP.rclDest.bottom)
|
|
ARGDW(BBP.rclDest.bottom - BBP.rclDest.top)));
|
|
|
|
DBGP_IF(DBGP_AAHEADER,
|
|
DBGP("*** FLIP Y: rclDst=(%6ld - %6ld)=%6ld, ptlFlip.y=%ld"
|
|
ARGDW(rclSurf.top) ARGDW(rclSurf.bottom)
|
|
ARGDW(rclSurf.bottom - rclSurf.top)
|
|
ARGDW(BBP.rclDest.bottom)));
|
|
|
|
Tmp = rclSurf.bottom - rclSurf.top;
|
|
rclSurf.top = BBP.rclDest.bottom - rclSurf.bottom;
|
|
rclSurf.bottom = rclSurf.top + Tmp;
|
|
pAABBP->ptlFlip.y = BBP.rclDest.bottom;
|
|
BBP.rclDest.bottom -= BBP.rclDest.top;
|
|
BBP.rclDest.top = 0;
|
|
}
|
|
|
|
pAABBP->rclDstOrg = BBP.rclDest;
|
|
pAABBP->rclDst = rclSurf;
|
|
|
|
DBGP_IF(DBGP_AAHEADER,
|
|
DBGP("Output: rclSrc=(%6ld, %6ld)-(%6ld, %6ld)=%6ld x %6ld"
|
|
ARGDW(pAABBP->rclSrc.left) ARGDW(pAABBP->rclSrc.top)
|
|
ARGDW(pAABBP->rclSrc.right) ARGDW(pAABBP->rclSrc.bottom)
|
|
ARGDW(pAABBP->rclSrc.right - pAABBP->rclSrc.left)
|
|
ARGDW(pAABBP->rclSrc.bottom - pAABBP->rclSrc.top)));
|
|
|
|
DBGP_IF(DBGP_AAHEADER,
|
|
DBGP("Output: rclDstOrg=(%6ld, %6ld)-(%6ld, %6ld)=%6ld x %6ld"
|
|
ARGDW(pAABBP->rclDstOrg.left) ARGDW(pAABBP->rclDstOrg.top)
|
|
ARGDW(pAABBP->rclDstOrg.right) ARGDW(pAABBP->rclDstOrg.bottom)
|
|
ARGDW(pAABBP->rclDstOrg.right - pAABBP->rclDstOrg.left)
|
|
ARGDW(pAABBP->rclDstOrg.bottom - pAABBP->rclDstOrg.top)));
|
|
|
|
DBGP_IF(DBGP_AAHEADER,
|
|
DBGP("Output: rclDst=(%6ld, %6ld)-(%6ld, %6ld)=%6ld x %6ld"
|
|
ARGDW(pAABBP->rclDst.left) ARGDW(pAABBP->rclDst.top)
|
|
ARGDW(pAABBP->rclDst.right) ARGDW(pAABBP->rclDst.bottom)
|
|
ARGDW(pAABBP->rclDst.right - pAABBP->rclDst.left)
|
|
ARGDW(pAABBP->rclDst.bottom - pAABBP->rclDst.top)));
|
|
|
|
DBGP_IF(DBGP_AAHEADER,
|
|
DBGP("Output: ptlBrushOrg=(%6ld, %6ld)"
|
|
ARGDW(pAABBP->ptlBrushOrg.x) ARGDW(pAABBP->ptlBrushOrg.y)));
|
|
|
|
DBGP_IF(DBGP_AAHEADER,
|
|
DBGP("Output: ptlSrcMask=(%6ld, %6ld)"
|
|
ARGDW(pAABBP->ptlMask.x) ARGDW(pAABBP->ptlMask.y)));
|
|
|
|
return(1);
|
|
|
|
}
|
|
|
|
|
|
#if DBG
|
|
extern INT cCXMask;
|
|
|
|
|
|
LPSTR
|
|
GetAACXFuncName(
|
|
AACXFUNC AACXFunc
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
|
|
|
|
|
|
Arguments:
|
|
|
|
|
|
|
|
|
|
Return Value:
|
|
|
|
|
|
|
|
|
|
Author:
|
|
|
|
06-Jan-1999 Wed 19:11:27 created -by- Daniel Chou (danielc)
|
|
|
|
|
|
Revision History:
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
if (AACXFunc == (AACXFUNC)RepDIB_CX) {
|
|
|
|
return("RepDIB_CX");
|
|
|
|
} else if (AACXFunc == (AACXFUNC)SkipDIB_CX) {
|
|
|
|
return("SkipDIB_CX");
|
|
|
|
} else if (AACXFunc == (AACXFUNC)CopyDIB_CX) {
|
|
|
|
return("CopyDIB_CX");
|
|
|
|
} else if (AACXFunc == (AACXFUNC)ShrinkDIB_CX) {
|
|
|
|
return("ShrinkDIB_CX");
|
|
|
|
} else if (AACXFunc == (AACXFUNC)ExpandDIB_CX) {
|
|
|
|
return("ExpandDIB_CX");
|
|
|
|
} else if (AACXFunc == (AACXFUNC)GrayRepDIB_CX) {
|
|
|
|
return("GrayRepDIB_CX");
|
|
|
|
} else if (AACXFunc == (AACXFUNC)GraySkipDIB_CX) {
|
|
|
|
return("GraySkipDIB_CX");
|
|
|
|
} else if (AACXFunc == (AACXFUNC)GrayCopyDIB_CXGray) {
|
|
|
|
return("GrayCopyDIB_CXGray");
|
|
|
|
} else if (AACXFunc == (AACXFUNC)GrayCopyDIB_CX) {
|
|
|
|
return("GrayCopyDIB_CX");
|
|
|
|
} else if (AACXFunc == (AACXFUNC)GrayExpandDIB_CX) {
|
|
|
|
return("GrayExpandDIB_CX");
|
|
|
|
} else if (AACXFunc == (AACXFUNC)GrayShrinkDIB_CX) {
|
|
|
|
return("GrayShrinkDIB_CX");
|
|
|
|
} else {
|
|
|
|
DBGP("ERROR: Unknown AACXFUNC=%p, Function" ARGPTR(AACXFunc));
|
|
|
|
return("Unknown AACXFUNC");
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
LPSTR
|
|
GetAACYFuncName(
|
|
AACYFUNC AACYFunc
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
|
|
|
|
|
|
Arguments:
|
|
|
|
|
|
|
|
|
|
Return Value:
|
|
|
|
|
|
|
|
|
|
Author:
|
|
|
|
06-Jan-1999 Wed 19:11:27 created -by- Daniel Chou (danielc)
|
|
|
|
|
|
Revision History:
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
if (AACYFunc == (AACYFUNC)TileDIB_CY) {
|
|
|
|
return("TileDIB_CY");
|
|
|
|
} else if (AACYFunc == (AACYFUNC)RepDIB_CY) {
|
|
|
|
return("RepDIB_CY");
|
|
|
|
} else if (AACYFunc == (AACYFUNC)FastExpAA_CY) {
|
|
|
|
return("FastExpAA_CY");
|
|
|
|
} else if (AACYFunc == (AACYFUNC)SkipDIB_CY) {
|
|
|
|
return("SkipDIB_CY");
|
|
|
|
} else if (AACYFunc == (AACYFUNC)BltDIB_CY) {
|
|
|
|
return("BltDIB_CY");
|
|
|
|
} else if (AACYFunc == (AACYFUNC)ShrinkDIB_CY) {
|
|
|
|
return("ShrinkDIB_CY");
|
|
|
|
} else if (AACYFunc == (AACYFUNC)ShrinkDIB_CY_SrkCX) {
|
|
|
|
return("ShrinkDIB_CY_SrkCX");
|
|
|
|
} else if (AACYFunc == (AACYFUNC)ExpandDIB_CY_ExpCX) {
|
|
|
|
return("ExpandDIB_CY_ExpCX");
|
|
|
|
} else if (AACYFunc == (AACYFUNC)ExpandDIB_CY) {
|
|
|
|
return("ExpandDIB_CY");
|
|
|
|
} else if (AACYFunc == (AACYFUNC)GrayExpandDIB_CY_ExpCX) {
|
|
|
|
return("GrayExpandDIB_CY_ExpCX");
|
|
|
|
} else if (AACYFunc == (AACYFUNC)GrayExpandDIB_CY) {
|
|
|
|
return("GrayExpandDIB_CY");
|
|
|
|
} else if (AACYFunc == (AACYFUNC)GrayShrinkDIB_CY) {
|
|
|
|
return("GrayShrinkDIB_CY");
|
|
|
|
} else {
|
|
|
|
DBGP("ERROR: Unknown AACYFUNC=%p, Function" ARGPTR(AACYFunc));
|
|
|
|
return("Unknown AACYFUNC");
|
|
}
|
|
}
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
LONG
|
|
HTENTRY
|
|
SetupAAHeader(
|
|
PHALFTONERENDER pHR,
|
|
PDEVICECOLORINFO pDCI,
|
|
PAAHEADER pAAHdr,
|
|
AACYFUNC *pAACYFunc
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
|
|
|
|
|
|
Arguments:
|
|
|
|
|
|
|
|
|
|
Return Value:
|
|
|
|
|
|
|
|
|
|
Author:
|
|
|
|
03-Apr-1998 Fri 04:27:16 created -by- Daniel Chou (danielc)
|
|
|
|
|
|
Revision History:
|
|
|
|
07-Aug-1998 Fri 19:28:21 updated -by- Daniel Chou (danielc)
|
|
Fix the mirror/upside-down banding problems, the problem is when we
|
|
flip the destination original size rectangle we did not flip the
|
|
the real destination rectangle, this cause the the offset getting too
|
|
big and its pointer offset passed the end of the bitmap, it also
|
|
has problem that when we did not flip the destination rectangle
|
|
the wrong portion of the bitmap will be in the band.
|
|
|
|
--*/
|
|
|
|
{
|
|
PAAINFO pAAInfoCX;
|
|
PAAINFO pAAInfoCY;
|
|
PBITBLTPARAMS pBBP;
|
|
PHTSURFACEINFO pSrcSI;
|
|
PHTSURFACEINFO pDstSI;
|
|
PHTSURFACEINFO pMaskSI;
|
|
LPBYTE pbExtra;
|
|
AACYFUNC AACYFunc;
|
|
AABBP aabbp;
|
|
LONG iFree;
|
|
LONG cbFreeBuf;
|
|
LONG Top;
|
|
LONG Bottom;
|
|
LONG cyNext;
|
|
LONG cxSize;
|
|
LONG cbMaskSrc;
|
|
LONG cIn;
|
|
LONG cOut;
|
|
LONG cbCYExtra;
|
|
LONG cbCXExtra;
|
|
LONG cbInBuf;
|
|
LONG cbFUDI;
|
|
LONG cbVGA256Xlate;
|
|
LONG cbOutBuf;
|
|
LONG cbAlphaBuf;
|
|
LONG cbIdxBGR;
|
|
LONG Result;
|
|
LONG cbSrcPel;
|
|
DWORD PrimAdjFlags;
|
|
UINT DstSurfFmt;
|
|
|
|
|
|
pBBP = pHR->pBitbltParams;
|
|
pSrcSI = pHR->pSrcSI;
|
|
pDstSI = pHR->pDestSI;
|
|
pMaskSI = pHR->pSrcMaskSI;
|
|
DstSurfFmt = (UINT)pDstSI->SurfaceFormat;
|
|
PrimAdjFlags = (DWORD)pHR->pDevClrAdj->PrimAdj.Flags;
|
|
cbSrcPel = (pHR->pDevClrAdj->DMI.Flags & DMIF_GRAY) ? sizeof(BYTE) :
|
|
sizeof(BGR8);
|
|
DBGP_IF(DBGP_AAHEADER,
|
|
DBGP("\nSrcSI=%ld x %ld [Format=%ld], DestSI=%ld x %ld [Format=%ld]"
|
|
ARGDW(pSrcSI->Width) ARGDW(pSrcSI->Height)
|
|
ARGDW(pSrcSI->SurfaceFormat)
|
|
ARGDW(pDstSI->Width) ARGDW(pDstSI->Height)
|
|
ARGDW(pDstSI->SurfaceFormat)));
|
|
|
|
aabbp.AAHFlags = (PrimAdjFlags & DCA_BBPF_AA_OFF) ? AAHF_BBPF_AA_OFF : 0;
|
|
|
|
if (pBBP->Flags & BBPF_TILE_SRC) {
|
|
|
|
aabbp.AAHFlags |= AAHF_TILE_SRC;
|
|
aabbp.AAHFlags |= AAHF_BBPF_AA_OFF;
|
|
}
|
|
|
|
if (ComputeAABBP(pBBP, pDstSI, &aabbp, cbSrcPel == sizeof(BYTE)) <= 0) {
|
|
|
|
return(0);
|
|
}
|
|
|
|
cbCXExtra = sizeof(RGBLUTAA);
|
|
|
|
if (PrimAdjFlags & DCA_ALPHA_BLEND) {
|
|
|
|
aabbp.AAHFlags |= AAHF_ALPHA_BLEND;
|
|
|
|
if (PrimAdjFlags & DCA_CONST_ALPHA) {
|
|
|
|
aabbp.AAHFlags |= AAHF_CONST_ALPHA;
|
|
|
|
cbCXExtra += (AB_BGR_CA_SIZE + AB_CONST_SIZE);
|
|
|
|
} else {
|
|
|
|
if (PrimAdjFlags & DCA_AB_PREMUL_SRC) {
|
|
|
|
//
|
|
// Set the flag so we will try to compute premul's orginal src
|
|
//
|
|
|
|
pAAHdr->SrcSurfInfo.Flags |= AASIF_AB_PREMUL_SRC;
|
|
}
|
|
|
|
if (PrimAdjFlags & DCA_AB_DEST) {
|
|
|
|
aabbp.AAHFlags |= AAHF_AB_DEST;
|
|
}
|
|
|
|
cbCXExtra += AB_BGR_SIZE;
|
|
}
|
|
}
|
|
|
|
if (PrimAdjFlags & DCA_NO_MAPPING_TABLE) {
|
|
|
|
aabbp.AAHFlags &= ~AAHF_DO_CLR_MAPPING;
|
|
}
|
|
|
|
ALIGN_MEM(cbCXExtra, cbCXExtra);
|
|
|
|
DBGP_IF(DBGP_LUT_MAP,
|
|
DBGP("CXExtra=%ld (RGBLUTAA) + 0 (Mapping=%hs) = %ld"
|
|
ARGDW(sizeof(RGBLUTAA))
|
|
ARGPTR((aabbp.AAHFlags & AAHF_DO_SRC_CLR_MAPPING) ?
|
|
"SRC" : "DST")
|
|
ARGDW(sizeof(RGBLUTAA) + 0)));
|
|
|
|
//
|
|
// This flag is set when reading the source bitmap, so the pointer will
|
|
// advanced to next scanline, this flag will not set for the destiantion
|
|
// since when blending and we reading from destination, we do not want to
|
|
// advanced the destination pointer because it will be done during output
|
|
//
|
|
|
|
ComputeInputColorInfo((LPBYTE)pSrcSI->pColorTriad->pColorTable,
|
|
(UINT)pSrcSI->pColorTriad->BytesPerEntry,
|
|
(UINT)pSrcSI->pColorTriad->PrimaryOrder,
|
|
&(pHR->BFInfo),
|
|
&(pAAHdr->SrcSurfInfo));
|
|
|
|
pAAHdr->SrcSurfInfo.Flags |= AASIF_INC_PB |
|
|
((cbSrcPel == sizeof(BYTE)) ? AASIF_GRAY : 0);
|
|
|
|
|
|
if (PrimAdjFlags & DCA_USE_ADDITIVE_PRIMS) {
|
|
|
|
aabbp.AAHFlags |= AAHF_ADDITIVE;
|
|
}
|
|
|
|
if (pBBP->Flags & BBPF_TILE_SRC) {
|
|
|
|
aabbp.AAHFlags &= ~AAHF_DO_FIXUPDIB;
|
|
}
|
|
|
|
if (aabbp.AAHFlags & AAHF_BBPF_AA_OFF) {
|
|
|
|
aabbp.AAHFlags &= ~AAHF_DO_FIXUPDIB;
|
|
}
|
|
|
|
if (aabbp.AAHFlags & AAHF_DO_FIXUPDIB) {
|
|
|
|
CheckBMPNeedFixup(pDCI, pAAHdr, pSrcSI, &aabbp);
|
|
|
|
if (aabbp.AAHFlags & AAHF_SHRINKING) {
|
|
|
|
if (PrimAdjFlags & DCA_BBPF_AA_OFF) {
|
|
|
|
aabbp.AAHFlags |= AAHF_BBPF_AA_OFF;
|
|
|
|
} else {
|
|
|
|
aabbp.AAHFlags &= ~AAHF_BBPF_AA_OFF;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
if (aabbp.AAHFlags & AAHF_BBPF_AA_OFF) {
|
|
|
|
aabbp.AAHFlags &= ~AAHF_FAST_EXP_AA;
|
|
}
|
|
|
|
if (pMaskSI) {
|
|
|
|
aabbp.AAHFlags |= AAHF_HAS_MASK;
|
|
}
|
|
|
|
if (!(pAAInfoCX = aabbp.AABuildCXFunc(pDCI,
|
|
aabbp.AAHFlags,
|
|
&aabbp.rclSrc.left,
|
|
&aabbp.rclSrc.right,
|
|
pSrcSI->Width,
|
|
aabbp.rclDstOrg.left,
|
|
aabbp.rclDstOrg.right,
|
|
&aabbp.rclDst.left,
|
|
&aabbp.rclDst.right,
|
|
cbCXExtra))) {
|
|
|
|
//
|
|
// Remove cbCXExtra (use pDCI's rgbLUT and BGRMapTable, AlphaBlendBGR)
|
|
//
|
|
|
|
if (!(pAAInfoCX = aabbp.AABuildCXFunc(pDCI,
|
|
aabbp.AAHFlags,
|
|
&aabbp.rclSrc.left,
|
|
&aabbp.rclSrc.right,
|
|
pSrcSI->Width,
|
|
aabbp.rclDstOrg.left,
|
|
aabbp.rclDstOrg.right,
|
|
&aabbp.rclDst.left,
|
|
&aabbp.rclDst.right,
|
|
cbCXExtra = 0))) {
|
|
|
|
return(HTERR_INSUFFICIENT_MEMORY);
|
|
}
|
|
}
|
|
|
|
// Bug 27036: reject empty rectangles
|
|
if(!pAAInfoCX->cIn || !pAAInfoCX->cOut)
|
|
{
|
|
#if 0
|
|
LONG crash = 1 ; // empty src or dest rectangle!
|
|
crash /= (pAAInfoCX->cIn * pAAInfoCX->cOut); // delete when debugging is complete.
|
|
if(crash)
|
|
return 0 ;
|
|
#endif
|
|
HTFreeMem(pAAInfoCX);
|
|
return 0 ;
|
|
}
|
|
|
|
if (cbCXExtra) {
|
|
|
|
pAAHdr->prgbLUT = (PRGBLUTAA)(pbExtra = pAAInfoCX->pbExtra);
|
|
pbExtra += sizeof(RGBLUTAA);
|
|
|
|
ASSERT_MEM_ALIGN(pAAHdr->prgbLUT, sizeof(LONG));
|
|
|
|
if (aabbp.AAHFlags & AAHF_ALPHA_BLEND) {
|
|
|
|
pAAHdr->pAlphaBlendBGR = (LPBYTE)pbExtra;
|
|
|
|
if (PrimAdjFlags & DCA_CONST_ALPHA) {
|
|
|
|
pbExtra += (AB_BGR_CA_SIZE + AB_CONST_SIZE);
|
|
|
|
} else {
|
|
|
|
pbExtra += AB_BGR_SIZE;
|
|
}
|
|
}
|
|
|
|
} else {
|
|
|
|
ASSERT_MEM_ALIGN(&pDCI->rgbLUT, sizeof(LONG));
|
|
|
|
aabbp.AAHFlags |= AAHF_USE_DCI_DATA;
|
|
pAAHdr->prgbLUT = &pDCI->rgbLUT;
|
|
|
|
if (aabbp.AAHFlags & AAHF_ALPHA_BLEND) {
|
|
|
|
pAAHdr->pAlphaBlendBGR = pDCI->pAlphaBlendBGR;
|
|
|
|
if (PrimAdjFlags & DCA_CONST_ALPHA) {
|
|
|
|
pAAHdr->pAlphaBlendBGR += AB_BGR_SIZE;
|
|
}
|
|
}
|
|
}
|
|
|
|
pAAHdr->pIdxBGR = pAAHdr->prgbLUT->IdxBGR;
|
|
|
|
if (aabbp.AAHFlags & AAHF_FLIP_X) {
|
|
|
|
DBGP_IF(DBGP_AAHEADER,
|
|
DBGP("X Dst=(%ld - %ld)=%ld change it to (%ld - %ld), ptlFlip.x=%ld"
|
|
ARGDW(aabbp.rclDst.left) ARGDW(aabbp.rclDst.right)
|
|
ARGDW(aabbp.rclDst.right - aabbp.rclDst.left)
|
|
ARGDW(aabbp.ptlFlip.x - aabbp.rclDst.left - 1)
|
|
ARGDW(aabbp.ptlFlip.x - aabbp.rclDst.right - 1)
|
|
ARGDW(aabbp.ptlFlip.x)));
|
|
|
|
aabbp.rclDst.left = aabbp.ptlFlip.x - aabbp.rclDst.left - 1;
|
|
aabbp.rclDst.right = aabbp.ptlFlip.x - aabbp.rclDst.right - 1;
|
|
}
|
|
|
|
//
|
|
// cbCYExtra is for the input scan line, add one because we want to
|
|
// run it in DWORD mode so we need at least an extra byte at end
|
|
// of input buffer
|
|
//
|
|
|
|
cIn = pAAInfoCX->cIn;
|
|
cOut = pAAInfoCX->cOut;
|
|
cbInBuf = cIn + 6; // left extra=3, right extra=3
|
|
cbFreeBuf =
|
|
cbCYExtra = 0;
|
|
AACYFunc = NULL;
|
|
|
|
if (aabbp.AAHFlags & AAHF_BBPF_AA_OFF) {
|
|
|
|
switch (aabbp.CYFuncMode) {
|
|
|
|
case AACYMODE_SHRINK:
|
|
case AACYMODE_SHRINK_SRKCX:
|
|
|
|
AACYFunc = (AACYFUNC)SkipDIB_CY;
|
|
break;
|
|
|
|
case AACYMODE_EXPAND:
|
|
case AACYMODE_EXPAND_EXPCX:
|
|
|
|
cbCYExtra = (aabbp.AAHFlags & AAHF_ALPHA_BLEND) ?
|
|
(sizeof(BGR8) * (cOut + 6)) : 0;
|
|
|
|
AACYFunc = (AACYFUNC)RepDIB_CY;
|
|
break;
|
|
|
|
case AACYMODE_BLT:
|
|
|
|
AACYFunc = (AACYFUNC)BltDIB_CY;
|
|
break;
|
|
}
|
|
|
|
if (AACYFunc) {
|
|
|
|
switch (aabbp.CXFuncMode) {
|
|
|
|
case AACXMODE_BLT:
|
|
|
|
aabbp.AACXFunc = (cbSrcPel == sizeof(BYTE)) ?
|
|
(AACXFUNC)GrayCopyDIB_CXGray :
|
|
(AACXFUNC)CopyDIB_CX;
|
|
break;
|
|
|
|
case AACXMODE_SHRINK:
|
|
|
|
aabbp.AACXFunc = (cbSrcPel == sizeof(BYTE)) ?
|
|
(AACXFUNC)GraySkipDIB_CX :
|
|
(AACXFUNC)SkipDIB_CX;
|
|
break;
|
|
|
|
case AACXMODE_EXPAND:
|
|
|
|
aabbp.AACXFunc = (cbSrcPel == sizeof(BYTE)) ?
|
|
(AACXFUNC)GrayRepDIB_CX :
|
|
(AACXFUNC)RepDIB_CX;
|
|
break;
|
|
}
|
|
|
|
aabbp.CYFuncMode = AACYMODE_NONE;
|
|
}
|
|
}
|
|
|
|
switch (aabbp.CYFuncMode) {
|
|
|
|
case AACYMODE_TILE:
|
|
|
|
AACYFunc = TileDIB_CY;
|
|
cbCYExtra = (cbSrcPel == sizeof(BYTE)) ? (cIn * sizeof(WORD)) : 0;
|
|
break;
|
|
|
|
case AACYMODE_BLT:
|
|
|
|
AACYFunc = (AACYFUNC)BltDIB_CY;
|
|
break;
|
|
|
|
case AACYMODE_SHRINK:
|
|
|
|
//
|
|
// We need to make sure Off555Buf does not changed
|
|
//
|
|
|
|
cbFreeBuf = (sizeof(LONG) * 256 * 2);
|
|
|
|
if (cbSrcPel == sizeof(BYTE)) {
|
|
|
|
AACYFunc = GrayShrinkDIB_CY;
|
|
cbCYExtra = (sizeof(LONG) * cOut * 3) + cbFreeBuf +
|
|
((cOut + 6) * cbSrcPel);
|
|
|
|
} else {
|
|
|
|
AACYFunc = ShrinkDIB_CY;
|
|
cbCYExtra = (sizeof(RGBL) * cIn * 3) + cbFreeBuf +
|
|
(cbInBuf * cbSrcPel);
|
|
}
|
|
|
|
break;
|
|
|
|
case AACYMODE_SHRINK_SRKCX:
|
|
|
|
AACYFunc = ShrinkDIB_CY_SrkCX;
|
|
cbFreeBuf = (sizeof(LONG) * 256 * 2);
|
|
cbCYExtra = (sizeof(RGBL) * (pAAInfoCX->cAADone + 2) * 3) + cbFreeBuf;
|
|
break;
|
|
|
|
case AACYMODE_EXPAND:
|
|
|
|
AACYFunc = (cbSrcPel == sizeof(BYTE)) ? GrayExpandDIB_CY :
|
|
ExpandDIB_CY;
|
|
cbCYExtra = (cbFreeBuf = (sizeof(LONG) * 256 * 4)) +
|
|
((cOut + 6) * cbSrcPel * 6);
|
|
break;
|
|
|
|
case AACYMODE_EXPAND_EXPCX:
|
|
|
|
//
|
|
// This function use IputBufBeg to sharpening the input scanline so we
|
|
// need 4 extra BGR8 for running the expand pre-read
|
|
//
|
|
|
|
if (aabbp.AAHFlags & AAHF_FAST_EXP_AA) {
|
|
|
|
DBGP_IF(DBGP_AAHEADER, DBGP("Use FastExpAA_CY functions"));
|
|
|
|
cbCYExtra = (cbInBuf * 5 * cbSrcPel);
|
|
AACYFunc = (AACYFUNC)FastExpAA_CY;
|
|
|
|
} else {
|
|
|
|
AACYFunc = (cbSrcPel == sizeof(BYTE)) ? GrayExpandDIB_CY_ExpCX :
|
|
ExpandDIB_CY_ExpCX;
|
|
cbCYExtra = (cbFreeBuf = (sizeof(LONG) * 256 * 4)) +
|
|
(cbInBuf * cbSrcPel * 3) + ((cOut + 6) * cbSrcPel * 4);
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
cbAlphaBuf = (aabbp.AAHFlags & AAHF_ALPHA_BLEND) ? cOut : 0;
|
|
pAAHdr->DstSurfInfo.Flags = (cbSrcPel == sizeof(BYTE)) ? AASIF_GRAY : 0;
|
|
pAAHdr->DstSurfInfo.cbCX = cbAlphaBuf * cbSrcPel;
|
|
|
|
ALIGN_MEM(cbAlphaBuf, (cbAlphaBuf + 2 + 6) * cbSrcPel);
|
|
ALIGN_MEM(cbCYExtra, cbCYExtra);
|
|
|
|
//
|
|
// cbInBuf is for the input scan line of EXPAND/SHRINK mode, add one
|
|
// because we want to run it in DWORD mode so we need at least an extra
|
|
// byte at end of input buffer
|
|
//
|
|
// 26-Jun-1998 Fri 16:03:26 updated -by- Daniel Chou (danielc)
|
|
// The cbOutBuf is used only when we flipping in X direction, this is
|
|
// needed since the input/output buffer may collide into each other
|
|
//
|
|
|
|
ALIGN_MEM(cbInBuf, (cbInBuf + 2) * cbSrcPel);
|
|
ALIGN_MEM(cbOutBuf, (cOut + (FAST_MAX_CX * 2)) * sizeof(BGRF));
|
|
|
|
cbMaskSrc = (aabbp.AAHFlags & AAHF_HAS_MASK) ?
|
|
(ComputeBytesPerScanLine(BMF_1BPP, 4, cIn) + 4) : 0;
|
|
cbMaskSrc = _ALIGN_MEM(cbMaskSrc);
|
|
|
|
if (cbInBuf < cbAlphaBuf) {
|
|
|
|
cbInBuf = cbAlphaBuf;
|
|
}
|
|
|
|
if ((aabbp.AAHFlags & (AAHF_ALPHA_BLEND | AAHF_CONST_ALPHA)) ==
|
|
AAHF_ALPHA_BLEND) {
|
|
|
|
ALIGN_MEM(cbAlphaBuf, cOut);
|
|
|
|
} else {
|
|
|
|
cbAlphaBuf = 0;
|
|
}
|
|
|
|
DBGP_IF(DBGP_FIXUPDIB,
|
|
DBGP("** Allocate cIn=%ld, cOut=%ld, cbInBuf=%ld, cbOutBuf=%ld, cbMaskSrc=%ld"
|
|
ARGDW(cIn) ARGDW(cOut) ARGDW(cbInBuf) ARGDW(cbOutBuf)
|
|
ARGDW(cbMaskSrc)));
|
|
|
|
|
|
if ((DstSurfFmt == BMF_8BPP_VGA256) && (pHR->pXlate8BPP)) {
|
|
|
|
ALIGN_MEM(cbVGA256Xlate, SIZE_XLATE_666);
|
|
|
|
DBGP_IF((DBGP_AAHTPAT | DBGP_AAHT_MEM),
|
|
DBGP("Allocate %ld bytes of Xlate8BPP" ARGDW(cbVGA256Xlate)));
|
|
|
|
} else {
|
|
|
|
cbVGA256Xlate = 0;
|
|
}
|
|
|
|
if (aabbp.AAHFlags & AAHF_DO_FIXUPDIB) {
|
|
|
|
ALIGN_MEM(cbFUDI, (cIn + 4) * cbSrcPel);
|
|
|
|
} else {
|
|
|
|
cbFUDI = 0;
|
|
}
|
|
|
|
if ((pAAHdr->SrcSurfInfo.Flags & AASIF_GRAY) &&
|
|
(pHR->BFInfo.Flags & BFIF_RGB_888) &&
|
|
(pAAHdr->SrcSurfInfo.AABFData.Flags & AABF_MASK_IS_ORDER) &&
|
|
(pHR->BFInfo.RGBOrder.Index != PRIMARY_ORDER_BGR)) {
|
|
|
|
//
|
|
// This is for mapping >= 16bpp source's IdxBGR to gray, when mapping
|
|
// to gray we will make IdxBGR to a correct source order so that it
|
|
// will optimized the source input function speed
|
|
//
|
|
// The AABF_MASK_IS_ORDER indicate the source is 8-bits each of Red,
|
|
// green and blue and it is only occuply lower 24-bits of either
|
|
// a 24-bits or a 32-bits data
|
|
//
|
|
|
|
ALIGN_MEM(cbIdxBGR, sizeof(LONG) * 256 * 3);
|
|
|
|
DBGP_IF(DBGP_AAHEADER,
|
|
DBGP("Allocate gray non 24bits BGR [%ld] IDXBGR of %ld bytes"
|
|
ARGDW(pHR->BFInfo.RGBOrder.Index) ARGDW(cbIdxBGR)));
|
|
|
|
} else {
|
|
|
|
cbIdxBGR = 0;
|
|
}
|
|
|
|
if (pAAInfoCY = aabbp.AABuildCYFunc(pDCI,
|
|
aabbp.AAHFlags,
|
|
&aabbp.rclSrc.top,
|
|
&aabbp.rclSrc.bottom,
|
|
pSrcSI->Height,
|
|
aabbp.rclDstOrg.top,
|
|
aabbp.rclDstOrg.bottom,
|
|
&aabbp.rclDst.top,
|
|
&aabbp.rclDst.bottom,
|
|
cbInBuf + cbOutBuf + cbMaskSrc +
|
|
(cbFUDI * 6) + cbAlphaBuf +
|
|
cbIdxBGR +
|
|
cbVGA256Xlate + cbCYExtra))
|
|
{
|
|
// Bug 27036: reject empty rectangles
|
|
if(!pAAInfoCY->cIn || !pAAInfoCY->cOut)
|
|
{
|
|
#if 0
|
|
LONG crash = 1 ; // empty src or dest rectangle!
|
|
crash /= (pAAInfoCY->cIn * pAAInfoCY->cOut); // delete when debugging is complete.
|
|
if(crash)
|
|
return 0 ;
|
|
#endif
|
|
HTFreeMem(pAAInfoCX);
|
|
HTFreeMem(pAAInfoCY);
|
|
return 0 ;
|
|
}
|
|
|
|
|
|
pbExtra = pAAInfoCY->pbExtra + cbCYExtra;
|
|
pAAHdr->Flags = aabbp.AAHFlags;
|
|
pAAHdr->SrcSurfInfo.cbCX = cbSrcPel * cIn;
|
|
pAAHdr->pInputBeg = (PBGR8)pbExtra;
|
|
pbExtra += cbInBuf;
|
|
|
|
if (cbAlphaBuf) {
|
|
|
|
//
|
|
// 04-Aug-2000 Fri 10:31:45 updated -by- Daniel Chou (danielc)
|
|
// Since cbAlphaBuf is Memoey Aliged Adjusted, we want the
|
|
// pSrcAVEnd to be at exactly count of cOut not cbAlphaBuf
|
|
//
|
|
|
|
pAAHdr->pSrcAV =
|
|
pAAHdr->pSrcAVBeg = (LPBYTE)pbExtra;
|
|
pAAHdr->pSrcAVEnd = (LPBYTE)pbExtra + cOut;
|
|
pbExtra += cbAlphaBuf;
|
|
pAAHdr->SrcAVInc = sizeof(BYTE);
|
|
}
|
|
|
|
if (cbFUDI) {
|
|
|
|
pAAHdr->pbFixupDIB = (LPBYTE)pbExtra;
|
|
pAAHdr->FUDI.cbbgr = (DWORD)cbFUDI;
|
|
|
|
for (Top = 0; Top < 6; Top++) {
|
|
|
|
pAAHdr->FUDI.prgbD[Top] = (PBGR8)pbExtra;
|
|
pbExtra += cbFUDI;
|
|
}
|
|
}
|
|
|
|
if (cbVGA256Xlate) {
|
|
|
|
pAAHdr->pXlate8BPP = pbExtra;
|
|
pbExtra += cbVGA256Xlate;
|
|
}
|
|
|
|
if (cbMaskSrc) {
|
|
|
|
pAAHdr->pMaskSrc = pbExtra;
|
|
pbExtra += cbMaskSrc;
|
|
}
|
|
|
|
if (cbIdxBGR) {
|
|
|
|
//
|
|
// The pIdxBGR is a local version that will be later re-arranged
|
|
// from pAAHdr->pIdxBGR to correct source byte order in
|
|
// SetGrayColorTable() function
|
|
//
|
|
|
|
pAAHdr->SrcSurfInfo.pIdxBGR = (PLONG)pbExtra;
|
|
pbExtra += cbIdxBGR;
|
|
|
|
} else {
|
|
|
|
pAAHdr->SrcSurfInfo.pIdxBGR = pAAHdr->pIdxBGR;
|
|
}
|
|
|
|
DBGP_IF(DBGP_AAHEADER,
|
|
DBGP("cbInBuf=%ld, %p-%p" ARGDW(cbInBuf)
|
|
ARGPTR(pAAHdr->pInputBeg)
|
|
ARGPTR((LPBYTE)pAAHdr->pInputBeg + cbInBuf)));
|
|
|
|
//
|
|
// FAST_MAX_CX are added to both end of AABuf, this is needed when
|
|
// we want to process the output fast, since we may need to extended
|
|
// the computation to the neighbor pixels
|
|
//
|
|
|
|
pAAHdr->pOutputBeg =
|
|
pAAHdr->pRealOutBeg =
|
|
pAAHdr->pAABufBeg = (PBGRF)pbExtra + FAST_MAX_CX;
|
|
pAAHdr->pRealOutEnd =
|
|
pAAHdr->pOutputEnd = pAAHdr->pAABufBeg + cOut;
|
|
pAAHdr->pAABufEnd = pAAHdr->pOutputEnd;
|
|
|
|
//
|
|
// Set the BGRF's Flags to 0xFF first, the 0xFF indicate that this
|
|
// pixel need to be output (masked).
|
|
//
|
|
|
|
FillMemory((LPBYTE)pAAHdr->pOutputBeg,
|
|
(LPBYTE)pAAHdr->pOutputEnd - (LPBYTE)pAAHdr->pOutputBeg,
|
|
PBGRF_MASK_FLAG);
|
|
|
|
//
|
|
// We mirror the image by composed the source the the AABuf in
|
|
// reverse way. Reading the source from left to right but when
|
|
// composed the source buffer (AABuf) we put it from right to left
|
|
//
|
|
|
|
if (aabbp.rclDst.left > aabbp.rclDst.right) {
|
|
|
|
XCHG(aabbp.rclDst.left, aabbp.rclDst.right, Result);
|
|
|
|
pAAHdr->pAABufBeg = pAAHdr->pOutputEnd - 1;
|
|
pAAHdr->pAABufEnd = pAAHdr->pOutputBeg - 1;
|
|
pAAHdr->AABufInc = -(LONG)sizeof(BGRF);
|
|
pAAHdr->pSrcAVBeg = pAAHdr->pSrcAVEnd - 1;
|
|
pAAHdr->pSrcAVEnd = pAAHdr->pSrcAV - 1;
|
|
pAAHdr->SrcAVInc = -pAAHdr->SrcAVInc;
|
|
|
|
} else {
|
|
|
|
pAAHdr->AABufInc = (LONG)sizeof(BGRF);
|
|
}
|
|
|
|
pAAHdr->ptlBrushOrg.x = aabbp.rclDst.left - aabbp.ptlBrushOrg.x;
|
|
|
|
DBGP_IF(DBGP_AAHEADER,
|
|
DBGP("pInput=%p-%p (%ld), pAABuf=%p-%p (%ld), pOutput=%p-%p, DstLeft=%ld"
|
|
ARGPTR(pAAHdr->pInputBeg)
|
|
ARGPTR((LPBYTE)pAAHdr->pInputBeg +
|
|
pAAHdr->SrcSurfInfo.cbCX)
|
|
ARGL(pAAHdr->SrcSurfInfo.cbCX)
|
|
ARGPTR(pAAHdr->pAABufBeg) ARGPTR(pAAHdr->pAABufEnd)
|
|
ARGDW(pAAHdr->AABufInc)
|
|
ARGPTR(pAAHdr->pOutputBeg) ARGPTR(pAAHdr->pOutputEnd)
|
|
ARGDW(aabbp.rclDst.left)));
|
|
|
|
|
|
if (aabbp.AAHFlags & AAHF_FLIP_Y) {
|
|
|
|
DBGP_IF(DBGP_AAHEADER,
|
|
DBGP("Y Dst=(%ld - %ld)=%ld change it to (%ld - %ld), ptlFlip.y=%ld"
|
|
ARGDW(aabbp.rclDst.top) ARGDW(aabbp.rclDst.bottom)
|
|
ARGDW(aabbp.rclDst.bottom - aabbp.rclDst.top)
|
|
ARGDW(aabbp.ptlFlip.y - aabbp.rclDst.top - 1)
|
|
ARGDW(aabbp.ptlFlip.y - aabbp.rclDst.bottom - 1)
|
|
ARGDW(aabbp.ptlFlip.y)));
|
|
|
|
aabbp.rclDst.top = aabbp.ptlFlip.y - aabbp.rclDst.top - 1;
|
|
aabbp.rclDst.bottom = aabbp.ptlFlip.y - aabbp.rclDst.bottom - 1;
|
|
}
|
|
|
|
pAAHdr->ptlBrushOrg.y = aabbp.rclDst.top - aabbp.ptlBrushOrg.y;
|
|
|
|
DBGP_IF(DBGP_AAHEADER,
|
|
DBGP("BrushOrg=(%ld, %ld) ---> (%ld, %ld)"
|
|
ARGDW(pBBP->ptlBrushOrg.x) ARGDW(pBBP->ptlBrushOrg.y)
|
|
ARGDW(pAAHdr->ptlBrushOrg.x) ARGDW(pAAHdr->ptlBrushOrg.y)));
|
|
|
|
pAAHdr->pAAInfoCX = pAAInfoCX;
|
|
pAAHdr->pAAInfoCY = pAAInfoCY;
|
|
pAAHdr->AACXFunc = aabbp.AACXFunc;
|
|
pAAHdr->SrcSurfInfo.cx = pAAInfoCX->cIn;
|
|
pAAHdr->SrcSurfInfo.cyOrg =
|
|
pAAHdr->SrcSurfInfo.cy = pAAInfoCY->cIn;
|
|
|
|
if (aabbp.AAHFlags & AAHF_HAS_MASK) {
|
|
|
|
POINTL MaskEnd;
|
|
|
|
cyNext =
|
|
cxSize = GET_PHTSI_CXSIZE(pMaskSI);
|
|
aabbp.ptlMask.x += pAAInfoCX->Mask.iBeg;
|
|
aabbp.ptlMask.y += pAAInfoCY->Mask.iBeg;
|
|
MaskEnd.x = aabbp.ptlMask.x + pAAInfoCX->Mask.iSize;
|
|
MaskEnd.y = aabbp.ptlMask.y + pAAInfoCY->Mask.iSize;
|
|
|
|
if ((aabbp.ptlMask.x < 0) ||
|
|
(aabbp.ptlMask.y < 0) ||
|
|
(MaskEnd.x > pMaskSI->Width) ||
|
|
(MaskEnd.y > pMaskSI->Height)) {
|
|
|
|
HTFreeMem(pAAInfoCX);
|
|
HTFreeMem(pAAInfoCY);
|
|
|
|
return(HTERR_SRC_MASK_BITS_TOO_SMALL);
|
|
}
|
|
|
|
pAAHdr->cyMaskNext = cyNext;
|
|
pAAHdr->cyMaskIn = pAAInfoCY->Mask.iSize;
|
|
iFree = ComputeByteOffset(BMF_1BPP,
|
|
MaskEnd.x,
|
|
&(pAAHdr->MaskBitOff));
|
|
cbFreeBuf = ComputeByteOffset(BMF_1BPP,
|
|
aabbp.ptlMask.x,
|
|
&(pAAHdr->MaskBitOff));
|
|
pAAHdr->cbMaskSrc = iFree - cbFreeBuf + 1;
|
|
pAAHdr->pMaskIn = pMaskSI->pPlane +
|
|
(aabbp.ptlMask.y * cxSize) + cbFreeBuf;
|
|
|
|
DBGP_IF(DBGP_MASK | DBGP_AAHEADER,
|
|
DBGP("CX: iMaskBeg=%ld, iMaskSize=%ld, cMaskIn=%ld, cMaskOut=%ld"
|
|
ARGDW(pAAInfoCX->Mask.iBeg) ARGDW(pAAInfoCX->Mask.iSize)
|
|
ARGDW(pAAInfoCX->Mask.cIn) ARGDW(pAAInfoCX->Mask.cOut)));
|
|
|
|
DBGP_IF(DBGP_MASK | DBGP_AAHEADER,
|
|
DBGP("CY: iMaskBeg=%ld, iMaskSize=%ld, cMaskIn=%ld, cMaskOut=%ld"
|
|
ARGDW(pAAInfoCY->Mask.iBeg) ARGDW(pAAInfoCY->Mask.iSize)
|
|
ARGDW(pAAInfoCY->Mask.cIn) ARGDW(pAAInfoCY->Mask.cOut)));
|
|
|
|
DBGP_IF(DBGP_MASK | DBGP_AAHEADER,
|
|
DBGP("aabbp.ptlMask x=%ld - %ld, cb=%ld, MaskBitOff=%02lx [%ld]"
|
|
ARGDW(aabbp.ptlMask.x) ARGDW(MaskEnd.x)
|
|
ARGDW(pAAHdr->cbMaskSrc) ARGDW(pAAHdr->MaskBitOff)
|
|
ARGDW(cbFreeBuf)));
|
|
|
|
//
|
|
// 0x01 in the source means use modified pixel, for the
|
|
// reason of or in the mask, we will use 0=0xFF, 1=0x00
|
|
// in the mask
|
|
//
|
|
|
|
|
|
if (pBBP->Flags & BBPF_INVERT_SRC_MASK) {
|
|
|
|
aabbp.AAHFlags |= AAHF_INVERT_MASK;
|
|
}
|
|
|
|
pAAHdr->AAMaskCXFunc = aabbp.AAMaskCXFunc;
|
|
pAAHdr->AAMaskCYFunc = aabbp.AAMaskCYFunc;
|
|
|
|
SETDBGVAR(cCXMask, 0);
|
|
|
|
DBGP_IF(DBGP_AAHEADER,
|
|
DBGP("--- SrcMask=(%5ld, %5ld)->(%5ld, %5ld) ---"
|
|
ARGDW(pBBP->ptlSrcMask.x) ARGDW(pBBP->ptlSrcMask.y)
|
|
ARGDW(aabbp.ptlMask.x) ARGDW(aabbp.ptlMask.y)));
|
|
}
|
|
|
|
cyNext =
|
|
cxSize = GET_PHTSI_CXSIZE(pSrcSI);
|
|
|
|
pAAHdr->cyABNext =
|
|
pAAHdr->SrcSurfInfo.cyNext = cyNext;
|
|
pAAHdr->SrcSurfInfo.pbOrg =
|
|
pAAHdr->SrcSurfInfo.pb =
|
|
pSrcSI->pPlane + (aabbp.rclSrc.top * cxSize) +
|
|
ComputeByteOffset((UINT)pSrcSI->SurfaceFormat,
|
|
aabbp.rclSrc.left,
|
|
&(pAAHdr->SrcSurfInfo.BitOffset));
|
|
|
|
pAAHdr->GetAVCXFunc = aabbp.GetAVCXFunc;
|
|
pAAHdr->GetAVCYFunc = aabbp.GetAVCYFunc;
|
|
|
|
DBGP_IF(DBGP_AAHEADER,
|
|
DBGP("** pIn: (%p-%p), Beg=(%4ld, %4ld)=%p [%5ld], XOff=%4ld:%ld, cbCYExtra=%p-%p (%ld)"
|
|
ARGPTR(pSrcSI->pPlane)
|
|
ARGPTR(pSrcSI->pPlane + (cxSize * pSrcSI->Height))
|
|
ARGDW(aabbp.rclSrc.left) ARGDW(aabbp.rclSrc.top)
|
|
ARGPTR(pAAHdr->SrcSurfInfo.pb)
|
|
ARGDW(pAAHdr->SrcSurfInfo.cyNext)
|
|
ARGDW(ComputeByteOffset((UINT)pSrcSI->SurfaceFormat,
|
|
aabbp.rclSrc.left,
|
|
&(pAAHdr->SrcSurfInfo.BitOffset)))
|
|
ARGDW(pAAHdr->SrcSurfInfo.BitOffset)
|
|
ARGPTR(pAAInfoCY->pbExtra)
|
|
ARGPTR(pAAInfoCY->pbExtra + cbCYExtra)
|
|
ARGDW(cbCYExtra)));
|
|
|
|
//
|
|
// We do up-side-down output by writing to the destination scan lines
|
|
// in reverse order.
|
|
//
|
|
|
|
cxSize = GET_PHTSI_CXSIZE(pDstSI);
|
|
cyNext = (aabbp.rclDst.top > aabbp.rclDst.bottom) ? -cxSize :
|
|
cxSize;
|
|
pAAHdr->DstSurfInfo.cyNext = cyNext;
|
|
pAAHdr->DstSurfInfo.pbOrg =
|
|
pAAHdr->DstSurfInfo.pb =
|
|
pDstSI->pPlane + (aabbp.rclDst.top * cxSize) +
|
|
ComputeByteOffset((UINT)DstSurfFmt,
|
|
aabbp.rclDst.left,
|
|
&(pAAHdr->DstSurfInfo.BitOffset));
|
|
pAAHdr->pOutLast = pAAHdr->DstSurfInfo.pb +
|
|
(pAAHdr->DstSurfInfo.cyNext *
|
|
pAAInfoCY->cOut);
|
|
pAAHdr->DstSurfInfo.cx = cOut;
|
|
pAAHdr->DstSurfInfo.cyOrg =
|
|
pAAHdr->DstSurfInfo.cy = pAAInfoCY->cOut;
|
|
pAAHdr->Flags = aabbp.AAHFlags; // Re-Save
|
|
*pAACYFunc = AACYFunc;
|
|
|
|
#if DBG
|
|
pAAHdr->pOutBeg = pDstSI->pPlane +
|
|
(aabbp.rclDst.top * cxSize) +
|
|
ComputeByteOffset((UINT)DstSurfFmt,
|
|
aabbp.rclDst.left,
|
|
(LPBYTE)&iFree);
|
|
pAAHdr->pOutEnd = pDstSI->pPlane +
|
|
(aabbp.rclDst.bottom * cxSize) +
|
|
ComputeByteOffset((UINT)DstSurfFmt,
|
|
aabbp.rclDst.right,
|
|
(LPBYTE)&iFree);
|
|
|
|
if (pAAHdr->pOutBeg > pAAHdr->pOutEnd) {
|
|
|
|
pAAHdr->pOutEnd = pDstSI->pPlane +
|
|
(aabbp.rclDst.top * cxSize) +
|
|
ComputeByteOffset((UINT)DstSurfFmt,
|
|
aabbp.rclDst.right,
|
|
(LPBYTE)&iFree);
|
|
pAAHdr->pOutBeg = pDstSI->pPlane +
|
|
(aabbp.rclDst.bottom * cxSize) +
|
|
ComputeByteOffset((UINT)DstSurfFmt,
|
|
aabbp.rclDst.left,
|
|
(LPBYTE)&iFree);
|
|
|
|
}
|
|
#endif
|
|
|
|
//
|
|
// Check it out if we need to fixup the input source bitmap
|
|
//
|
|
|
|
if (aabbp.AAHFlags & AAHF_TILE_SRC) {
|
|
|
|
//
|
|
// Increase the source cy and adjust pIn now
|
|
//
|
|
|
|
pAAHdr->SrcSurfInfo.Flags |= AASIF_TILE_SRC;
|
|
|
|
DBGP_IF(DBGP_AAHEADER,
|
|
DBGP("Advance pIn by iSrcBeg=%ld x %ld=%ld"
|
|
ARGDW(pAAInfoCY->iSrcBeg)
|
|
ARGDW(pAAHdr->SrcSurfInfo.cyNext)
|
|
ARGDW(pAAInfoCY->iSrcBeg *
|
|
pAAHdr->SrcSurfInfo.cyNext)));
|
|
|
|
pAAHdr->SrcSurfInfo.pb += pAAInfoCY->iSrcBeg *
|
|
pAAHdr->SrcSurfInfo.cyNext;
|
|
pAAHdr->SrcSurfInfo.cy -= pAAInfoCY->iSrcBeg;
|
|
}
|
|
|
|
pAAHdr->pbgrfAB = (PBGRF)pAAHdr->SrcSurfInfo.pb;
|
|
pAAHdr->cybgrfAB = pAAHdr->SrcSurfInfo.cy;
|
|
|
|
DBGP_IF(DBGP_AAHEADER,
|
|
DBGP("** pOut: (%p-%p), Beg=(%4ld, %4ld)=%p-%p (%p-%p) [%5ld], XOff=%4ld:%ld, cbCYExtra=%5ld"
|
|
ARGPTR(pDstSI->pPlane)
|
|
ARGPTR(pDstSI->pPlane + (cxSize * pDstSI->Height))
|
|
ARGDW(aabbp.rclDst.left) ARGDW(aabbp.rclDst.top)
|
|
ARGPTR(pAAHdr->DstSurfInfo.pb) ARGPTR(pAAHdr->pOutLast)
|
|
ARGPTR(pAAHdr->pOutBeg) ARGPTR(pAAHdr->pOutEnd)
|
|
ARGDW(pAAHdr->DstSurfInfo.cyNext)
|
|
ARGDW(ComputeByteOffset((UINT)DstSurfFmt,
|
|
aabbp.rclDst.left,
|
|
&(pAAHdr->DstSurfInfo.BitOffset)))
|
|
ARGDW(pAAHdr->DstSurfInfo.BitOffset)
|
|
ARGDW(cbCYExtra)));
|
|
|
|
DBGP_IF(DBGP_AAHEADER,
|
|
DBGP("--- BrushOrg=(%5ld, %5ld)->(%5ld, %5ld) ---"
|
|
ARGDW(pBBP->ptlBrushOrg.x) ARGDW(pBBP->ptlBrushOrg.y)
|
|
ARGDW(pAAHdr->ptlBrushOrg.x) ARGDW(pAAHdr->ptlBrushOrg.y)));
|
|
|
|
DBGP_IF(DBGP_AAHEADER,
|
|
DBGP("pAAHdr=%p - %p, (%ld bytes)"
|
|
ARGPTR(pAAHdr) ARGPTR((LPBYTE)pAAHdr + pAAHdr->cbAlloc)
|
|
ARGDW(pAAHdr->cbAlloc)));
|
|
|
|
DBGP_IF(DBGP_AAHEADER,
|
|
DBGP("pAAInfoCX=%p-%p (%ld), pAAInfoCY=%p-%p (%ld)"
|
|
ARGPTR(pAAInfoCX)
|
|
ARGPTR((LPBYTE)pAAInfoCX + pAAInfoCX->cbAlloc)
|
|
ARGDW(pAAInfoCX->cbAlloc)
|
|
ARGPTR(pAAInfoCY)
|
|
ARGPTR((LPBYTE)pAAInfoCY + pAAInfoCY->cbAlloc)
|
|
ARGDW(pAAInfoCY->cbAlloc)));
|
|
|
|
DBGP_IF(DBGP_FUNC,
|
|
DBGP("AACYFunc=%hs, AACXFunc=%hs"
|
|
ARGPTR(GetAACYFuncName(*pAACYFunc))
|
|
ARGPTR(GetAACXFuncName(aabbp.AACXFunc))));
|
|
|
|
return(1);
|
|
}
|
|
|
|
HTFreeMem(pAAInfoCX);
|
|
|
|
return(HTERR_INSUFFICIENT_MEMORY);
|
|
}
|