/*
 * 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;
}
