mirror of
https://github.com/reactos/wine.git
synced 2024-11-29 14:40:56 +00:00
204 lines
5.7 KiB
C
204 lines
5.7 KiB
C
|
/*
|
||
|
* GDI device independent bitmaps
|
||
|
*
|
||
|
* Copyright 1993 Alexandre Julliard
|
||
|
*/
|
||
|
|
||
|
static char Copyright[] = "Copyright Alexandre Julliard, 1993";
|
||
|
|
||
|
#include <stdlib.h>
|
||
|
|
||
|
#include "gdi.h"
|
||
|
|
||
|
|
||
|
extern XImage * BITMAP_BmpToImage( BITMAP *, void * );
|
||
|
|
||
|
|
||
|
/***********************************************************************
|
||
|
* DIB_BitmapInfoSize
|
||
|
*
|
||
|
* Return the size of the bitmap info structure.
|
||
|
*/
|
||
|
int DIB_BitmapInfoSize( BITMAPINFO * info, WORD coloruse )
|
||
|
{
|
||
|
int size = info->bmiHeader.biClrUsed;
|
||
|
if (!size && (info->bmiHeader.biBitCount != 24))
|
||
|
size = 1 << info->bmiHeader.biBitCount;
|
||
|
if (coloruse == DIB_RGB_COLORS)
|
||
|
size = info->bmiHeader.biSize + size * sizeof(RGBQUAD);
|
||
|
else
|
||
|
size = info->bmiHeader.biSize + size * sizeof(WORD);
|
||
|
return size;
|
||
|
}
|
||
|
|
||
|
|
||
|
/***********************************************************************
|
||
|
* DIB_DIBmpToImage
|
||
|
*
|
||
|
* Create an XImage pointing to the bitmap data.
|
||
|
*/
|
||
|
XImage * DIB_DIBmpToImage( BITMAPINFOHEADER * bmp, void * bmpData )
|
||
|
{
|
||
|
XImage * image;
|
||
|
int bytesPerLine = (bmp->biWidth * bmp->biBitCount + 31) / 32 * 4;
|
||
|
|
||
|
image = XCreateImage( XT_display, DefaultVisualOfScreen( XT_screen ),
|
||
|
bmp->biBitCount, ZPixmap, 0, bmpData,
|
||
|
bmp->biWidth, bmp->biHeight, 32, bytesPerLine );
|
||
|
if (!image) return 0;
|
||
|
image->byte_order = MSBFirst;
|
||
|
image->bitmap_bit_order = MSBFirst;
|
||
|
image->bitmap_unit = 16;
|
||
|
_XInitImageFuncPtrs(image);
|
||
|
return image;
|
||
|
}
|
||
|
|
||
|
|
||
|
/***********************************************************************
|
||
|
* SetDIBits (GDI.440)
|
||
|
*/
|
||
|
int SetDIBits( HDC hdc, HBITMAP hbitmap, WORD startscan, WORD lines,
|
||
|
LPSTR bits, BITMAPINFO * info, WORD coloruse )
|
||
|
{
|
||
|
DC * dc;
|
||
|
BITMAPOBJ * bmpObj;
|
||
|
BITMAP * bmp;
|
||
|
WORD * colorMapping;
|
||
|
RGBQUAD * rgbPtr;
|
||
|
XImage * bmpImage, * dibImage;
|
||
|
int i, x, y, pixel, colors;
|
||
|
|
||
|
if (!lines) return 0;
|
||
|
if (!(dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ))) return 0;
|
||
|
if (!(bmpObj = (BITMAPOBJ *)GDI_GetObjPtr( hbitmap, BITMAP_MAGIC )))
|
||
|
return 0;
|
||
|
if (!(bmp = (BITMAP *) GlobalLock( bmpObj->hBitmap ))) return 0;
|
||
|
|
||
|
/* Build the color mapping table */
|
||
|
|
||
|
if (info->bmiHeader.biBitCount == 24) colorMapping = NULL;
|
||
|
else if (coloruse == DIB_RGB_COLORS)
|
||
|
{
|
||
|
colors = info->bmiHeader.biClrUsed;
|
||
|
if (!colors) colors = 1 << info->bmiHeader.biBitCount;
|
||
|
if (!(colorMapping = (WORD *)malloc( colors * sizeof(WORD) )))
|
||
|
{
|
||
|
GlobalUnlock( bmpObj->hBitmap );
|
||
|
return 0;
|
||
|
}
|
||
|
for (i = 0, rgbPtr = info->bmiColors; i < colors; i++, rgbPtr++)
|
||
|
colorMapping[i] = GetNearestPaletteIndex( dc->w.hPalette,
|
||
|
RGB(rgbPtr->rgbRed,
|
||
|
rgbPtr->rgbGreen,
|
||
|
rgbPtr->rgbBlue) );
|
||
|
}
|
||
|
else colorMapping = (WORD *)info->bmiColors;
|
||
|
|
||
|
/* Transfer the pixels (very slow...) */
|
||
|
|
||
|
bmpImage = BITMAP_BmpToImage( bmp, ((char *)bmp) + sizeof(BITMAP) );
|
||
|
dibImage = DIB_DIBmpToImage( &info->bmiHeader, bits );
|
||
|
|
||
|
for (y = 0; y < lines; y++)
|
||
|
{
|
||
|
for (x = 0; x < info->bmiHeader.biWidth; x++)
|
||
|
{
|
||
|
pixel = XGetPixel( dibImage, x, y );
|
||
|
if (colorMapping) pixel = colorMapping[pixel];
|
||
|
else pixel = GetNearestPaletteIndex(dc->w.hPalette,(COLORREF)pixel);
|
||
|
XPutPixel( bmpImage, x, bmp->bmHeight - startscan - y - 1, pixel );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
bmpImage->data = NULL;
|
||
|
dibImage->data = NULL;
|
||
|
XDestroyImage( bmpImage );
|
||
|
XDestroyImage( dibImage );
|
||
|
|
||
|
if (colorMapping && (coloruse == DIB_RGB_COLORS)) free(colorMapping);
|
||
|
|
||
|
GlobalUnlock( bmpObj->hBitmap );
|
||
|
return lines;
|
||
|
}
|
||
|
|
||
|
|
||
|
/***********************************************************************
|
||
|
* GetDIBits (GDI.441)
|
||
|
*/
|
||
|
int GetDIBits( HDC hdc, HBITMAP hbitmap, WORD startscan, WORD lines,
|
||
|
LPSTR bits, BITMAPINFO * info, WORD coloruse )
|
||
|
{
|
||
|
DC * dc;
|
||
|
BITMAPOBJ * bmpObj;
|
||
|
BITMAP * bmp;
|
||
|
PALETTEENTRY * palEntry;
|
||
|
PALETTEOBJ * palette;
|
||
|
XImage * bmpImage, * dibImage;
|
||
|
int i, x, y;
|
||
|
|
||
|
if (!lines) return 0;
|
||
|
if (!(dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ))) return 0;
|
||
|
if (!(bmpObj = (BITMAPOBJ *)GDI_GetObjPtr( hbitmap, BITMAP_MAGIC )))
|
||
|
return 0;
|
||
|
if (!(palette = (PALETTEOBJ*)GDI_GetObjPtr( dc->w.hPalette, PALETTE_MAGIC )))
|
||
|
return 0;
|
||
|
if (!(bmp = (BITMAP *) GlobalLock( bmpObj->hBitmap ))) return 0;
|
||
|
|
||
|
/* Transfer color info */
|
||
|
|
||
|
palEntry = palette->logpalette.palPalEntry;
|
||
|
for (i = 0; i < info->bmiHeader.biClrUsed; i++, palEntry++)
|
||
|
{
|
||
|
if (coloruse == DIB_RGB_COLORS)
|
||
|
{
|
||
|
info->bmiColors[i].rgbRed = palEntry->peRed;
|
||
|
info->bmiColors[i].rgbGreen = palEntry->peGreen;
|
||
|
info->bmiColors[i].rgbBlue = palEntry->peBlue;
|
||
|
info->bmiColors[i].rgbReserved = 0;
|
||
|
}
|
||
|
else ((WORD *)info->bmiColors)[i] = (WORD)i;
|
||
|
}
|
||
|
|
||
|
/* Transfer the pixels (very slow...) */
|
||
|
|
||
|
if (bits)
|
||
|
{
|
||
|
bmpImage = BITMAP_BmpToImage( bmp, ((char *)bmp) + sizeof(BITMAP) );
|
||
|
dibImage = DIB_DIBmpToImage( &info->bmiHeader, bits );
|
||
|
|
||
|
for (y = 0; y < lines; y++)
|
||
|
{
|
||
|
for (x = 0; x < info->bmiHeader.biWidth; x++)
|
||
|
{
|
||
|
XPutPixel( dibImage, x, y,
|
||
|
XGetPixel(bmpImage, x, bmp->bmHeight-startscan-y-1) );
|
||
|
|
||
|
}
|
||
|
}
|
||
|
|
||
|
bmpImage->data = NULL;
|
||
|
dibImage->data = NULL;
|
||
|
XDestroyImage( bmpImage );
|
||
|
XDestroyImage( dibImage );
|
||
|
}
|
||
|
|
||
|
GlobalUnlock( bmpObj->hBitmap );
|
||
|
return lines;
|
||
|
}
|
||
|
|
||
|
|
||
|
/***********************************************************************
|
||
|
* CreateDIBitmap (GDI.442)
|
||
|
*/
|
||
|
HBITMAP CreateDIBitmap( HDC hdc, BITMAPINFOHEADER * header, DWORD init,
|
||
|
LPSTR bits, BITMAPINFO * data, WORD coloruse )
|
||
|
{
|
||
|
HBITMAP handle;
|
||
|
|
||
|
handle = CreateCompatibleBitmap( hdc, header->biWidth, header->biHeight );
|
||
|
if (!handle) return 0;
|
||
|
if (init == CBM_INIT) SetDIBits( hdc, handle, 0, header->biHeight,
|
||
|
bits, data, coloruse );
|
||
|
return handle;
|
||
|
}
|