|
|
/******************************Module*Header*******************************\
* Module Name: xlateobj.hxx * * This file contains the class prototypes for palettes and xlates * * Created: 08-Nov-1990 19:30:06 * Author: Patrick Haluptzok patrickh * * Copyright (c) 1990-1999 Microsoft Corporation * * TERMINOLOGY: * * Logical hpal: Something an application creates. These exist in the * hdc. * * Physical hpal: An hpal that describes a surface. These are unique per * hsurf. They can only be changed by GDI, not directly * by an application. * * Every hdc has 3 fields for compatibiliy with Win3.0 Animate * palette functionality. * * The first one is in the DCLEVEL: * * HPALETTE hpal; // Indicates the current hpal for the DC.
* * These fields are not in the DCLEVEL: * * HDC hdcHpalPrev; // These two hdc fields enable tracking where
* HDC hdcHpalNext; // a hpal has been selected in.
* * Every hpal has 2 fields for compatibility with Win3.0 Animate. * * HDC hdcHead; // The head of the list for the dc's that
* // this hpal is selected into
* ULONG cRef; // count of dc's and levels this baby is
* // selected into
* * When a hpal is selected into a hdc, the hdc is added into a * linked list of hdc associated with the hpal. The reference * count for the hpal is incremented. The previous hpal has * it's reference count decremented, and the hdc is taken out * of it's linked list. This is so we can run down the list * of DC the palette is selected into to do the AnimatePalette. * * The hpal is saved with SaveDC. SaveDC increments the reference count * of the corresponding hpal and copies it to the new level. * * On RestoreDC decrement the old hpal's reference count. If the hpal's * on the levels are different, the new hpal must be added back in the * linked list, ***NOTE: it doesn't need to increment the reference count * for the new level's hpal, the reference count already has * this level added in it. * * A RealizePalette creates a xlateobj for mapping entries from the hdc's * hpal to the hsurf's hpal if the surface is managed by the window manager. * If the surface is not window managed the mapping is so trivial that a * xlateobj is not created. * * GLOBAL Notions: * * STOCKOBJ_PAL * PPALETTE ppalDefault; * PPALETTE ppalDefaultSurface8bpp; * * STOCKOBJ_PAL is what every DC has when it is called by GetDC. It is * the special case palette that is always locked, non-modifiable and * contains the 20 default colors. The constructors and destructors and * methods all should do the right thing for the default palette, i.e. * never really lock it or modify it, but allow everyone to look at it * and copy it. * * Tue 04-Dec-1990 -by- Patrick Haluptzok [patrickh] * update \**************************************************************************/
#ifndef _XLATEOBJ_
#define _XLATEOBJ_
#ifndef GDIFLAGS_ONLY // used for gdikdx
typedef struct _PIXEL32 { BYTE b; BYTE g; BYTE r; BYTE a; }PIXEL32,*PPIXEL32;
typedef union _ALPHAPIX { PIXEL32 pix; RGBQUAD rgb; ULONG ul; } ALPHAPIX,*PALPHAPIX;
typedef union _PAL_ULONG { PALETTEENTRY pal; ULONG ul; } PAL_ULONG;
typedef union _BGR_ULONG { RGBQUAD rgb; ULONG ul; } BGR_ULONG;
typedef union _HDEVPPAL { HDEV hdev; PPALETTE ppal; } HDEVPPAL;
typedef struct _PAL_LOGPALETTE { SHORT palVersion; SHORT palNumEntries; PALETTEENTRY palPalEntry[20]; } PAL_LOGPALETTE;
// The translate structure is used on palette managed devices to convert
// logical palette indices to physical palette indices.
typedef struct _TRANSLATE { ULONG iUniq; // Surface time this translate was made for. 0 if rerealize necesary.
BYTE ajVector[1]; // NOTE: THIS IS A VARIABLE-LENGTH FIELD AND MUST BE LAST
} TRANSLATE;
typedef TRANSLATE *PTRANSLATE;
typedef struct _TRANSLATE20 { ULONG iUniq; BYTE ajVector[20]; } TRANSLATE20;
extern TRANSLATE20 defaultTranslate;
extern PAL_LOGPALETTE logDefaultPal; extern BYTE HalftoneColorCube[];
//
// forward reference
//
// NOTE: the cache size must be a power of 2, quicker modula calculation.
#define XLATE_CACHE_SIZE ((ULONG) 8)
#define XLATE_MODULA (XLATE_CACHE_SIZE - (ULONG) 1)
#endif // GDIFLAGS_ONLY used for gdikdx
#define DIB_PAL_NONE 3
// PALOBJ flags - Fist bunch are defined in winddi.h
//#define PAL_INDEXED 0x00000001
//#define PAL_BITFIELDS 0x00000002
//#define PAL_RGB 0x00000004
//#define PAL_BGR 0x00000008
//#define PAL_CMYK 0x00000010
#define PAL_DC 0x00000100 // See below for comments
#define PAL_FIXED 0x00000200
#define PAL_FREE 0x00000400
#define PAL_MANAGED 0x00000800
#define PAL_NOSTATIC 0x00001000
#define PAL_MONOCHROME 0x00002000
#define PAL_BRUSHHACK 0x00004000
#define PAL_DIBSECTION 0x00008000
#define PAL_NOSTATIC256 0x00010000
#define PAL_HT 0x00100000
#define PAL_RGB16_555 0x00200000
#define PAL_RGB16_565 0x00400000
#define PAL_GAMMACORRECT 0x00800000 // This bit is only for palette on surface
//
// PAL_DIBSECTION is set when the palette is created for a DIBSECTION being
// created with DIB_PAL_COLORS. When this happens we should attempt to map
// the colors directly as identity xlate if possible, rather than doing the
// first color match wins routine.
//
// PAL_DC specifies the palette was created by an application through
// CreatePalette. These palettes only live in DC's, never in
// surfaces. These may be selected into multiple DC's, with the
// restriction that only one of the DC's hsurf's hpal is of type
// PAL_MANAGED
// Physical palettes are unique to an hsurf. No two surfaces have
// the same palette, though their entries may be the same. (They can also
// share color tables if it's a palette for a DirectDRaw object.) There are
// 3 different PAL_SURF types.
// 1. PAL_FIXED is a fixed palette. If this flag is set then
// the palette for this surface cannot be changed.
// 2. PAL_FREE means the palette is completely free. If it's selected into
// a DC with an hpal, the DC's hpal will map right in 1-1. This is the
// type of palette a Bitmap would have.
// 3. PAL_MANAGED means this palette has some entries fixed and
// some are settable. The fixed entries must be the first 10 and
// last 10. This is what a palette managed device has.
// PAL_NOSTATIC is a flag that signifies that for this PAL_MANAGED surface
// only two colors black, white, (first and last) are reserved.
// PAL_MONOCHROME is the flag stuck on monochrome bitmaps that should
// have their 0-> mapped to the foreground color of the dest DC and
// the 1-> mapped to the background color. The flag is put on palettes
// of bitmaps created via the call CreateBitmap, CreateBitmapIndirect.
// CreateDIBitmap treats monochromes just like 4,8 etc. it looks at
// the associated color table with the bitmap and therefore doesn't
// mark the palette PAL_MONOCHROME. This flag is required for
// Win 3.0 compatibility.
// There are 2 classes of palettes:
//
// A. PAL_INDEXED - the palette is described by an array of RGB's.
// 1. PAL_MONOCHROME - is a subset of PAL_INDEXED
//
// B. Not PAL_INDEXED, cEntries == 0
// the palette has no table, it describes how to convert
// the bits directly into RGBs via masks.
// 1. PAL_RGB - Classical RGB.
// PAL_RGB specifies a palette as being true RGB. An application creates
// an RGB palette by calling CreatePalette with numentries equal to 0.
// The byte order from low to high is R, G, B, flag.
// PAL_BGR specifies RGB expect the ordering from low to high is
// B, G, R, flags
// If the palette has less than 20 colors simultaneously then it must be a
// fixed palette or a free palette, none of the entries may be settable
// and the driver may pass back any colors it wants for it's palette.
// Windows3.1 flags for palette matching
#define PC_USED 0x10
#define PC_FOREGROUND 0x20
#ifndef GDIFLAGS_ONLY // used for gdikdx
//
// in some cases build an xlate table from rgb333 to palette entries
//
typedef PBYTE PRGB555XLATE;
#endif // GDIFLAGS_ONLY used for gdikdx
// Specify on calls to search for nearest COLORREFs or PALENTRYs whether
// to do an exact match search before doing the nearest match, since an
// exact search is so much faster.
#define SE_DONT_SEARCH_EXACT_FIRST 0x00
#define SE_DO_SEARCH_EXACT_FIRST 0x01
//
// ulXlatePalUnique maintains "time" of the last change to a palette or xlateobj.
// This is needed to tell if a xlateobj or translate is valid.
//
#ifndef GDIFLAGS_ONLY // used for gdikdx
extern ULONG ulXlatePalUnique; extern PAL_ULONG aPalHalftone[];
//
// Function prototype for palette-specific routines to convert a
// PALETTEENTRY to the destination device's color format.
//
class PALETTE;
typedef ULONG (FASTCALL *PFN_GetFromPalentry)(PALETTE*, ULONG);
//
// Function prototype for optimized routines to convert between two
// bitfields (or RGB or BGR) format colors.
//
typedef ULONG (FASTCALL *PFN_pfnXlate)(XLATEOBJ*, ULONG);
/******************************Public*Class*******************************\
* class PALETTE * * Palette class * * History: * 07-Nov-1990 -by- Patrick Haluptzok patrickh * Wrote it. \**************************************************************************/
class PALETTE : public OBJECT { public: FLONG flPal; // flags in palette
ULONG cEntries; // count of entries currently in palette
ULONG ulTime; // Time that specifies when the palette
// was last modified. Use this to determine
// if xlateobj are still valid.
HDC hdcHead; // Head of the linked list of DC's this hpalette
// is selected into so we traverse all the DC's
// an hpal is selected into to do AnimatePalette
// ect. correctly
HDEVPPAL hSelected; // For a PAL_DC this is the hdev of the pdev
// this
// palette is selected into. We track this
// because a palette can only be selected into
// the DC's of 1 device at a
// time. The DEVLOCK of the pdev serializes
// access to the pxlates in the palDC.
// For a PAL_MANAGED palette this is
// the hpal of its default palette.
ULONG cRefhpal; // For a PAL_DC this is the
// count of times this hpal is selected into a DC.
// For a PAL_xxx this is the
// index in the cache table of where the last
// hxlate used for this surf palette was stuffed.
ULONG cRefRegular; // For a PAL_MANAGED this is the number of reserved
// entries.
// For the special case where we have created a DIB
// via DIB_PAL_COLORS, we store the actual length of
// the DIB's color table here so we don't have to
// make as big an xlate
// For a DIBSECTION bitmap this is the count of
// entries that are used. This is for
// Get/SetDIBColorTable to remember the ClrUsed.
HDEV hdevOwner; // Pointer to PDEV who create this palette by EngCreatePalette()
// this entry is used only for the palette on the surface.
// [note] later to 'union' with someelse value which
// is only used for logical palette.
PTRANSLATE ptransFore; // Foreground mapping.
PTRANSLATE ptransCurrent; // Current mapping which may == ptransFore.
PTRANSLATE ptransOld; // The old translate for UpdateColors.
// This needs to be kept around to support
// UpdateColors.
PFN_GetFromPalentry pfnGetNearestFromPalentry; PFN_GetFromPalentry pfnGetMatchFromPalentry; // Indirect functions to convert a PALETTEENTRY
// to the destination device's color format
ULONG ulRGBTime; PRGB555XLATE pRGBXlate; // prgbXlate is allocated for a palette when doing
// translations from 16,24,32 bit per pixel formats
// to the palette format. ulRGBTime is used to determine
// if the xlate is valid.
PAL_ULONG *apalColor; // Pointer to color table. Usually points to
// &apalColorTabe[0], except for a DirectDraw
// GetDC surface, for which it points directly to
// the screen surface's color table
PALETTE *ppalColor; // Palette that owns the color table
// NOTE: THIS IS A VARIABLE-LENGTH FIELD AND MUST BE LAST
PAL_ULONG apalColorTable[1]; // array of rgb values that each index corresponds
// plus array of intensities from least intense to most
// intense (plus index to corresponding rgb value)
};
typedef PALETTE *PPALETTE;
/******************************Public*Class********************************\
* XLATE * * This is the data structure for an xlate object. An xlate tranlates * indices from being relative one palette to being relative to another. * * History: * Mon 07-Mar-1994 -by- Patrick Haluptzok [patrickh] * Derive off of XLATEOBJ. * * 18-Nov-1990 -by- Patrick Haluptzok patrickh * Wrote it. \**************************************************************************/
class XLATE : public _XLATEOBJ { public: // ULONG iUniq; // Uniqueness
// FLONG flXlate; // Accelerator flags
// USHORT iSrcType; // Src palette type
// USHORT iDstType; // Dst palette type
// ULONG cEntries; // Count of entries in table
// ULONG *pulXlate; // Pointer to translation vector.
ULONG iBackSrc; // tracked for blting to monochrome
ULONG iForeDst; // tracked for blting from monochrome
ULONG iBackDst; // tracked for blting from monochrome
LONG lCacheIndex; // Is XLATE_CACHE_JOURNAL if for journal play back
// Is XLATE_CACHE_INVALID if it's not in cache
// Otherwise it's the cache index.
PPALETTE ppalSrc; // Points to Src palette.
PPALETTE ppalDst; // Points to Dst palette.
PPALETTE ppalDstDC; // Points to Dst DC palette.
HANDLE hcmXform; // ICM Color Transform for operation
LONG lIcmMode; // ICM mode for operation
FLONG flPrivate; // Private accelerator flags
// NOTE: THIS IS A VARIABLE-LENGTH FIELD AND MUST BE LAST
ULONG ai[1]; // The translation vector.
public:
BOOL bIsIdentity() { return(flXlate & XO_TRIVIAL); } ULONG ulTranslate(ULONG cIndex) { return(XLATEOBJ_iXlate(this, cIndex)); } VOID vSetIndex(ULONG ulIndex, ULONG ulValue) { ASSERTGDI(ulIndex < cEntries, "ERROR XLATE vSetIndex"); ai[ulIndex] = ulValue; } VOID FASTCALL vMapNewXlate(PTRANSLATE ptrans); VOID vCheckForTrivial(); VOID vCheckForICM(HANDLE hcmXform,ULONG lIcmMode); PFN_pfnXlate pfnXlateBetweenBitfields(); };
typedef XLATE *PXLATE;
//
// This class is for the global identity xlate we have sitting around.
//
class XLATE256 : public XLATE { public: ULONG aiExtra[255]; // We have a 256 array of ident xlate.
};
class XLATE2 : public XLATE { public: ULONG aiExtra[1]; // We have a 2 entry array.
};
extern XLATE256 xloIdent;
// The following constants are for reserved uniqueness values.
// 1 is reserved for the identity xlate.
// 2 is reserved for the palette time for a palette managed bitmap palette.
// If ever wrapping is an issue I would increment by 2, start at an even #
// and put the reserved times at odd offsets.
#define XLATE_IDENTITY_UNIQ 1
#define COMPAT_PAL_MAN_BM_UNIQ 2
#define XLATE_START_UNIQ 3
//
// The 2 common palettes used in Windows are:
// The palette for mononchrome bitmaps
// The default logical palette for DC's
//
extern PPALETTE ppalDefault; extern PPALETTE gppalRGB; extern PPALETTE ppalDefaultSurface8bpp; extern PPALETTE ppalMono; extern HPALETTE hpalMono;
/******************************Public*Structure****************************\
* P_BITFIELDS * * This supports the 16 and 32 bit-bitfield palette types. The bitfields * for each color are assumed to be contiguous and don't overlap. * * Let a 16 or 32 bit index be represented by: * * { X | Y | Z } where X is the high ignored bits, Y is the color bits * for a particular Color and Z is the ignored low bits. * * cColorRight = (Y > 8) ? (Z + Y - 8) : (Z); * * Let w=0 for red, w=8 for green, w=16 for blue * * cColorLeft = (Y > 8) ? (w) : (w + 8 - Y) * * We compute this for R,G,B and from these we can transform the colors * from RGB to indexes and back again no matter how wide or what order * the bitfields for each of the colors is. * * History: * 08-Nov-1991 -by- Patrick Haluptzok patrickh * Wrote it. \**************************************************************************/
typedef struct _P_BITFIELDS { FLONG flRed; // Masks for the corresponding bits
FLONG flGre; FLONG flBlu; ULONG cRedLeft; ULONG cGreLeft; ULONG cBluLeft; ULONG cRedRight; ULONG cGreRight; ULONG cBluRight; ULONG cRedMiddle; ULONG cGreMiddle; ULONG cBluMiddle; } P_BITFIELDS;
/******************************Public*Class*******************************\
* class XEPALOBJ * * Palette User Object * * History: * Thu 29-Aug-1991 -by- Patrick Haluptzok [patrickh] * changed it to be XEPALOBJ * * 07-Nov-1990 -by- Patrick Haluptzok patrickh * Wrote it. \**************************************************************************/
class XEPALOBJ /* xepal */ { protected: PPALETTE ppal;
public: XEPALOBJ() { ppal = (PPALETTE) NULL; } XEPALOBJ(PPALETTE ppalNew) { ppal = ppalNew; }
VOID vAltCheckLock(HPALETTE hpal) { ppal = (PPALETTE) HmgShareCheckLock((HOBJ)hpal, PAL_TYPE); }
VOID vAltLock(HPALETTE hpal) { ppal = (PPALETTE) HmgShareLock((HOBJ)hpal, PAL_TYPE); }
VOID vAltUnlock() { if (ppal != (PPALETTE) NULL) { DEC_SHARE_REF_CNT(ppal); ppal = (PPALETTE) NULL; } }
// These are the common functions
HPALETTE hpal() { return((HPALETTE) ppal->hGet()); } BOOL bValid() { return(ppal != (PPALETTE) NULL); } BOOL bIsPalDefault() { return(ppal == ppalDefault); } VOID vSetPID(W32PID pid) { HmgSetOwner((HOBJ)hpal(), pid, PAL_TYPE); }
VOID vRefPalette() { if (ppal != NULL) INC_SHARE_REF_CNT(ppal); } VOID vUnrefPalette(); BOOL bDeletePalette(BOOL bCleanup = FALSE, CLEANUPTYPE cutype = CLEANUP_NONE); // release associated memory
// Bitfield functions
FLONG flRed() { return(((P_BITFIELDS *) ppal->apalColor)->flRed); } VOID flRed(FLONG flNew) { ((P_BITFIELDS *) ppal->apalColor)->flRed = flNew; } FLONG flGre() { return(((P_BITFIELDS *) ppal->apalColor)->flGre); } VOID flGre(FLONG flNew) { ((P_BITFIELDS *) ppal->apalColor)->flGre = flNew; } FLONG flBlu() { return(((P_BITFIELDS *) ppal->apalColor)->flBlu); } VOID flBlu(FLONG flNew) { ((P_BITFIELDS *) ppal->apalColor)->flBlu = flNew; } ULONG& cRedLeft() { return(((P_BITFIELDS *) ppal->apalColor)->cRedLeft); } VOID cRedLeft(ULONG ul) { ((P_BITFIELDS *) ppal->apalColor)->cRedLeft = ul; } ULONG& cGreLeft() { return(((P_BITFIELDS *) ppal->apalColor)->cGreLeft); } VOID cGreLeft(ULONG ul) { ((P_BITFIELDS *) ppal->apalColor)->cGreLeft = ul; } ULONG& cBluLeft() { return(((P_BITFIELDS *) ppal->apalColor)->cBluLeft); } VOID cBluLeft(ULONG ul) { ((P_BITFIELDS *) ppal->apalColor)->cBluLeft = ul; } ULONG& cRedRight() { return(((P_BITFIELDS *) ppal->apalColor)->cRedRight); } VOID cRedRight(ULONG ul) { ((P_BITFIELDS *) ppal->apalColor)->cRedRight = ul; } ULONG& cGreRight() { return(((P_BITFIELDS *) ppal->apalColor)->cGreRight); } VOID cGreRight(ULONG ul) { ((P_BITFIELDS *) ppal->apalColor)->cGreRight = ul; } ULONG& cBluRight() { return(((P_BITFIELDS *) ppal->apalColor)->cBluRight); } VOID cBluRight(ULONG ul) { ((P_BITFIELDS *) ppal->apalColor)->cBluRight = ul; }
ULONG& cRedMiddle() { return(((P_BITFIELDS *) ppal->apalColor)->cRedMiddle); } VOID cRedMiddle(ULONG ul) { ((P_BITFIELDS *) ppal->apalColor)->cRedMiddle = ul; } ULONG& cGreMiddle() { return(((P_BITFIELDS *) ppal->apalColor)->cGreMiddle); } VOID cGreMiddle(ULONG ul) { ((P_BITFIELDS *) ppal->apalColor)->cGreMiddle = ul; } ULONG& cBluMiddle() { return(((P_BITFIELDS *) ppal->apalColor)->cBluMiddle); } VOID cBluMiddle(ULONG ul) { ((P_BITFIELDS *) ppal->apalColor)->cBluMiddle = ul; }
ULONG ulBitfieldToRGB(ULONG ulIndex);
ULONG ulIndexToRGB(ULONG ulIndex);
// General functions
PPALETTE ppalGet() { return(ppal); } PVOID pvPalette() { return((PVOID) ppal); } VOID ppalSet(PPALETTE ppalNew) { ppal = ppalNew; } FLONG flPal() { return(ppal->flPal); } VOID flPalSet(FLONG flag) { ppal->flPal = flag; } VOID flPal(FLONG flag) { ppal->flPal |= flag; } ULONG iPalMode() { return(ppal->flPal & (PAL_RGB | PAL_BGR | PAL_CMYK | PAL_INDEXED | PAL_BITFIELDS)); } BOOL bIsRGB() { return(ppal->flPal & PAL_RGB); } BOOL bIsBGR() { return(ppal->flPal & PAL_BGR); } BOOL bIs565() { return(ppal->flPal & PAL_RGB16_565); } BOOL bIs555() { return(ppal->flPal & PAL_RGB16_555); } BOOL bIsCMYK() { return(ppal->flPal & PAL_CMYK); } BOOL bIsIndexed() { return(ppal->cEntries); } BOOL bIsPalDC() { return(ppal->flPal & PAL_DC); } BOOL bIsBitfields() { return(ppal->flPal & PAL_BITFIELDS); } BOOL bIsPalDibsection() { return(ppal->flPal & PAL_DIBSECTION); } BOOL bIsHalftone() { return(ppal->flPal & PAL_HT);} ULONG cEntries() { return(ppal->cEntries); } VOID cEntries(ULONG ulTemp) { ppal->cEntries = ulTemp; } PPALETTE ppalColor() { return(ppal->ppalColor); } PAL_ULONG *apalColorGet() { return(ppal->apalColor); } VOID vComputeCallTables(); VOID apalColorSet(PPALETTE ppalGlobal) { if (ppal->ppalColor != ppal) { // Handle re-assignment case
DEC_SHARE_REF_CNT(ppal->ppalColor); } INC_SHARE_REF_CNT(ppalGlobal); ppal->apalColor = ppalGlobal->apalColor; ppal->ppalColor = ppalGlobal; } VOID apalResetColorTable() { if (ppal->ppalColor != ppal) { // Handle re-assignment case
DEC_SHARE_REF_CNT(ppal->ppalColor); } // Note that this does not transfer ownership of the color table
ppal->apalColor = &ppal->apalColorTable[0]; ppal->ppalColor = ppal; } ULONG ulTime() { if (ppal->ppalColor != ppal) { // Note if color table lives in different PALETTE, get time from there.
return(ppal->ppalColor->ulTime); } else { return(ppal->ulTime); } } VOID ulTime(ULONG ulNewTime) { ppal->ulTime = ulNewTime; if (ppal->ppalColor != ppal) { // Note if color table lives in different PALETTE, update that's ulTime, too.
ppal->ppalColor->ulTime = ulNewTime; } } VOID vUpdateTime() { ulTime(ulGetNewUniqueness(ulXlatePalUnique)); } VOID vSetHTPal() { ppal->flPal |= PAL_HT; } VOID vClearHTPal() { ppal->flPal &= ~PAL_HT; } BOOL bIsHTPal() { return(ppal->flPal & PAL_HT); } PALETTEENTRY palentryGet(ULONG ulIndex) { ASSERTGDI(ulIndex < ppal->cEntries, "ERROR palentryGet: ulIndex > cEntries"); return(ppal->apalColor[ulIndex].pal); } ULONG ulEntryGet(ULONG ulIndex) { ASSERTGDI(ulIndex < ppal->cEntries, "ERROR ulentryGet: ulIndex > cEntries"); return(ppal->apalColor[ulIndex].ul); } VOID palentrySet(ULONG ulIndex, PALETTEENTRY palentry) { ASSERTGDI(ulIndex < ppal->cEntries, "ERROR palentrySet: ulIndex > cEntries"); ppal->apalColor[ulIndex].pal = palentry; } VOID ulEntrySet(ULONG ulIndex, ULONG ulRGB) { ASSERTGDI(ulIndex < ppal->cEntries, "ERROR palentrySet: ulIndex > cEntries"); ppal->apalColor[ulIndex].ul = ulRGB; } ULONG ulSetEntries(ULONG iStart, ULONG cEntry, CONST PALETTEENTRY *ppalentry); ULONG ulAnimatePalette(ULONG iStart, ULONG cEntry, CONST PALETTEENTRY *ppalentry); ULONG ulGetEntries(ULONG iStart, ULONG cEntry, PPALETTEENTRY ppalentry, BOOL bZeroFlags);
ULONG ulGetNearestFromPalentryNoExactMatchFirst(CONST PALETTEENTRY palentry); ULONG ulGetMatchFromPalentry(CONST PALETTEENTRY palentry) { return(ppal->pfnGetMatchFromPalentry(ppal, *((ULONG*) &palentry))); } ULONG ulGetMatchFromPalentry(CONST ULONG palentry) { return(ppal->pfnGetMatchFromPalentry(ppal, palentry)); } ULONG ulGetNearestFromPalentry(CONST PALETTEENTRY palentry) { return(ppal->pfnGetNearestFromPalentry(ppal, *((ULONG*) &palentry))); } ULONG ulGetNearestFromPalentry(CONST ULONG palentry) { return(ppal->pfnGetNearestFromPalentry(ppal, palentry)); } ULONG ulGetNearestFromPalentry( CONST PALETTEENTRY palentry, ULONG seSearchExactFirst ) { ULONG ul;
if (seSearchExactFirst == SE_DONT_SEARCH_EXACT_FIRST) { ul = ulGetNearestFromPalentryNoExactMatchFirst(palentry); } else { ul = ulGetNearestFromPalentry(palentry); }
return(ul); }
VOID vInitMono(); VOID vInitVGA(); VOID vInit256Rainbow(); VOID vInit256Default();
// These are the DC palette functions - PALOBJDC
VOID hdcHead(HDC hdcHead) { ASSERTGDI(ppal->flPal & PAL_DC, "ERROR hdcHead() passed invalid palette type\n"); ppal->hdcHead = hdcHead; } HDC hdcHead() { ASSERTGDI(ppal->flPal & PAL_DC, "ERROR hdcHead() 1passed invalid palette type\n"); return(ppal->hdcHead); } VOID cRefhpal(ULONG ulTemp) { ASSERTGDI(ppal->flPal & PAL_DC, "ERROR cRefhpal not called on PAL_DC1\n"); ppal->cRefhpal = ulTemp; } ULONG cRefhpal() { ASSERTGDI(ppal->flPal & PAL_DC, "ERROR cRefhpal not called on PAL_DC\n"); return(ppal->cRefhpal); } VOID iXlateIndex(ULONG ulTemp) { ASSERTGDI(!(ppal->flPal & PAL_DC), "ERROR iXlateIndex called on PAL_DC1\n"); ASSERTGDI(ulTemp < XLATE_CACHE_SIZE, "ERROR saving too large cache index \n"); ppal->cRefhpal = ulTemp; } ULONG iXlateIndex() { ASSERTGDI(!(ppal->flPal & PAL_DC), "ERROR iXlateIndex called on PAL_DC\n"); ASSERTGDI(ppal->cRefhpal < XLATE_CACHE_SIZE, "ERROR retrieving out of bounds cache index \n"); return(ppal->cRefhpal); }
VOID ptransFore(PTRANSLATE ptrans) { ASSERTGDI(ppal->flPal & PAL_DC, "ERROR pxlFore() passed invalid palette type\n"); ppal->ptransFore = ptrans; } PTRANSLATE ptransFore() { ASSERTGDI(ppal->flPal & PAL_DC, "ERROR pxlFore() 1passed invalid palette type\n"); return(ppal->ptransFore); } VOID ptransCurrent(PTRANSLATE ptrans) { ASSERTGDI(ppal->flPal & PAL_DC, "ERROR ptransCurrent() passed invalid palette type\n"); ppal->ptransCurrent = ptrans; } PTRANSLATE ptransCurrent() { ASSERTGDI(ppal->flPal & PAL_DC, "ERROR ptransCurrent() 1passed invalid palette type\n"); return(ppal->ptransCurrent); } VOID ptransOld(PTRANSLATE ptrans) { ASSERTGDI(ppal->flPal & PAL_DC, "ERROR ptransOld() passed invalid palette type\n"); ppal->ptransOld = ptrans; } PTRANSLATE ptransOld() { ASSERTGDI(ppal->flPal & PAL_DC, "ERROR ptransOld() 1passed invalid palette type\n"); return(ppal->ptransOld); }
//
// For ResizePalette
//
BOOL bSwap(PPALETTE*,ULONG,ULONG);
//
// This returns the index in the surface palette an index in the dc
// palette maps to. It assumes you checked for a valid ptrans and a
// valid index range.
//
ULONG ulTranslateDCtoCurrent(ULONG ulIndex) { ASSERTGDI(ppal->flPal & PAL_DC, "ERROR GDI ulTranslateIndex"); ASSERTGDI(ulIndex < ppal->cEntries, "ERROR GDI ulTranslateIndex1"); ASSERTGDI(ppal->ptransCurrent != (PTRANSLATE) NULL, "ERROR GDI ulTranslateIndex2"); return((ULONG) ppal->ptransCurrent->ajVector[ulIndex]); }
//
// This returns the index in the surface palette an index in the dc
// palette maps to. It assumes you checked for a valid ptrans and a
// valid index range.
//
ULONG ulTranslateDCtoFore(ULONG ulIndex) { ASSERTGDI(ppal->flPal & PAL_DC, "ERROR GDI ulTranslateIndex1"); ASSERTGDI(ulIndex < ppal->cEntries, "ERROR GDI ulTranslateIndex11"); ASSERTGDI(ppal->ptransFore != (PTRANSLATE) NULL, "ERROR GDI ulTranslateIndex21"); return((ULONG) ppal->ptransFore->ajVector[ulIndex]); }
//
// For a palette managed DC this is the hdev the palette is selected into.
//
HDEV hdev() { ASSERTGDI(ppal->flPal & PAL_DC, "ERROR hdev() passed invalid palette type\n"); return(ppal->hSelected.hdev); } VOID hdev(HDEV hdev) { ASSERTGDI(ppal->flPal & PAL_DC, "ERROR hdev() 1passed invalid palette type\n"); ppal->hSelected.hdev = hdev; }
BOOL bSet_hdev(HDEV hdev); VOID vInc_cRef() { ASSERTGDI(ppal->flPal & PAL_DC, "vInc_cRef() passed invalid palette type\n"); InterlockedIncrement((PLONG) &(ppal->cRefhpal)); }
VOID vDec_cRef() { ASSERTGDI(ppal->flPal & PAL_DC, "vDec_cRef() passed invalid palette type\n"); ASSERTGDI(ppal->cRefhpal != 0, "cRefhpal == 0 in vDec Palette"); InterlockedDecrement((PLONG) &(ppal->cRefhpal)); }
// These are the surface palette functions - PALOBJS
BOOL bIsPalFixed() { return(ppal->flPal & PAL_FIXED); } BOOL bIsPalManaged() { return(ppal->flPal & PAL_MANAGED); } BOOL bIsPalFree() { return(ppal->flPal & PAL_FREE); } BOOL bIsMonochrome() { return((ppal != NULL) && (ppal->flPal & PAL_MONOCHROME)); } VOID vCopy_rgbquad(RGBQUAD *prgbquad, ULONG iStart, ULONG cEntries); VOID vCopy_cmykquad(ULONG *pcmykquad, ULONG iStart, ULONG cEntries); ULONG ulGetExactIndexFromPalentry(PAL_ULONG Color); PTRANSLATE ptransMapIn(XEPALOBJ palDC, BOOL bForeground, ULONG *pulUsedChanged, ULONG *pulUnUsedChanged); BOOL bJamItIn(XEPALOBJ palDC, BOOL bForeground, BOOL *pulUsedChanged, BOOL *pulUnUsedEntriesChanged); ULONG ulRealizeOnFree(XEPALOBJ palDC); VOID ulNumReserved(ULONG ulTemp) { ASSERTGDI(!(ppal->flPal & PAL_DC), "ERROR ulNumReserved called on PAL_DC1\n"); ASSERTGDI(ulTemp < ppal->cEntries, "ERROR saving too large free index \n"); ppal->cRefRegular = ulTemp; } ULONG cColorTableLength() { ASSERTGDI(!(ppal->flPal & PAL_DC), "ERROR cColorTableLength called on PAL_DC1\n"); return ppal->cRefRegular; } VOID cColorTableLength(ULONG ulLength) { ASSERTGDI(!(ppal->flPal & PAL_DC), "ERROR cColorTableLength called on PAL_DC1\n"); ppal->cRefRegular = ulLength; } ULONG ulNumReserved() { ASSERTGDI(!(ppal->flPal & PAL_DC), "ERROR ulNumReserved called on PAL_DC\n"); ASSERTGDI(ppal->cRefRegular <= (ppal->cEntries - 1), "ERROR retrieving out of bounds free index \n"); ASSERTGDI(ppal->cRefRegular >= 1, "ERROR ulNumReserved too small\n"); return(ppal->cRefRegular); } BOOL bIsNoStatic() { return(ppal->flPal & PAL_NOSTATIC); } BOOL bIsNoStatic256() { return(ppal->flPal & PAL_NOSTATIC256); }
VOID vSetNoStatic() { ppal->flPal = (ppal->flPal | PAL_NOSTATIC) & ~PAL_NOSTATIC256; } VOID vSetNoStatic256() { ppal->flPal = (ppal->flPal | PAL_NOSTATIC256) & ~PAL_NOSTATIC; }
VOID vMakeNoXlate(); PPALETTE ppalOriginal() { ASSERTGDI(ppal->flPal & PAL_MANAGED, "ERROR hpalOriginal() passed invalid palette type\n"); return(ppal->hSelected.ppal); } VOID ppalOriginal(PPALETTE ppalNew) { ASSERTGDI(ppal->flPal & PAL_MANAGED, "ERROR hpalOriginal() 1passed invalid palette type\n"); ppal->hSelected.ppal = ppalNew; } VOID vCopyEntriesFrom(XEPALOBJ palSrc) { RtlCopyMemory(apalColorGet(), palSrc.apalColorGet(), (UINT) (MIN(palSrc.cEntries(), cEntries())) * sizeof(PAL_ULONG)); } VOID vFill_rgbquads(RGBQUAD *prgb, ULONG iStart, ULONG cEntries); VOID vFill_triples(RGBTRIPLE *prgb, ULONG iStart, ULONG cEntries); VOID vAddToList(XDCOBJ& dco); VOID vRemoveFromList(XDCOBJ& dco); VOID vGetEntriesFrom(XEPALOBJ palDC, XEPALOBJ palSurf, PUSHORT pusIndices, ULONG cEntry); BOOL bEqualEntries(XEPALOBJ pal); BOOL bGenColorXlate555();
PRGB555XLATE pGetRGBXlate(); BYTE Xlate555(BYTE r,BYTE g, BYTE b) { return(ppal->pRGBXlate[ ((r & 0xf8) << 7) || ((g & 0xf8) << 2) || ((b & 0xf8) >> 3)]); }
//
// ICM: GammaCorrection stuff for 8bpp surface
//
BOOL bNeedGammaCorrection() { return(ppal->flPal & PAL_GAMMACORRECT); } BOOL bNeedGammaCorrection(BOOL b) { SETFLAG(b,ppal->flPal,PAL_GAMMACORRECT);return (b); }
VOID CorrectColors(PPALETTEENTRY ppalentry, ULONG cEntries);
HDEV hdevOwner() { return(ppal->hdevOwner); } HDEV hdevOwner(HDEV hdev_) { ppal->hdevOwner = hdev_;return(hdev_); } };
/*********************************Class************************************\
* class EPALOBJ : public XEPALOBJ * * Used for creating a user object from a pointer to the object. * * History: * Wed 28-Aug-1991 -by- Patrick Haluptzok [patrickh] * Wrote it. \**************************************************************************/
class EPALOBJ : public XEPALOBJ /* palo */ { public: EPALOBJ() {ppal = (PPALETTE) NULL; } EPALOBJ(HPALETTE hpal) {ppal = (PPALETTE) HmgShareCheckLock((HOBJ)hpal, PAL_TYPE);} ~EPALOBJ() { if (ppal != (PPALETTE) NULL) { DEC_SHARE_REF_CNT(ppal); } } };
/******************************Public*Class********************************\
* class PALMEMOBJ * * Palette Memory Object * * History: * 07-Nov-1990 -by- Patrick Haluptzok patrickh * Wrote it. \**************************************************************************/
class PALMEMOBJ : public XEPALOBJ /* epalmo */ { private: BOOL bKeep;
public: PALMEMOBJ() {bKeep = FALSE; ppal = (PPALETTE) NULL;}
BOOL bCreatePalette(ULONG iMode, ULONG cColors, ULONG *pulColors, FLONG flRed, FLONG flGreen, FLONG flBlue, ULONG iType);
BOOL bCreateHTPalette(LONG iFormatHT, GDIINFO *pGdiInfo);
~PALMEMOBJ(); VOID vKeepIt() { bKeep = TRUE; } };
// structure for entry in the xlate cache.
typedef struct _XLATETABLE { ULONG ulReference; // How many people are currently using it.
PXLATE pxlate; ULONG ulPalSrc; // palette src time when xlate created
ULONG ulPalDst; // palette dst time when xlate created
ULONG ulPalSrcDC; // palette src DC time when xlate created
ULONG ulPalDstDC; // palette dst DC time when xlate created
} XLATETABLE;
extern XLATETABLE xlateTable[XLATE_CACHE_SIZE]; extern ULONG ulTableIndex;
#endif // GDIFLAGS_ONLY used for gdikdx
// This signifies the xlate wasn't put in the cache. The destructor
// checks for this and deletes it if it's not in the cache.
#define XLATE_CACHE_JOURNAL -2
#define XLATE_CACHE_INVALID -1
// This describes the overall logic of surface to surface xlates.
// There are basically n types of xlates to worry about:
//
// 1. XO_TRIVIAL - no translation occurs, identity.
//
// 2. XO_TABLE - look up in a table for the correct table translation.
//
// a. XO_TO_MONO - look in to table for the correct tranlation,
// but when getting it out of the cache make sure iBackSrc is the
// same. iBackSrc goes to 1, everything else to 0.
// b. XLATE_FROM_MONO - look into table for the correct translation
// but when getting it out of the cache make sure iBackDst and
// iForeDst are both still valid. 1 goes to iBackDst, 0 to iForeDst.
// c. just plain jane indexed to indexed or rgb translation.
//
// 3. XO_RGB_SRC - Have to call XLATEOBJ_iXlate to get it translated.
//
// a. XO_TO_MONO - we have saved the iBackColor in ai[0]
// b. just plain jane RGB to indexed. Grab the RGB, find the closest
// match in Dst palette. Lot's of work.
//
// 4. XO_RGB_BOTH - Bit mashing time. Call XLATEOBJ_iXlate
//
// The code is written to quickly recognize the XO_TRIVIAL case, efficiently
// compute and cache the translate table for the type XO_TABLE case, and
// do the correct, expensive work required for cases 3 and 4.
// #define XO_TRIVIAL 0x00000001
// #define XO_TABLE 0x00000002
// #define XO_TO_MONO 0x00000004
// #define XO_FROM_CMYK 0x00000008
// #define XO_DEVICE_ICM 0x00000010
// #define XO_HOST_ICM 0x00000020
#define XLATE_FROM_MONO 0x00000100
#define XLATE_RGB_SRC 0x00000200
#define XLATE_RGB_BOTH 0x00000400
#define XLATE_PAL_MANAGED 0x00000800
#define XLATE_USE_CURRENT 0x00001000
#define XLATE_USE_SURFACE_PAL 0x00002000 // Only used with MultiMonitor system
#define XLATE_USE_FOREGROUND 0x00004000 // Only used with MultiMonitor system
#ifndef GDIFLAGS_ONLY // used for gdikdx
extern "C" ULONG XLATEOBJ_iXlate(XLATEOBJ *pxo, ULONG cIndex);
PXLATE CreateXlateObject( HANDLE hcmXform, LONG lIcmMode, XEPALOBJ palSrc, XEPALOBJ palDst, XEPALOBJ palSrcDC, XEPALOBJ palDstDC, ULONG iForeDst, ULONG iBackDst, ULONG iBackSrc, ULONG flCreate );
PXLATE pCreateXlate( ULONG ulNumEntries );
/*********************************Class************************************\
* EXLATEOBJ * * This is the user object for a palette translation table. * * History: * Wed 09-Mar-1994 -by- Patrick Haluptzok [patrickh] * Get rid of stack object, clean up. * * Sun 05-May-1991 -by- Patrick Haluptzok [patrickh] * add new DDI changes to code, deja vu. * * Mon 04-Feb-1991 -by- Patrick Haluptzok [patrickh] * add DDI changes to code. * * Mon 03-Dec-1990 -by- Patrick Haluptzok [patrickh] * wrote the first pass for NT. \**************************************************************************/
class EXLATEOBJ { protected: XLATE *pxlate;
public:
EXLATEOBJ() { pxlate = (PXLATE) NULL; } EXLATEOBJ(PXLATE pxlateNew) { pxlate = pxlateNew; } ~EXLATEOBJ() { vAltUnlock(); } BOOL bValid() { return(pxlate != (PXLATE) NULL); } XLATE *pxlo() { return(pxlate); } VOID vMakeIdentity() { pxlate = &xloIdent; }
PXLATE pInitXlate(PXLATE pxlateN) { return(pxlate = pxlateN); }
PXLATE pCreateXlateObject(ULONG ul) { return(pxlate = pCreateXlate(ul)); }
PXLATE pInitXlateNoCache( HANDLE hcmXform, LONG lIcmMode, XEPALOBJ palSrc, XEPALOBJ palDst, XEPALOBJ palDstDC, ULONG iForeDst, // For Mono->Color 0 goes to it
ULONG iBackDst, // For Mono->Color 1 goes to it
ULONG iBackSrc, // For Color->Mono index goes to 1
ULONG flCreate = 0) // Used for Multi-Monitor System
{ //
// Cache ignorant initializer for Xlates. Good for short lived palettes.
//
return(pxlate = CreateXlateObject( hcmXform, lIcmMode, palSrc, palDst, palDstDC, palDstDC, iForeDst, iBackDst, iBackSrc, flCreate ) ); }
ULONG iBackSrc() { return(pxlate->iBackSrc); } ULONG iForeDst() { return(pxlate->iForeDst); } ULONG iBackDst() { return(pxlate->iBackDst); } PPALETTE ppalSrc() { return(pxlate->ppalSrc); } PPALETTE ppalDst() { return(pxlate->ppalDst); } PPALETTE ppalDstDC() { return(pxlate->ppalDstDC);} VOID vAltLock(PXLATE pxlateN) { pxlate = (PXLATE) pxlateN;} VOID vAltUnlock() { if (pxlate != (PXLATE) NULL) { if (pxlate->lCacheIndex >= 0) { //
// It's in the cache
//
ASSERTGDI(pxlate->lCacheIndex < XLATE_CACHE_SIZE, "ERROR not a cache index"); ASSERTGDI(xlateTable[pxlate->lCacheIndex].ulReference != 0, "ERROR xlateindex too small"); InterlockedDecrement((LPLONG) &(xlateTable[pxlate->lCacheIndex].ulReference)); } else if (pxlate->lCacheIndex == XLATE_CACHE_INVALID) { VFREEMEM(pxlate); } #if DBG
else { ASSERTGDI(pxlate->lCacheIndex == XLATE_CACHE_JOURNAL, "ERROR cacheIndex not valid"); } #endif
} }
BOOL bMakeXlate(PUSHORT,XEPALOBJ,SURFACE*,ULONG,ULONG);
BOOL bInitXlateObj(HANDLE hcmXform, LONG lIcmMode, XEPALOBJ palSrc, XEPALOBJ palDst, XEPALOBJ palSrcDC, XEPALOBJ palDstDC, ULONG iForeDst, // For Mono->Color 0 goes to it
ULONG iBackDst, // For Mono->Color 1 goes to it
ULONG iBackSrc, // For Color->Mono index goes to 1
ULONG flCreate = 0); // Used for Multi-Monitor System
VOID vAddToCache(XEPALOBJ palSrc, XEPALOBJ palDest, XEPALOBJ palSrcDC, XEPALOBJ palDestDC);
BOOL bSearchCache(XEPALOBJ palSrc, XEPALOBJ palDst, XEPALOBJ palSrcDC, XEPALOBJ palDstDC, ULONG iForeDst, ULONG iBackDst, ULONG iBackSrc, ULONG flCreate);
BOOL bCreateXlateFromTable(ULONG cEntries, PULONG pIndices, XEPALOBJ palDst); VOID vDelete();
};
PBYTE XLATEOBJ_pGetXlate555( XLATEOBJ *pxlo );
BYTE XLATEOBJ_ulIndexToPalSurf( XLATEOBJ *, PBYTE, ULONG );
BYTE XLATEOBJ_RGB32ToPalSurf( XLATEOBJ *, PBYTE, ULONG );
BYTE XLATEOBJ_BGR32ToPalSurf( XLATEOBJ *, PBYTE, ULONG );
BYTE XLATEOBJ_RGB16_565ToPalSurf( XLATEOBJ *, PBYTE, ULONG );
BYTE XLATEOBJ_RGB16_555ToPalSurf( XLATEOBJ *, PBYTE, ULONG );
typedef BYTE (*PFN_XLATE_RGB_TO_PALETTE)(XLATEOBJ *,PBYTE,ULONG);
/******************************Public*Class********************************\
* class XLATEMEMOBJ * * Xlate Memory Object * * History: * 07-Nov-1990 -by- Patrick Haluptzok patrickh * Wrote it. \**************************************************************************/
class XLATEMEMOBJ : public EXLATEOBJ /* xlmo */ { public: XLATEMEMOBJ(XEPALOBJ palSurf, XEPALOBJ palDC); ~XLATEMEMOBJ(); };
//
// Prototypes for internal functions used in palette management.
//
BOOL bDeletePalette( HPAL hpal, BOOL bCleanup = FALSE, CLEANUPTYPE cutype = CLEANUP_NONE );
ULONG rgbFromColorref( XEPALOBJ palSurf, XEPALOBJ palDC, ULONG crColor );
ULONG ulGetNearestIndexFromColorref( XEPALOBJ palSurf, XEPALOBJ palDC, ULONG crColor, ULONG seSearchExactFirst = SE_DO_SEARCH_EXACT_FIRST );
ULONG ulGetMatchingIndexFromColorref( XEPALOBJ palSurf, XEPALOBJ palDC, ULONG crColor );
ULONG ulIndexToRGB( XEPALOBJ palSrc, XEPALOBJ palDC, ULONG iSolidColor );
ULONG ulColorRefToRGB( XEPALOBJ palSrc, XEPALOBJ palDC, ULONG iSolidColor );
BOOL bIsCompatible( PPALETTE *pppalReference, PPALETTE ppalBM, SURFACE *pSurfBM, HDEV hdev );
VOID vDeleteXLATEOBJ( PXLATE pxlate );
BOOL CreateSurfacePal( XEPALOBJ palSrc, FLONG iPalType, ULONG ulNumReserved, ULONG ulNumPalReg );
VOID ParseBits( FLONG flag, ULONG *pcRight, ULONG *pcLeft, ULONG *pcMiddle, ULONG cForColor );
VOID vMatchAPal( PDC pdc, XEPALOBJ palSurf, XEPALOBJ palDC, ULONG *pulnPhysChanged, ULONG *pulnTransChanged );
PTRANSLATE ptransMatchAPal( PDC pdc, XEPALOBJ palSurf, XEPALOBJ palDC, BOOL bForeground, ULONG *pulnPhysChanged, ULONG *pulnTransChanged );
BOOL bEqualRGB_In_Palette( XEPALOBJ, XEPALOBJ );
PPALETTE CreatePhysicalPalette( HDC hdc, HPALETTE hpal );
PPALETTE ppalGetPPal( HDC hdc, HPALETTE hpal );
VOID vResetSurfacePalette( HDEV hdev );
//
// asm accelerator for ulGetNearestPalentry
//
extern "C" {
PPALETTEENTRY ppalSearchNearestEntry( PPALETTEENTRY ppalTemp, CONST PALETTEENTRY palentry, ULONG cEntries, PUINT pArrayOfSquares ); }
PPALETTE ppalGet_ip( XEPALOBJ, HANDLE, PPDEV ); #endif
#endif // GDIFLAGS_ONLY used for gdikdx
|