📄 dibpal.c
字号:
/*----------------------------------------
DIBPAL.C -- Palette-Creation Functions
(c) Charles Petzold, 1998
----------------------------------------*/
#include <windows.h>
#include "dibhelp.h"
#include "dibpal.h"
/*------------------------------------------------------------
DibPalDibTable: Creates a palette from the DIB color table
------------------------------------------------------------*/
HPALETTE DibPalDibTable (HDIB hdib)
{
HPALETTE hPalette ;
int i, iNum ;
LOGPALETTE * plp ;
RGBQUAD rgb ;
if (0 == (iNum = DibNumColors (hdib)))
return NULL ;
plp = malloc (sizeof (LOGPALETTE) + (iNum - 1) * sizeof (PALETTEENTRY)) ;
plp->palVersion = 0x0300 ;
plp->palNumEntries = iNum ;
for (i = 0 ; i < iNum ; i++)
{
DibGetColor (hdib, i, &rgb) ;
plp->palPalEntry[i].peRed = rgb.rgbRed ;
plp->palPalEntry[i].peGreen = rgb.rgbGreen ;
plp->palPalEntry[i].peBlue = rgb.rgbBlue ;
plp->palPalEntry[i].peFlags = 0 ;
}
hPalette = CreatePalette (plp) ;
free (plp) ;
return hPalette ;
}
/*------------------------------------------------------------------------
DibPalAllPurpose: Creates a palette suitable for a wide variety
of images; the palette has 247 entries, but 15 of them are
duplicates or match the standard 20 colors.
------------------------------------------------------------------------*/
HPALETTE DibPalAllPurpose (void)
{
HPALETTE hPalette ;
int i, incr, R, G, B ;
LOGPALETTE * plp ;
plp = malloc (sizeof (LOGPALETTE) + 246 * sizeof (PALETTEENTRY)) ;
plp->palVersion = 0x0300 ;
plp->palNumEntries = 247 ;
// The following loop calculates 31 grays shades, but 3 of them
// will match the standard 20 colors
for (i = 0, G = 0, incr = 8 ; G <= 0xFF ; i++, G += incr)
{
plp->palPalEntry[i].peRed = (BYTE) G ;
plp->palPalEntry[i].peGreen = (BYTE) G ;
plp->palPalEntry[i].peBlue = (BYTE) G ;
plp->palPalEntry[i].peFlags = 0 ;
incr = (incr == 9 ? 8 : 9) ;
}
// The following loop is responsible for 216 entries, but 8 of
// them will match the standard 20 colors, and another
// 4 of them will match the gray shades above.
for (R = 0 ; R <= 0xFF ; R += 0x33)
for (G = 0 ; G <= 0xFF ; G += 0x33)
for (B = 0 ; B <= 0xFF ; B += 0x33)
{
plp->palPalEntry[i].peRed = (BYTE) R ;
plp->palPalEntry[i].peGreen = (BYTE) G ;
plp->palPalEntry[i].peBlue = (BYTE) B ;
plp->palPalEntry[i].peFlags = 0 ;
i++ ;
}
hPalette = CreatePalette (plp) ;
free (plp) ;
return hPalette ;
}
/*------------------------------------------------------------------------
DibPalUniformGrays: Creates a palette of iNum grays, uniformly spaced
------------------------------------------------------------------------*/
HPALETTE DibPalUniformGrays (int iNum)
{
HPALETTE hPalette ;
int i ;
LOGPALETTE * plp ;
plp = malloc (sizeof (LOGPALETTE) + (iNum - 1) * sizeof (PALETTEENTRY)) ;
plp->palVersion = 0x0300 ;
plp->palNumEntries = iNum ;
for (i = 0 ; i < iNum ; i++)
{
plp->palPalEntry[i].peRed =
plp->palPalEntry[i].peGreen =
plp->palPalEntry[i].peBlue = (BYTE) (i * 255 / (iNum - 1)) ;
plp->palPalEntry[i].peFlags = 0 ;
}
hPalette = CreatePalette (plp) ;
free (plp) ;
return hPalette ;
}
/*------------------------------------------------------------------------
DibPalUniformColors: Creates a palette of iNumR x iNumG x iNumB colors
------------------------------------------------------------------------*/
HPALETTE DibPalUniformColors (int iNumR, int iNumG, int iNumB)
{
HPALETTE hPalette ;
int i, iNum, R, G, B ;
LOGPALETTE * plp ;
iNum = iNumR * iNumG * iNumB ;
plp = malloc (sizeof (LOGPALETTE) + (iNum - 1) * sizeof (PALETTEENTRY)) ;
plp->palVersion = 0x0300 ;
plp->palNumEntries = iNumR * iNumG * iNumB ;
i = 0 ;
for (R = 0 ; R < iNumR ; R++)
for (G = 0 ; G < iNumG ; G++)
for (B = 0 ; B < iNumB ; B++)
{
plp->palPalEntry[i].peRed = (BYTE) (R * 255 / (iNumR - 1)) ;
plp->palPalEntry[i].peGreen = (BYTE) (G * 255 / (iNumG - 1)) ;
plp->palPalEntry[i].peBlue = (BYTE) (B * 255 / (iNumB - 1)) ;
plp->palPalEntry[i].peFlags = 0 ;
i++ ;
}
hPalette = CreatePalette (plp) ;
free (plp) ;
return hPalette ;
}
/*---------------------------------------------------------------
DibPalVga: Creates a palette based on standard 16 VGA colors
---------------------------------------------------------------*/
HPALETTE DibPalVga (void)
{
static RGBQUAD rgb [16] = { 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x80, 0x00,
0x00, 0x80, 0x00, 0x00,
0x00, 0x80, 0x80, 0x00,
0x80, 0x00, 0x00, 0x00,
0x80, 0x00, 0x80, 0x00,
0x80, 0x80, 0x00, 0x00,
0x80, 0x80, 0x80, 0x00,
0xC0, 0xC0, 0xC0, 0x00,
0x00, 0x00, 0xFF, 0x00,
0x00, 0xFF, 0x00, 0x00,
0x00, 0xFF, 0xFF, 0x00,
0xFF, 0x00, 0x00, 0x00,
0xFF, 0x00, 0xFF, 0x00,
0xFF, 0xFF, 0x00, 0x00,
0xFF, 0xFF, 0xFF, 0x00 } ;
HPALETTE hPalette ;
int i ;
LOGPALETTE * plp ;
plp = malloc (sizeof (LOGPALETTE) + 15 * sizeof (PALETTEENTRY)) ;
plp->palVersion = 0x0300 ;
plp->palNumEntries = 16 ;
for (i = 0 ; i < 16 ; i++)
{
plp->palPalEntry[i].peRed = rgb[i].rgbRed ;
plp->palPalEntry[i].peGreen = rgb[i].rgbGreen ;
plp->palPalEntry[i].peBlue = rgb[i].rgbBlue ;
plp->palPalEntry[i].peFlags = 0 ;
}
hPalette = CreatePalette (plp) ;
free (plp) ;
return hPalette ;
}
/*---------------------------------------------
Macro used in palette optimization routines
---------------------------------------------*/
#define PACK_RGB(R,G,B,iRes) ((int) (R) | ((int) (G) << (iRes)) | \
((int) (B) << ((iRes) + (iRes))))
/*--------------------------------------------------------------------
AccumColorCounts: Fills up piCount (indexed by a packed RGB color)
with counts of pixels of that color.
--------------------------------------------------------------------*/
static void AccumColorCounts (HDIB hdib, int * piCount, int iRes)
{
int x, y, cx, cy ;
RGBQUAD rgb ;
cx = DibWidth (hdib) ;
cy = DibHeight (hdib) ;
for (y = 0 ; y < cy ; y++)
for (x = 0 ; x < cx ; x++)
{
DibGetPixelColor (hdib, x, y, &rgb) ;
rgb.rgbRed >>= (8 - iRes) ;
rgb.rgbGreen >>= (8 - iRes) ;
rgb.rgbBlue >>= (8 - iRes) ;
++piCount [PACK_RGB (rgb.rgbRed, rgb.rgbGreen, rgb.rgbBlue, iRes)] ;
}
}
/*--------------------------------------------------------------
DibPalPopularity: Popularity algorithm for optimized colors
--------------------------------------------------------------*/
HPALETTE DibPalPopularity (HDIB hdib, int iRes)
{
HPALETTE hPalette ;
int i, iArraySize, iEntry, iCount, iIndex, iMask, R, G, B ;
int * piCount ;
LOGPALETTE * plp ;
// Validity checks
if (DibBitCount (hdib) < 16)
return NULL ;
if (iRes < 3 || iRes > 8)
return NULL ;
// Allocate array for counting pixel colors
iArraySize = 1 << (3 * iRes) ;
iMask = (1 << iRes) - 1 ;
if (NULL == (piCount = calloc (iArraySize, sizeof (int))))
return NULL ;
// Get the color counts
AccumColorCounts (hdib, piCount, iRes) ;
// Set up a palette
plp = malloc (sizeof (LOGPALETTE) + 235 * sizeof (PALETTEENTRY)) ;
plp->palVersion = 0x0300 ;
for (iEntry = 0 ; iEntry < 236 ; iEntry++)
{
for (i = 0, iCount = 0 ; i < iArraySize ; i++)
if (piCount[i] > iCount)
{
iCount = piCount[i] ;
iIndex = i ;
}
if (iCount == 0)
break ;
R = (iMask & iIndex ) << (8 - iRes) ;
G = (iMask & (iIndex >> iRes )) << (8 - iRes) ;
B = (iMask & (iIndex >> (iRes + iRes))) << (8 - iRes) ;
plp->palPalEntry[iEntry].peRed = (BYTE) R ;
plp->palPalEntry[iEntry].peGreen = (BYTE) G ;
plp->palPalEntry[iEntry].peBlue = (BYTE) B ;
plp->palPalEntry[iEntry].peFlags = 0 ;
piCount [iIndex] = 0 ;
}
// On exit from the loop iEntry will be the number of stored entries
plp->palNumEntries = iEntry ;
// Create the palette, clean up, and return the palette handle
hPalette = CreatePalette (plp) ;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -