CDIB.C
资源名称:MSDN_VC98.zip [点击查看]
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:15k
源码类别:
Windows编程
开发平台:
Visual C++
- /*****************************************************************************
- *
- * CrunchDIB - shrink a DIB down by 2 with color averaging
- *
- *****************************************************************************/
- /**************************************************************************
- *
- * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
- * KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
- * PURPOSE.
- *
- * Copyright (C) 1993 - 1997 Microsoft Corporation. All Rights Reserved.
- *
- **************************************************************************/
- #include <windows.h>
- #include <windowsx.h>
- #include <mmsystem.h>
- #include <memory.h>
- //
- // support huge >64k DIBs?
- //
- #ifndef WIN32
- #define HUGE_DIBS
- #endif
- #ifdef HUGE_DIBS
- #define LPBYTE BYTE _huge *
- #define LPWORD WORD _huge *
- #undef FAR
- #define FAR _huge
- #endif
- /*****************************************************************************
- *
- * These are the standard VGA colors, we will be stuck with until the
- * end of time!
- *
- *****************************************************************************/
- static DWORD VGAColors[16] = {
- 0x00000000 // 0000 black
- ,0x00800000 // 0001 dark red
- ,0x00008000 // 0010 dark green
- ,0x00808000 // 0011 mustard
- ,0x00000080 // 0100 dark blue
- ,0x00800080 // 0101 purple
- ,0x00008080 // 0110 dark turquoise
- ,0x00C0C0C0 // 1000 gray
- ,0x00808080 // 0111 dark gray
- ,0x00FF0000 // 1001 red
- ,0x0000FF00 // 1010 green
- ,0x00FFFF00 // 1011 yellow
- ,0x000000FF // 1100 blue
- ,0x00FF00FF // 1101 pink (magenta)
- ,0x0000FFFF // 1110 cyan
- ,0x00FFFFFF // 1111 white
- };
- /*****************************************************************************
- *
- * bit(b,n) - get the Nth bit of BYTE b
- *
- *****************************************************************************/
- #define bit(b,n) (BYTE)(((b) & (1 << (n))) >> (n))
- /*****************************************************************************
- *
- * SumMono
- *
- * this routine taks four "mono" values and returns the average value.
- *
- * ((b0) + (b1) + (b2) + (b3) >= 2)
- *
- *
- *****************************************************************************/
- #define SumMono(b0,b1,b2,b3) (BYTE)(((b0) + (b1) + (b2) + (b3) + 2) / 4)
- /*****************************************************************************
- *
- * MapVGA
- *
- * map a rgb value to a VGA index
- *
- * 0000 black
- * 0001 dark red
- * 0010 dark green
- * 0011 mustard
- * 0100 dark blue
- * 0101 purple
- * 0110 dark turquoise
- * 1000 gray
- * 0111 dark gray
- * 1001 red
- * 1010 green
- * 1011 yellow
- * 1100 blue
- * 1101 pink (magenta)
- * 1110 cyan
- * 1111 white
- *
- *****************************************************************************/
- #define MapVGA(r,g,b) (((r&~3) == (g&~3) && (g&~3) == (b&~3)) ?
- ((r < 64) ? 0 : (r <= 128) ? 8 : (r <= 192) ? 7 : 15) :
- (((r>192) || (g>192) || (b>192)) ?
- (((r>191) ? 1:0) | ((g>191) ? 2:0) | ((b>191) ? 4:0) | 8) :
- (((r>64) ? 1:0) | ((g>64) ? 2:0) | ((b>64) ? 4:0))) )
- /*****************************************************************************
- *
- * SumRGB
- *
- *****************************************************************************/
- #define SumRGB(b0,b1,b2,b3) RGB(
- ((int)pal.palPalEntry[b0].peRed +
- (int)pal.palPalEntry[b1].peRed +
- (int)pal.palPalEntry[b2].peRed +
- (int)pal.palPalEntry[b3].peRed) >> 2,
- ((int)pal.palPalEntry[b0].peGreen +
- (int)pal.palPalEntry[b1].peGreen +
- (int)pal.palPalEntry[b2].peGreen +
- (int)pal.palPalEntry[b3].peGreen) >> 2,
- ((int)pal.palPalEntry[b0].peBlue +
- (int)pal.palPalEntry[b1].peBlue +
- (int)pal.palPalEntry[b2].peBlue +
- (int)pal.palPalEntry[b3].peBlue) >> 2)
- /*****************************************************************************
- *
- * RGB16
- *
- *****************************************************************************/
- typedef struct { BYTE b,g,r; } RGB24;
- #define RGB16(r,g,b) (
- (((UINT)(r) >> 3) << 10) |
- (((UINT)(g) >> 3) << 5) |
- (((UINT)(b) >> 3) << 0) )
- #define rgb16(r,g,b) (
- ((UINT)(r) << 10) |
- ((UINT)(g) << 5) |
- ((UINT)(b) << 0) )
- //#define RGB16R(rgb) ((((UINT)(rgb) >> 10) & 0x1F) * 255u / 31u)
- //#define RGB16G(rgb) ((((UINT)(rgb) >> 5) & 0x1F) * 255u / 31u)
- //#define RGB16B(rgb) ((((UINT)(rgb) >> 0) & 0x1F) * 255u / 31u)
- #define RGB16R(rgb) aw5to8[((UINT)(rgb) >> 10) & 0x1F]
- #define RGB16G(rgb) aw5to8[((UINT)(rgb) >> 5) & 0x1F]
- #define RGB16B(rgb) aw5to8[((UINT)(rgb) >> 0) & 0x1F]
- #define RGB16r(rgb) ((BYTE)((UINT)(rgb) >> 10) & 0x1F)
- #define RGB16g(rgb) ((BYTE)((UINT)(rgb) >> 5) & 0x1F)
- #define RGB16b(rgb) ((BYTE)((UINT)(rgb) >> 0) & 0x1F)
- /*****************************************************************************
- *
- * Pel() used for 24bit Crunch
- *
- *****************************************************************************/
- #define Pel(p,x) (BYTE)(BitCount == 1 ? Pel1(p,x) :
- BitCount == 4 ? Pel4(p,x) : Pel8(p,x))
- #define Pel1(p,x) (BYTE)bit(((LPBYTE)(p))[(x)/8],7-((x)%8))
- #define Pel4(p,x) (BYTE)((x & 1) ? (((LPBYTE)(p))[(x)/2] & 15) : (((LPBYTE)(p))[(x)/2] >> 4))
- #define Pel8(p,x) (BYTE)(((LPBYTE)(p))[(x)])
- #define Pel16(p,x) (((LPWORD)(p))[(x)])
- #define Pel24(p,x) (((RGB24 FAR *)(p))[(x)])
- /*****************************************************************************
- *
- * CrunchDIB - shrink a DIB down by 2 with color averaging
- *
- * this routine works on 1,4 bpp DIBs
- *
- * for mono DIBs it is assumed they are black and white
- *
- * for 4bpp DIBs it is assumed they use the VGA colors
- *
- * this routine can't be used "in place"
- *
- *****************************************************************************/
- BOOL CrunchDIB(
- LPBITMAPINFOHEADER lpbiSrc, // BITMAPINFO of source
- LPVOID lpSrc, // input bits to crunch
- LPBITMAPINFOHEADER lpbiDst, // BITMAPINFO of dest
- LPVOID lpDst) // output bits to crunch
- {
- LPBYTE pbSrc;
- LPBYTE pbDst;
- LPBYTE pb;
- LPWORD pw;
- BYTE r,g,b,b0,b1,b2,b3;
- WORD w0,w1,w2,w3;
- RGB24 rgb0,rgb1,rgb2,rgb3;
- int WidthBytesSrc;
- int WidthBytesDst;
- UINT x;
- UINT y;
- UINT dx;
- UINT dy;
- int i;
- COLORREF rgb;
- int BitCount;
- UINT aw5to8[32];
- struct {
- WORD palVersion;
- WORD palNumEntries;
- PALETTEENTRY palPalEntry[256];
- } pal;
- if (lpbiSrc->biCompression != BI_RGB)
- return FALSE;
- BitCount = (int)lpbiSrc->biBitCount;
- if (BitCount == 16)
- for (i=0; i<32; i++)
- aw5to8[i] = (UINT)i * 255u / 31u;
- dx = (int)lpbiDst->biWidth;
- WidthBytesDst = (((UINT)lpbiDst->biBitCount * dx + 31)&~31) / 8;
- dy = (int)lpbiSrc->biHeight;
- dx = (int)lpbiSrc->biWidth;
- WidthBytesSrc = (((UINT)lpbiSrc->biBitCount * dx + 31)&~31) / 8;
- dx &= ~1;
- dy &= ~1;
- pbSrc = lpSrc;
- pbDst = lpDst;
- if (lpbiSrc->biClrUsed == 0 && lpbiSrc->biBitCount <= 8)
- lpbiSrc->biClrUsed = (1 << (int)lpbiSrc->biBitCount);
- pal.palVersion = 0x300;
- pal.palNumEntries = (int)lpbiSrc->biClrUsed;
- for (i=0; i<(int)pal.palNumEntries; i++)
- {
- pal.palPalEntry[i].peRed = ((LPRGBQUAD)(lpbiSrc+1))[i].rgbRed;
- pal.palPalEntry[i].peGreen = ((LPRGBQUAD)(lpbiSrc+1))[i].rgbGreen;
- pal.palPalEntry[i].peBlue = ((LPRGBQUAD)(lpbiSrc+1))[i].rgbBlue;
- pal.palPalEntry[i].peFlags = 0;
- }
- if (lpbiDst->biBitCount == 8)
- _fmemcpy(lpbiDst+1,lpbiSrc+1,(int)lpbiSrc->biClrUsed*sizeof(RGBQUAD));
- if (lpbiDst->biBitCount == 4)
- _fmemcpy(lpbiDst+1,VGAColors,sizeof(VGAColors));
- if ((int)lpbiDst->biBitCount == (int)lpbiSrc->biBitCount)
- {
- switch((int)lpbiSrc->biBitCount)
- {
- case 1:
- dx = dx / 8; // dx is byte count
- for (y=0; y<dy; y+=2)
- {
- pb = pbDst;
- for (x=0; x<dx; x += 2)
- {
- b0 = pbSrc[x];
- b1 = pbSrc[x + WidthBytesSrc];
- b = (BYTE)(
- (SumMono(bit(b0,7), bit(b0,6), bit(b1,7), bit(b1,6)) << 7) |
- (SumMono(bit(b0,5), bit(b0,4), bit(b1,5), bit(b1,4)) << 6) |
- (SumMono(bit(b0,3), bit(b0,2), bit(b1,3), bit(b1,2)) << 5) |
- (SumMono(bit(b0,1), bit(b0,0), bit(b1,1), bit(b1,0)) << 4));
- b0 = pbSrc[x + 1];
- b1 = pbSrc[x + 1 + WidthBytesSrc];
- b |=(SumMono(bit(b0,7), bit(b0,6), bit(b1,7), bit(b1,6)) << 3) |
- (SumMono(bit(b0,5), bit(b0,4), bit(b1,5), bit(b1,4)) << 2) |
- (SumMono(bit(b0,3), bit(b0,2), bit(b1,3), bit(b1,2)) << 1) |
- (SumMono(bit(b0,1), bit(b0,0), bit(b1,1), bit(b1,0)) << 0);
- *pb++ = b;
- }
- pbSrc += WidthBytesSrc*2;
- pbDst += WidthBytesDst;
- }
- break;
- case 4:
- dx = dx / 2; // dx is byte count
- for (y=0; y<dy; y+=2)
- {
- pb = pbDst;
- for (x=0; x<dx; x+=2)
- {
- b0 = pbSrc[x];
- b1 = pbSrc[x + WidthBytesSrc];
- rgb = SumRGB((b0 >> 4),(b0 & 0x0F),
- (b1 >> 4),(b1 & 0x0F));
- b = (BYTE)(MapVGA(GetRValue(rgb),GetGValue(rgb),GetBValue(rgb)) << 4);
- b0 = pbSrc[x + 1];
- b1 = pbSrc[x + 1 + WidthBytesSrc];
- rgb = SumRGB((b0 >> 4),(b0 & 0x0F),
- (b1 >> 4),(b1 & 0x0F));
- b |= MapVGA(GetRValue(rgb),GetGValue(rgb),GetBValue(rgb));
- *pb++ = b;
- }
- pbSrc += WidthBytesSrc*2;
- pbDst += WidthBytesDst;
- }
- break;
- #if 0
- case 8:
- {
- HPALETTE hpal;
- hpal = CreatePalette((LPLOGPALETTE)&pal);
- for (y=0; y<dy; y+=2)
- {
- pb = pbDst;
- for (x=0; x<dx; x+=2)
- {
- b0 = Pel8(pbSrc,x);
- b1 = Pel8(pbSrc+WidthBytesSrc, x);
- b2 = Pel8(pbSrc,x+1);
- b3 = Pel8(pbSrc+WidthBytesSrc,x+1);
- *pb++ = (BYTE)GetNearestPaletteIndex(hpal,
- SumRGB(b0,b1,b2,b3));
- }
- pbSrc += WidthBytesSrc*2;
- pbDst += WidthBytesDst;
- }
- DeleteObject(hpal);
- }
- break;
- #endif
- case 16:
- for (y=0; y<dy; y+=2)
- {
- pw = (LPWORD)pbDst;
- for (x=0; x<dx; x += 2)
- {
- w0 = Pel16(pbSrc,x);
- w1 = Pel16(pbSrc,x+1);
- w2 = Pel16(pbSrc+WidthBytesSrc,x);
- w3 = Pel16(pbSrc+WidthBytesSrc,x+1);
- r = ((BYTE)RGB16r(w0) + RGB16r(w1) + RGB16r(w2) + RGB16r(w3)) >> 2;
- g = ((BYTE)RGB16g(w0) + RGB16g(w1) + RGB16g(w2) + RGB16g(w3)) >> 2;
- b = ((BYTE)RGB16b(w0) + RGB16b(w1) + RGB16b(w2) + RGB16b(w3)) >> 2;
- *pw++ = rgb16(r,g,b);
- }
- pbSrc += WidthBytesSrc*2;
- pbDst += WidthBytesDst;
- }
- break;
- case 24:
- for (y=0; y<dy; y+=2)
- {
- pb = pbDst;
- for (x=0; x<dx; x += 2)
- {
- rgb0 = Pel24(pbSrc,x);
- rgb1 = Pel24(pbSrc,x+1);
- rgb2 = Pel24(pbSrc+WidthBytesSrc,x);
- rgb3 = Pel24(pbSrc+WidthBytesSrc,x+1);
- rgb = RGB(
- ((UINT)rgb0.r + rgb1.r + rgb2.r + rgb3.r)/4,
- ((UINT)rgb0.g + rgb1.g + rgb2.g + rgb3.g)/4,
- ((UINT)rgb0.b + rgb1.b + rgb2.b + rgb3.b)/4);
- *pb++ = GetBValue(rgb);
- *pb++ = GetGValue(rgb);
- *pb++ = GetRValue(rgb);
- }
- pbSrc += WidthBytesSrc*2;
- pbDst += WidthBytesDst;
- }
- break;
- default:
- return FALSE;
- }
- }
- else if ((int)lpbiDst->biBitCount == 24)
- {
- switch((int)lpbiSrc->biBitCount)
- {
- case 1:
- case 4:
- case 8:
- for (y=0; y<dy; y+=2)
- {
- pb = pbDst;
- for (x=0; x<dx; x += 2)
- {
- b0 = Pel(pbSrc,x);
- b1 = Pel(pbSrc,x+1);
- b2 = Pel(pbSrc+WidthBytesSrc,x);
- b3 = Pel(pbSrc+WidthBytesSrc,x+1);
- rgb = SumRGB(b0,b1,b2,b3);
- *pb++ = GetBValue(rgb);
- *pb++ = GetGValue(rgb);
- *pb++ = GetRValue(rgb);
- }
- pbSrc += WidthBytesSrc*2;
- pbDst += WidthBytesDst;
- }
- break;
- case 16:
- for (y=0; y<dy; y+=2)
- {
- pb = pbDst;
- for (x=0; x<dx; x += 2)
- {
- w0 = Pel16(pbSrc,x);
- w1 = Pel16(pbSrc,x+1);
- w2 = Pel16(pbSrc+WidthBytesSrc,x);
- w3 = Pel16(pbSrc+WidthBytesSrc,x+1);
- r = (RGB16R(w0) + RGB16R(w1) + RGB16R(w2) + RGB16R(w3)) / 4;
- g = (RGB16G(w0) + RGB16G(w1) + RGB16G(w2) + RGB16G(w3)) / 4;
- b = (RGB16B(w0) + RGB16B(w1) + RGB16B(w2) + RGB16B(w3)) / 4;
- rgb = RGB(r,g,b);
- *pb++ = GetBValue(rgb);
- *pb++ = GetGValue(rgb);
- *pb++ = GetRValue(rgb);
- }
- pbSrc += WidthBytesSrc*2;
- pbDst += WidthBytesDst;
- }
- break;
- default:
- return FALSE;
- }
- }
- else
- {
- return FALSE;
- }
- return TRUE;
- }