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

716 lines
22 KiB

/*
*
* Copyright (C) 1993, 1994 by
* DIGITAL EQUIPMENT CORPORATION, Maynard, MA.
*
* This software is furnished under a license and may be used and copied
* only in accordance with the terms of such license and with the inclusion
* of the above copyright notice. This software or any other copies there-
* of may not be provided or otherwise made available to any other person.
* No title to and ownership of the software is hereby transferred.
*
* The information in this software is subject to change without notice
* and should not be construed as a commitment by DIGITAL EQUIPMENT COR-
* PORATION.
*
* DIGITAL assumes no responsibility for the use or reliability of its
* software on equipment which is not supplied by DIGITAL.
*
*******************************************************************************
*
* Module: support.c
*
* Abstract: TGA support routines.
*
* HISTORY
*
* 01-Nov-1993 Bob Seitsinger
* Original version.
*
* 10-Nov-1993 Bob Seitsinger
* Change DISPDBG() to DISPBLTDBG().
*
* 23-Nov-1993 Bob Seitsinger
* Modify to accept 1bpp and 4bpp source bitmap formats.
*
* 26-Dec-1993 Barry Tannenbaum
* Fixed formatting
*
* 07-Jan-1994 Bob Seitsinger
* Moved rect.c routine into here.
*
* 12-Feb-1994 Bob Seitsinger
* Insert ulXlateBmfToBpp and ulXlateBppToBmf, from blt.c.
*
* 14-Feb-1994 Bob Seitsinger
* Punt 1bpp bitmaps until we handle them with 'stipple' mode.
* Freecell still has a bug.
*
* 23-Feb-1994 Bob Seitsinger
* Add TGADoDMA() to support DMA.
*
* 15-Apr-1994 Bob Seitsinger
* Add code in TGADoDMA to be sensitive to the global variable
* DMAEnabled. Also, ignore 'area' consideration when determining
* if DMA should be used.
*
* 13-May-1994 Barry Tannenbaum
* bSupportedBpp modified to allow us to support 1BPP bitmaps
*
* 20-may-1994 Bob Seitsinger
* Delete ulXlateBmfToBpp and ulXlateBppToBmf. Not used. Replaced
* by SURFOBJ_* macros.
*
* 24-May-1994 Bob Seitsinger
* Fix bug with straggling ulXlateBmfToBpp, replace it with
* SURFOBJ_format().
*
* 25-Aug-1994 Bob Seitsinger
* Modify bSupportedBpp to be handle 8bpp AND 32bpp frame buffers.
* Also, insert vXlateBitmapFormat from the old blt.c, which now
* contains code to handle 4bpp->32bpp and 8bpp->32bpp conversions.
*
* 1-Sep-1994 Bob Seitsinger
* Modify vXlateBitmapFormat to make use of the ppdev->pjColorXlateBuffer
* pointer.
*
* 12-Sep-1994 Bob Seitsinger
* Add bBypassFirstNibble parameter to vXlateBitmapFormat function.
*
* 11-Oct-1994 Bob Seitsinger
* TGADoDMA needs to make sure source and destination have same
* pixel bit depth.
*
* 03-Nov-1994 Tim Dziechowski
* Detect _all_ unsupported bpp formats, both source and target.
* Fix bug which attributed all bpp punts to copybits.
*/
#include "driver.h"
#include "tgastats.h"
#if DMA_ENABLED
BOOL DMAEnabled = TRUE;
#endif
/******************************************************************************
* bSupportedBpp - Verify source and/or destination pixel depths.
*****************************************************************************/
BOOL bSupportedBpp (SURFOBJ *psoSrc, SURFOBJ *psoTrg, PPDEV ppdev)
{
DISPDBG ((1, "TGA.DLL!bSupportedBpp - Entry, ulBitCount [%d]\n",
ppdev->ulBitCount));
// !!! For now punt on all host-to-screen transfers because both
// bHSExpress8to8 and vBitbltHS4to8 (at least) have fundamental
// problems with reading past the end of bitmaps, often causing
// access violations.
// if ((NULL != psoSrc) && (STYPE_BITMAP == psoSrc->iType))
// {
// return FALSE;
// }
switch (ppdev->ulBitCount)
{
case 8:
// First check the source
if (NULL != psoSrc)
{
switch (psoSrc->iType)
{
case STYPE_BITMAP:
switch (psoSrc->iBitmapFormat)
{
case BMF_1BPP:
case BMF_4BPP:
case BMF_8BPP:
break;
default:
#ifdef TGA_STATS
BUMP_TGA_STAT(pReason->source_format);
if ((0 == psoSrc->iBitmapFormat) ||
(psoSrc->iBitmapFormat > MAX_BMF))
{
BUMP_TGA_STAT(pReason->source_bpp[0]);
}
else
{
BUMP_TGA_STAT(pReason->source_bpp[psoSrc->iBitmapFormat]);
}
#endif
DISPDBG ((0, "TGA.DLL!bSupportedBpp - Exit (Src iBitMapFormat - %s)\n",
name_bmf(psoSrc->iBitmapFormat) ));
return FALSE;
}
break;
case STYPE_DEVICE:
switch (((PPDEV)psoSrc->dhpdev)->ulBitCount)
{
case 8:
break;
default:
BUMP_TGA_STAT(pReason->source_bitcount);
DISPDBG ((0, "TGA.DLL!bSupportedBpp - Exit (Src ulBitCount - %d)\n",
((PPDEV)psoSrc->dhpdev)->ulBitCount));
return FALSE;
}
break;
}
}
// Now check the target
switch (psoTrg->iType)
{
case STYPE_BITMAP:
switch (psoTrg->iBitmapFormat)
{
case BMF_8BPP:
break;
default:
#ifdef TGA_STATS
BUMP_TGA_STAT(pReason->target_format);
if ((0 == psoTrg->iBitmapFormat) ||
(psoTrg->iBitmapFormat > MAX_BMF))
{
BUMP_TGA_STAT(pReason->target_bpp[0]);
}
else
{
BUMP_TGA_STAT(pReason->target_bpp[psoTrg->iBitmapFormat]);
}
#endif
DISPDBG ((0, "TGA.DLL!bSupportedBpp - Exit (Trg iBitMapFormat - %s)\n",
name_bmf(psoTrg->iBitmapFormat) ));
return FALSE;
}
break;
case STYPE_DEVICE:
switch (((PPDEV)psoTrg->dhpdev)->ulBitCount)
{
case 8:
break;
default:
BUMP_TGA_STAT(pReason->target_bitcount);
DISPDBG ((0, "TGA.DLL!bSupportedBpp - Exit (Trg ulBitCount - %d)\n",
((PPDEV)psoTrg->dhpdev)->ulBitCount));
return FALSE;
}
break;
}
break;
case 32:
// First check the source
if (NULL != psoSrc)
{
switch (psoSrc->iType)
{
case STYPE_BITMAP:
switch (psoSrc->iBitmapFormat)
{
case BMF_1BPP:
case BMF_4BPP:
case BMF_8BPP:
case BMF_32BPP:
break;
default:
#ifdef TGA_STATS
BUMP_TGA_STAT(pReason->source_format);
if ((0 == psoSrc->iBitmapFormat) ||
(psoSrc->iBitmapFormat > MAX_BMF))
{
BUMP_TGA_STAT(pReason->source_bpp[0]);
}
else
{
BUMP_TGA_STAT(pReason->source_bpp[psoSrc->iBitmapFormat]);
}
#endif
DISPDBG ((0, "TGA.DLL!bSupportedBpp - Exit (Src iBitMapFormat - %s)\n",
name_bmf(psoSrc->iBitmapFormat) ));
return FALSE;
}
break;
case STYPE_DEVICE:
switch (((PPDEV)psoSrc->dhpdev)->ulBitCount)
{
case 32:
break;
default:
BUMP_TGA_STAT(pReason->source_bitcount);
DISPDBG ((0, "TGA.DLL!bSupportedBpp - Exit (Src ulBitCount - %d)\n",
((PPDEV)psoSrc->dhpdev)->ulBitCount));
return FALSE;
}
break;
}
}
// Now check the target
switch (psoTrg->iType)
{
case STYPE_BITMAP:
switch (psoTrg->iBitmapFormat)
{
case BMF_32BPP:
break;
default:
#ifdef TGA_STATS
BUMP_TGA_STAT(pReason->target_format);
if ((0 == psoTrg->iBitmapFormat) ||
(psoTrg->iBitmapFormat > MAX_BMF))
{
BUMP_TGA_STAT(pReason->target_bpp[0]);
}
else
{
BUMP_TGA_STAT(pReason->target_bpp[psoTrg->iBitmapFormat]);
}
#endif
DISPDBG ((0, "TGA.DLL!bSupportedBpp - Exit (Trg iBitMapFormat - %s)\n",
name_bmf(psoTrg->iBitmapFormat) ));
return FALSE;
}
break;
case STYPE_DEVICE:
switch (((PPDEV)psoTrg->dhpdev)->ulBitCount)
{
case 32:
break;
default:
BUMP_TGA_STAT(pReason->target_bitcount);
DISPDBG ((0, "TGA.DLL!bSupportedBpp - Exit (Trg ulBitCount - %d)\n",
((PPDEV)psoTrg->dhpdev)->ulBitCount));
return FALSE;
}
break;
}
break;
default:
DISPDBG ((0, "TGA.DLL!bSupportedBpp - Exit (ulBitCount NOT handled - %d)\n",
ppdev->ulBitCount));
return FALSE;
}
DISPDBG ((1, "TGA.DLL!bSupportedBpp - Exit\n"));
return TRUE;
}
/******************************************************************************
* bIntersectRect
*
* Intersect Rect1 with Rect2, result in Dst. Return TRUE if Rect1 and Rect2
* intersect each other. Otherwise return FALSE.
*****************************************************************************/
BOOL bIntersectRects (OUT RECTL *prclDst, IN RECTL *prclRect1, IN RECTL *prclRect2)
{
DISPBLTDBG ((2, "TGA.DLL!bIntersectRects - Entry\n"));
//
// Quickly reject rectangles that don't intersect.
//
if ((prclRect1->left >= prclRect2->right)
|| (prclRect1->right <= prclRect2->left)
|| (prclRect1->top >= prclRect2->bottom)
|| (prclRect1->bottom <= prclRect2->top))
{
DISPBLTDBG ((3, "TGA.DLL!bIntersectRects - prclRect1: left [%d], top [%d], right [%d], bottom [%d]\n",
prclRect1->left, prclRect1->top, prclRect1->right, prclRect1->bottom));
DISPBLTDBG ((3, "TGA.DLL!bIntersectRects - prclRect2: left [%d], top [%d], right [%d], bottom [%d]\n",
prclRect2->left, prclRect2->top, prclRect2->right, prclRect2->bottom));
DISPBLTDBG ((2, "TGA.DLL!bIntersectRects - Exit (Rectangles don't intersect!)\n"));
return FALSE;
}
//
// Find the intersecting rectangle of Rect1 and Rect2.
//
prclDst->left = (prclRect1->left < prclRect2->left)
? prclRect2->left : prclRect1->left;
prclDst->right = (prclRect1->right > prclRect2->right)
? prclRect2->right : prclRect1->right;
prclDst->top = (prclRect1->top < prclRect2->top)
? prclRect2->top : prclRect1->top;
prclDst->bottom = (prclRect1->bottom > prclRect2->bottom)
? prclRect2->bottom : prclRect1->bottom;
DISPBLTDBG ((2, "TGA.DLL!bIntersectRects - Exit\n"));
return(TRUE);
}
/******************************************************************************
* TGADoDMA
*
* This routine determines if the current blit copy request should use DMA.
*****************************************************************************/
BOOL TGADoDMA (ULONG width,
ULONG height,
ULONG mode,
SURFOBJ *psoSrc,
SURFOBJ *psoTrg,
PULONG pulXlate)
{
#if DMA_ENABLED
BOOL dmaWrite;
DISPBLTDBG((4, "TGA.DLL!TGADoDMA - Entry\n"));
if (!DMAEnabled)
{
DISPBLTDBG ((0, "TGA.DLL!TGADoDMA - Exit (DMAEnabled == FALSE)\n"));
return FALSE;
}
// Source and Target must have same pixel bit depth.
if (SURFOBJ_format(psoSrc) != SURFOBJ_format(psoTrg))
{
DISPBLTDBG ((0, "TGA.DLL!TGADoDMA - Exit (SrcBMF != TrgBMF)\n"));
return FALSE;
}
// Make sure the target pixel depth is not < 8 bpp.
if (SURFOBJ_format(psoTrg) < BMF_8BPP)
{
DISPBLTDBG((4, "TGA.DLL!TGADoDMA - NOT using DMA - bits-per-pixel [%d] < 8\n", bpp));
return FALSE;
}
// It pays to do dma if area to be copied is wide enough and the total
// area is large enough. AND the bits-per-pixel are not sub-byte, i.e.
// not < 8.
//
// We don't need to be concerned about destination alignment in making
// this decision.
// Get location in table.
dmaWrite = (mode == TGA_MODE_DMA_WRITE_COPY);
// Is the target rectangle wide enough?
if (width < dmaInfo[dmaWrite].widthMinimum)
{
DISPBLTDBG((4, "TGA.DLL!TGADoDMA - NOT using DMA - width [%d] < minimum [%d]\n",
width, dmaInfo[dmaWrite].widthMinimum));
return FALSE;
}
// Is the target area large enough?
// if ((width * height) < dmaInfo[dmaWrite].areaMinimum)
// {
// DISPBLTDBG((4, "TGA.DLL!TGADoDMA - NOT using DMA - width [%d] * height [%d] < area minimum [%d]\n",
// width, height, dmaInfo[dmaWrite].areaMinimum));
// return FALSE;
// }
// Make sure we're not translating colors.
if (pulXlate != NULL)
{
DISPBLTDBG((4, "TGA.DLL!TGADoDMA - NOT using DMA - color translation required\n"));
return FALSE;
}
DISPBLTDBG((4, "TGA.DLL!TGADoDMA - Exit\n"));
return TRUE;
#else /* !DMA_ENABLED */
DISPBLTDBG((4, "TGA.DLL!TGADoDMA - Entry\n"));
DISPBLTDBG((4, "TGA.DLL!TGADoDMA - DMA DISABLED\n"));
DISPBLTDBG((4, "TGA.DLL!TGADoDMA - Exit\n"));
return FALSE;
#endif
}
/*******************************************************************************
* vXlateBitmapFormat
*
* This handles translating various bitmap formats to
* other bitmap formats.
*
* The width parameter is in 'pixels'. So, for an 8bpp bitmap,
* this translates into bytes, for a 4bpp bitmap, this translates
* into nibbles and for a 1bpp bitmap, this translates into bits.
******************************************************************************/
VOID vXlateBitmapFormat (ULONG targetbitmapformat,
ULONG sourcebitmapformat,
PULONG pulXlate,
ULONG width,
VOID *buffin,
PBYTE *buffout,
BOOL bBypassFirstNibble)
{
ULONG i, j;
PBYTE in_ptr, ucout_ptr;
ULONG *ulout_ptr;
ULONG width_ = width;
// Assign source buffer to a local variable to allow
// us to do pointer arithmetic, which is more efficient
// than array indexing.
in_ptr = buffin;
// Translate based on target, then source format.
// Put cases in ascending order of frequency.
switch (targetbitmapformat)
{
case BMF_8BPP:
{
// Assign target buffer to a local variable to allow
// us to do pointer arithmetic, which is more efficient
// than array indexing.
ucout_ptr = *buffout;
switch (sourcebitmapformat)
{
case BMF_8BPP:
{
if (NULL == pulXlate)
{
*buffout = (PBYTE) buffin;
return;
}
else
{
// This handles translating an 8bpp color to another 8bpp color.
for (j = 0; j < width; j++, in_ptr++)
{
*ucout_ptr++ = LOBYTE(pulXlate[*in_ptr]);
}
return;
}
Assert((FALSE), "TGA.DLL!vXlateBitmapFormat - BMF_8BPP case fell through\n");
}
case BMF_4BPP:
{
if (NULL == pulXlate)
{
// This handles translating a 4bpp bitmap to an 8bpp bitmap.
//
// For each 4bpp element of the input, expand into a byte.
// Note that this may translate up to 1 pixel extra!
// Bypass the first pixel in the byte (high-order 4 bits),
// if necessary.
if (bBypassFirstNibble)
{
*ucout_ptr++ = (*in_ptr++) & 0x0f;
width_--;
}
for (i = 0; i < width_; i += 2, in_ptr++)
{
*ucout_ptr++ = (*in_ptr) >> 0x04;
*ucout_ptr++ = (*in_ptr) & 0x0f;
}
return;
}
else
{
// This handles translating a 4bpp bitmap to an 8bpp bitmap
// AND converting the resultant color.
//
// For each 4BBP element of the input, expand into a byte.
// Note that this may translate up to 1 pixel extra!
// Bypass the first pixel in the byte (high-order 4 bits),
// if necessary.
if (bBypassFirstNibble)
{
*ucout_ptr++ = LOBYTE(pulXlate[((*in_ptr++) & 0x0f)]);
width_--;
}
for (i = 0; i < width_; i += 2, in_ptr++)
{
*ucout_ptr++ = LOBYTE(pulXlate[((*in_ptr) >> 0x04)]);
*ucout_ptr++ = LOBYTE(pulXlate[((*in_ptr) & 0x0f)]);
}
return;
}
Assert((FALSE), "TGA.DLL!vXlateBitmapFormat - BMF_4BPP case fell through\n");
}
default:
{
DISPBLTDBG ((0, "TGA.DLL!vXlateBitmapFormat - Unhandled src BMF [%d][%s], target BMF [%d][%s]\n",
sourcebitmapformat, name_bmf(sourcebitmapformat),
targetbitmapformat, name_bmf(targetbitmapformat)));
}
}
}
case BMF_32BPP:
{
// Assign target buffer to a local variable to allow
// us to do pointer arithmetic, which is more efficient
// than array indexing.
ulout_ptr = (ULONG *) *buffout;
switch (sourcebitmapformat)
{
case BMF_32BPP:
{
*buffout = (PBYTE) buffin;
return;
}
case BMF_8BPP:
{
if (NULL == pulXlate)
{
// This handles translating an 8bpp color to a 32bpp color.
for (j = 0; j < width; j++, in_ptr++)
{
*ulout_ptr++ = (ULONG) (*in_ptr);
}
return;
}
else
{
// This handles translating an 8bpp color to a 32bpp color.
for (j = 0; j < width; j++, in_ptr++)
{
*ulout_ptr++ = pulXlate[*in_ptr];
}
return;
}
Assert((FALSE), "TGA.DLL!vXlateBitmapFormat - BMF_8BPP case fell through\n");
}
case BMF_4BPP:
{
if (NULL == pulXlate)
{
// This handles translating a 4bpp bitmap to a 32bpp bitmap.
//
// For each 4bpp element of the input, expand into a byte.
// Note that this may translate up to 1 pixel extra!
// Bypass the first pixel in the byte (high-order 4 bits),
// if necessary.
if (bBypassFirstNibble)
{
*ulout_ptr++ = (ULONG) ((*in_ptr++) & 0x0f);
width_--;
}
for (i = 0; i < width_; i += 2, in_ptr++)
{
*ulout_ptr++ = (ULONG) ((*in_ptr) >> 0x04);
*ulout_ptr++ = (ULONG) ((*in_ptr) & 0x0f);
}
return;
}
else
{
// This handles translating a 4bpp bitmap to a 32bpp bitmap
// AND converting the resultant color.
//
// For each 4BBP element of the input, expand into a byte.
// Note that this may translate up to 1 pixel extra!
// Bypass the first pixel in the byte (high-order 4 bits),
// if necessary.
if (bBypassFirstNibble)
{
*ulout_ptr++ = pulXlate[((*in_ptr++) & 0x0f)];
width_--;
}
for (i = 0; i < width_; i += 2, in_ptr++)
{
*ulout_ptr++ = pulXlate[((*in_ptr) >> 0x04)];
*ulout_ptr++ = pulXlate[((*in_ptr) & 0x0f)];
}
return;
}
Assert((FALSE), "TGA.DLL!vXlateBitmapFormat - BMF_4BPP case fell through\n");
}
default:
{
DISPBLTDBG ((0, "TGA.DLL!vXlateBitmapFormat - Unhandled src BMF [%d][%s], target BMF [%d][%s]\n",
sourcebitmapformat, name_bmf(sourcebitmapformat),
targetbitmapformat, name_bmf(targetbitmapformat)));
}
}
}
default:
{
DISPBLTDBG ((0, "TGA.DLL!vXlateBitmapFormat - Unhandled target bitmap format - [%d][%s]\n",
targetbitmapformat, name_bmf(targetbitmapformat)));
}
}
}