bmp.h File Reference

Simple windows bitmap handling. More...

#include "opc/opc.h"
#include "ctl/ctldef.h"

Include dependency graph for bmp.h:

This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Defines

#define BMI_SIZE   (sizeof(BITMAPINFO) + (255 * sizeof(RGBQUAD)))
#define BMI_ParseData(image, bmi, bits)
 Given a pointer to a bitmap loaded into memory, find bmi, bits NOTE: Only valid on Wintel architecture.
#define BMI_Init(bmi, wide, high, bpp)
 Initialize bmi as generic Windows bitmap.
#define BMI_Create(bmi, bits)   { (bits) = calloc( BMI_LineSize(bmi), BMI_High(bmi) ); }
 Allocate a bitmap for 'bmi'.
#define BMI_Release(bmi, bits)   { free( bits ); }
 Free image allocated with BMI_Create.

Functions

int RGBQUAD_Nearest (const RGBQUAD *clut, size_t count, const RGBQUAD *color)
 Work out the best match in 'clut'.
bool BMI_ReadRow (RGBQUAD *pixel, const BITMAPINFO *bmi, const void *bits, int row)
 Get color values from each pixel in a row of bmi/bits as an RGBQUAD Half of translation from one BMI format to another.
bool BMI_WriteRow (const BITMAPINFO *bmi, void *bits, const RGBQUAD *pixel, int row)
void BMI_Translate (const BITMAPINFO *dst, void *bdst, const BITMAPINFO *src, const void *bsrc)
 Copy/Translate src bitmap to target bitmap.
void * BMI_Unpack (const BITMAPINFO *bmi, const void *bits)
 Unpack certain BMP formats.
size_t BMI_MakeClut (RGBQUAD *dstlut, size_t clut, const BITMAPINFO *bmi, const void *bits)
 Build a color lookup table of a given size from true-color source pixels Truly an ugly and time-consuming ordeal, but this should make it "simple", or at least less horrible.
void BMI_Clut_Begin (BMIClut *clut)
 Prepare palette accumulator for new data.
void BMI_Clut_AddColor (BMIClut *clut, const RGBQUAD *rgb)
 Add a color to the accumulator.
size_t BMI_Clut_Make (BMIClut *clut, RGBQUAD *dstlut, size_t cClut)
 Manufacutre the palette.
bool BMI_Save (const char *path, const BITMAPINFO *bmi, const void *bits)
 Save a bitmap.
bool BMI_Load (const char *path, BITMAPINFO **bmi, void **bits)
 Load a bitmap.
void BMI_OPC (OPC *opc, const BITMAPINFO *bmi, void *bits)
 Convert bmi,bits to native OPC NOTE: Assumes OPC is same format as bmi,bits.


Detailed Description

Simple windows bitmap handling.

Author:
David Mace

Definition in file bmp.h.


Define Documentation

#define BMI_Create ( bmi,
bits   )     { (bits) = calloc( BMI_LineSize(bmi), BMI_High(bmi) ); }

Allocate a bitmap for 'bmi'.

Parameters:
bmi Pointer to BITMAPINFO to containing description of bitmap
bits void Pointer to receive bitmap

Definition at line 160 of file bmp.h.

#define BMI_Init ( bmi,
wide,
high,
bpp   ) 

Value:

{\
    BITMAPINFOHEADER* pbmi = &(bmi)->bmiHeader;\
    pbmi->biSize = sizeof(BITMAPINFOHEADER);\
    pbmi->biWidth = (wide);\
    pbmi->biHeight = (high);\
    pbmi->biPlanes = 1;\
    pbmi->biBitCount = (bpp);\
    pbmi->biCompression = BI_RGB;\
    pbmi->biSizeImage = 0;\
    pbmi->biXPelsPerMeter = 0;\
    pbmi->biYPelsPerMeter = 0;\
    pbmi->biClrUsed = 0;\
    pbmi->biClrImportant = 0;\
}
Initialize bmi as generic Windows bitmap.

Parameters:
bmi Pointer to BITMAPINFO to initialize
wide Width of bmp
high Height of bmp
bpp Bits per pixel, i.e. 1,4,8,16,24,32

Definition at line 140 of file bmp.h.

#define BMI_ParseData ( image,
bmi,
bits   ) 

Value:

{\
    if( *((uint16 *)(image)) == *((uint16 *)"BM") ) \
    {\
        /* Loaded from a file; strip file header out */\
        (bmi) = (BITMAPINFO *)( (uint8 *)(image) + sizeof(BITMAPFILEHEADER) );\
        (bits) = (uint8 *)(image) + ((BITMAPFILEHEADER *)image)->bfOffBits;\
    }\
    else \
    {\
        /* <Probably> loaded from a resource */\
        (bmi) = (BITMAPINFO *)(image);\
        (bits) = (uint8 *)(bmi) + BMI_BMI_Size( bmi );\
    }\
}
Given a pointer to a bitmap loaded into memory, find bmi, bits NOTE: Only valid on Wintel architecture.

Parameters:
image Pointer to image to parse
bmi BITMAPINFO Pointer to be initialized
bits Pixel data

Definition at line 118 of file bmp.h.

Referenced by BMI_Load().

#define BMI_Release ( bmi,
bits   )     { free( bits ); }

Free image allocated with BMI_Create.

Parameters:
bmi Pointer to BITMAPINFO to containing description of bitmap
bits Bits to free, allocated with BMI_Create

Definition at line 166 of file bmp.h.

#define BMI_SIZE   (sizeof(BITMAPINFO) + (255 * sizeof(RGBQUAD)))

defined(_WINGDI_)

Definition at line 82 of file bmp.h.


Function Documentation

void BMI_Clut_AddColor ( BMIClut *  clut,
const RGBQUAD *  rgb 
)

Add a color to the accumulator.

Parameters:
clut Instance of clut
rgb Color to add

Definition at line 486 of file bmp.c.

References type_max.

Referenced by BMI_MakeClut().

00487 {
00488     #define CLI(RGBQUAD) ( (((RGBQUAD).rgbBlue&0xf8)>>3) | (((RGBQUAD).rgbGreen&0xf8)<<2) | (((RGBQUAD).rgbRed&0xf8)<<7) )
00489     int index = CLI(*rgb);
00490     struct BMIClutEntry* curr = clut->cluts + index;
00491     curr->rgb = *rgb;
00492     if( curr->count < type_max(uint32) )
00493         curr->count++;
00494 }

void BMI_Clut_Begin ( BMIClut *  clut  ) 

Prepare palette accumulator for new data.

Parameters:
clut Instance of clut to initialize

Definition at line 477 of file bmp.c.

Referenced by BMI_MakeClut().

00478 {
00479     memset( clut->cluts, 0, sizeof(clut->cluts) );
00480 }

size_t BMI_Clut_Make ( BMIClut *  clut,
RGBQUAD *  dstlut,
size_t  cClut 
)

Manufacutre the palette.

Parameters:
clut Instance of clut
dstlut Array to receive official colors
cClut Number of colors array will accept

Definition at line 532 of file bmp.c.

References array_qsort, and countof.

Referenced by BMI_MakeClut().

00533 {
00534     array_qsort( struct BMIClutEntry, clut->cluts, countof(clut->cluts), qsclutz );
00535     array_qsort( struct BMIClutEntry, clut->cluts, cClut, qspretty );
00536     {
00537         const struct BMIClutEntry* curr = clut->cluts;
00538         size_t remain = cClut;
00539         while( remain )
00540         {
00541             remain--;
00542             if( curr->count )
00543                 *dstlut++ = (curr++)->rgb;
00544             else
00545                 break;
00546         }
00547         cClut -= remain;
00548         return cClut;
00549     }
00550 }

bool BMI_Load ( const char *  path,
BITMAPINFO **  bmi,
void **  bits 
)

Load a bitmap.

Parameters:
path Path to reat file from
bmi Pointer to pointer to receive bitmap header
bits Pointer to pointer to receive bitmap content

Definition at line 735 of file bmp.c.

References BMI_ParseData, BMI_Unpack(), and ctl_mmap_open().

00736 {
00737     /*
00738      * TODO: Replace with target independent code
00739      */
00740     ctl_mmap image;
00741     ctl_mmap_open( &image, path );
00742     if( ctl_mmap_ready(&image) )
00743     {
00744         const BITMAPINFO* bmiIn;
00745         const void* bitsIn;
00746         BMI_ParseData( ctl_mmap_ptr(&image), bmiIn, bitsIn );
00747         *bmi = BMI_BMI_Copy(bmiIn);
00748         *bits = BMI_Unpack( bmiIn, bitsIn );
00749         return true;
00750     }
00751     return false;
00752 }

Here is the call graph for this function:

size_t BMI_MakeClut ( RGBQUAD *  dstlut,
size_t  cClut,
const BITMAPINFO *  bmi,
const void *  bits 
)

Build a color lookup table of a given size from true-color source pixels Truly an ugly and time-consuming ordeal, but this should make it "simple", or at least less horrible.

Parameters:
dstlut Buffer to receive color lookup table (sorted most to least popular)
cClut Maximum count of colors to match up
bmi BITMAPINFO we're generating a CLUT from
bits Bitmap data
Returns:
count of colors actually produced (<= clut)

Definition at line 462 of file bmp.c.

References BMI_Clut_AddColor(), BMI_Clut_Begin(), and BMI_Clut_Make().

00463 {
00464     BMIClut clutz;
00465     BMI_Clut_Begin( &clutz );
00466     {
00467         BMI_foreach( bmi, bits, pixel )
00468             BMI_Clut_AddColor( &clutz, pixel );
00469     }
00470     return BMI_Clut_Make( &clutz, dstlut, cClut );
00471 }

Here is the call graph for this function:

void BMI_OPC ( OPC opc,
const BITMAPINFO *  bmi,
void *  bits 
)

Convert bmi,bits to native OPC NOTE: Assumes OPC is same format as bmi,bits.

Parameters:
opc OPC to be filled in with data from bmi, bits
bmi BITMAPINFO describing size/format of data
bits Pointer to pixel data

Definition at line 20 of file bmp.c.

References Rect::bottom, OPC::clip, Rect::left, OPC::origin, OPC::pitch, Rect::right, and Rect::top.

00021 {
00022     OPC* out = (opc);
00023     const BITMAPINFO* bmin = (bmi);
00024     out->origin = (uint8*)BMI_Origin(bmin,bits);
00025     out->pitch = BMI_LineOffset(bmin);
00026     out->clip.left = out->clip.top = 0;
00027     out->clip.right = BMI_Wide(bmin);
00028     out->clip.bottom = BMI_High(bmin);
00029 }

bool BMI_ReadRow ( RGBQUAD *  pixel,
const BITMAPINFO *  bmi,
const void *  bits,
int  row 
)

Get color values from each pixel in a row of bmi/bits as an RGBQUAD Half of translation from one BMI format to another.

Parameters:
pixel Buffer to receive pixels, must have at least BMI_Wide(bmi) members
bmi bitmap header
bits bitmap content
row Row from bitmap to get data from
Returns:
true if data was actually read, false (and pixel buffer filled black) if not

Definition at line 100 of file bmp.c.

References assert.

Referenced by BMI_Translate().

00101 {
00102     /* Don't choke on bad row */
00103     assert(bmi);
00104     assert(bits);
00105     if( row < 0 || row >= BMI_High(bmi) || (bmi->bmiHeader.biCompression != BI_RGB && bmi->bmiHeader.biCompression != BI_BITFIELDS && bmi->bmiHeader.biCompression != BI_RLE4 && bmi->bmiHeader.biCompression != BI_RLE8) )
00106     {
00107         memset( pixel, 0, sizeof(RGBQUAD)*BMI_Wide(bmi) );
00108         return false;
00109     }
00110     switch( bmi->bmiHeader.biBitCount )
00111     {
00112     case 1:
00113         {
00114             const RGBQUAD* colors = BMI_ColorData(bmi);
00115             const uint8* pixels = (const uint8*)BMI_LinePtr(bmi,bits,row);
00116             int wordlen = BMI_Wide(bmi);
00117             while( wordlen )
00118             {
00119                 uint8 bit = 0x80;
00120                 while( bit && wordlen )
00121                 {
00122                     *pixel++ = colors[0 != (*pixels & bit)];
00123                     wordlen--;
00124                     bit >>= 1;
00125                 }
00126                 pixels++;
00127             }
00128         }
00129         return true;
00130 
00131     case 4:
00132         {
00133             const RGBQUAD* colors = BMI_ColorData(bmi);
00134             const uint8* pixels = (const uint8*)BMI_LinePtr(bmi,bits,row);
00135             int wordlen = BMI_Wide(bmi);
00136             int curr;
00137             for( curr = 0; curr < wordlen; ++curr )
00138             {
00139                 if( curr&1 )
00140                 {
00141                     *pixel++ = colors[*pixels&0xf];
00142                     pixels++;
00143                 }
00144                 else
00145                 {
00146                     *pixel++ = colors[(*pixels>>4)&0xf];
00147                 }
00148             }
00149         }
00150         return true;
00151 
00152     case 8:
00153         {
00154             const RGBQUAD* colors = BMI_ColorData(bmi);
00155             const uint8* pixels = (const uint8*)BMI_LinePtr(bmi,bits,row);
00156             int wordlen = BMI_Wide(bmi);
00157             while( wordlen-- )
00158                 *pixel++ = colors[*pixels++];
00159         }
00160         return true;
00161 
00162     case 16:
00163         if( bmi->bmiHeader.biCompression == BI_BITFIELDS )
00164         {
00165             const uint32* masks = (const uint32*)BMI_ColorData(bmi);
00166             uint16 mRed = (uint16)masks[0];
00167             uint16 mGreen = (uint16)masks[1];
00168             uint16 mBlue = (uint16)masks[2];
00169             int bRed = lsb(mRed);
00170             int bGreen = lsb(mGreen);
00171             int bBlue = lsb(mBlue);
00172             int nRed = nbits( mRed );
00173             int nGreen = nbits( mGreen );
00174             int nBlue = nbits( mBlue );
00175             const uint16* pixels = (const uint16*)BMI_LinePtr(bmi,bits,row);
00176             int wordlen = BMI_Wide(bmi);
00177             while( wordlen-- )
00178             {
00179                 pixel->rgbBlue = (uint8)(((mBlue & *pixels) >> bBlue) << (8-nBlue));
00180                 pixel->rgbGreen = (uint8)(((mGreen & *pixels) >> bGreen) << (8-nGreen));
00181                 pixel->rgbRed = (uint8)(((mRed & *pixels) >> bRed) << (8-nRed));
00182                 pixel->rgbReserved = 0;
00183                 pixel++;
00184                 pixels++;
00185             }
00186         }
00187         else
00188         {
00189             const uint16* pixels = (const uint16*)BMI_LinePtr(bmi,bits,row);
00190             int wordlen = BMI_Wide(bmi);
00191             while( wordlen-- )
00192             {
00193                 pixel->rgbBlue = (uint8)((*pixels & 0x1f) << 3);
00194                 pixel->rgbGreen = (uint8)(((*pixels >> 5) & 0x1f) << 3);
00195                 pixel->rgbRed = (uint8)(((*pixels >> 10) & 0x1f) << 3);
00196                 pixel->rgbReserved = 0;
00197                 pixels++;
00198                 pixel++;
00199             }
00200         }
00201         return true;
00202 
00203     case 24:
00204         {
00205             const uint8* pixels = (const uint8*)BMI_LinePtr(bmi,bits,row);
00206             int wordlen = BMI_Wide(bmi);
00207             while( wordlen-- )
00208             {
00209                 pixel->rgbBlue = *pixels++;
00210                 pixel->rgbGreen = *pixels++;
00211                 pixel->rgbRed = *pixels++;
00212                 pixel->rgbReserved = 0;
00213                 pixel++;
00214             }
00215         }
00216         return true;
00217 
00218     case 32:
00219         if( bmi->bmiHeader.biCompression == BI_BITFIELDS )
00220         {
00221             const uint32* masks = (const uint32*)BMI_ColorData(bmi);
00222             uint32 mRed = (uint32)masks[0];
00223             uint32 mGreen = (uint32)masks[1];
00224             uint32 mBlue = (uint32)masks[2];
00225             int bRed = lsb(mRed);
00226             int bGreen = lsb(mGreen);
00227             int bBlue = lsb(mBlue);
00228             int nRed = nbits( mRed );
00229             int nGreen = nbits( mGreen );
00230             int nBlue = nbits( mBlue );
00231             const uint32* pixels = (const uint32*)BMI_LinePtr(bmi,bits,row);
00232             int wordlen = BMI_Wide(bmi);
00233             while( wordlen-- )
00234             {
00235                 pixel->rgbBlue = (uint8)(((mBlue & *pixels) >> bBlue) << (8-nBlue));
00236                 pixel->rgbGreen = (uint8)(((mGreen & *pixels) >> bGreen) << (8-nGreen));
00237                 pixel->rgbRed = (uint8)(((mRed & *pixels) >> bRed) << (8-nRed));
00238                 pixel->rgbReserved = 0;
00239                 pixels++;
00240                 pixel++;
00241             }
00242         }
00243         else
00244         {
00245             const uint8* pixels = (const uint8*)BMI_LinePtr(bmi,bits,row);
00246             int wordlen = BMI_Wide(bmi);
00247             while( wordlen-- )
00248             {
00249                 pixel->rgbBlue = *pixels++;
00250                 pixel->rgbGreen = *pixels++;
00251                 pixel->rgbRed = *pixels++;
00252                 pixel->rgbReserved = 0;
00253                 pixel++;
00254                 pixels++;
00255             }
00256         }
00257         return true;
00258 
00259     default:
00260         break;
00261     }
00262     return false;
00263 }

bool BMI_Save ( const char *  path,
const BITMAPINFO *  bmi,
const void *  bits 
)

Save a bitmap.

Parameters:
path Path to write file to
bmi bitmap header
bits bitmap content

Definition at line 677 of file bmp.c.

References assert.

00678 {
00679     /*
00680      * TODO: Replace with target independent code
00681      */
00682     /* Save BMI/bits as a BITMAP */
00683     FILE *fp = fopen( path, "wb" );
00684     assert( bmi );
00685     assert( bits );
00686     assert( bmi->bmiHeader.biWidth > 0 );
00687     assert( bmi->bmiHeader.biHeight );
00688     if( fp )
00689     {
00690         BITMAPFILEHEADER bmf;
00691         bmf.bfType = *((uint16 *)"BM");
00692         bmf.bfSize = sizeof(bmf) + BMI_BMI_Size(bmi) + BMI_BitmapSize(bmi);
00693         bmf.bfReserved1 = 0;
00694         bmf.bfReserved2 = 0;
00695         bmf.bfOffBits = sizeof(bmf) + BMI_BMI_Size(bmi);
00696         if( 1 != fwrite( &bmf, sizeof(bmf), 1, fp ) )
00697         {
00698             fclose( fp );
00699             return false;
00700         }
00701         {
00702             /* Tell it form is 'rightside up' */
00703             BITMAPINFO *bmiScratch = BMI_Alloc();
00704             memcpy( bmiScratch, bmi, BMI_BMI_Size(bmi) );
00705             bmiScratch->bmiHeader.biHeight = abs(bmiScratch->bmiHeader.biHeight);
00706             if( 1 != fwrite( bmiScratch, BMI_BMI_Size(bmiScratch), 1, fp ) )
00707             {
00708                 fclose( fp );
00709                 return false;
00710             }
00711             BMI_Free(bmiScratch);
00712         }
00713         {
00714             /* Always write image upside-down */
00715             int line = BMI_High(bmi);
00716             while( line-- )
00717             {
00718                 if( 1 != fwrite( BMI_LinePtr(bmi,bits,line), BMI_LineSize(bmi), 1, fp ) )
00719                     break;
00720             }
00721         }
00722         fclose( fp );
00723         return true;
00724     }
00725     return false;
00726 }

void BMI_Translate ( const BITMAPINFO *  dst,
void *  bdst,
const BITMAPINFO *  src,
const void *  bsrc 
)

Copy/Translate src bitmap to target bitmap.

Parameters:
dst Destination bitmap definition
bdst Destination bitmap data
src Source bitmap definition
bsrc Source bitmap data

Definition at line 560 of file bmp.c.

References BMI_ReadRow(), and BMI_WriteRow().

00561 {
00562     RGBQUAD* colors = (RGBQUAD*)malloc( sizeof(RGBQUAD) * max(BMI_Wide(dst),BMI_Wide(src)) );
00563     int rowCurr = min( BMI_High(dst), BMI_High(src) );
00564     while( rowCurr-- )
00565     {
00566         BMI_ReadRow( colors, src, bsrc, rowCurr );
00567         BMI_WriteRow( dst, bdst, colors, rowCurr );
00568     }
00569     free(colors);
00570 }

Here is the call graph for this function:

void* BMI_Unpack ( const BITMAPINFO *  bmi,
const void *  bits 
)

Unpack certain BMP formats.

Parameters:
bmi Describes BMP format
bits (Presumably) packed source data
Returns:
New (unpacked) image, and modifies bmi to 'unpacked' version, or NULL if unmodified/unhandled

Definition at line 579 of file bmp.c.

Referenced by BMI_Load().

00580 {
00581     switch( bmi->bmiHeader.biCompression )
00582     {
00583     default:
00584     case BI_BITFIELDS:
00585     case BI_RGB:
00586         return NULL;
00587 
00588     case BI_RLE4:
00589     case BI_RLE8:
00590         {
00591             size_t current = BMI_BitmapSize(bmi);
00592             size_t lineSize = BMI_LineSize(bmi);
00593             size_t needs = lineSize * BMI_High(bmi);
00594             void* ret = malloc(needs);
00595             const uint8* pSrc = (const uint8*)bits;
00596             const uint8* pEnd = pSrc + current;
00597             uint8* pDstEdge = (uint8*)ret;
00598             uint8* pDst = pDstEdge;
00599             const uint8* pdEnd = pDst + needs;
00600             while( pSrc < pEnd )
00601             {
00602                 int count = *pSrc++;
00603                 if( count )
00604                 {
00605                     uint8 fill = *pSrc++;
00606                     count = min(count,(int)(pdEnd-pDst));
00607                     if( bmi->bmiHeader.biCompression == BI_RLE8 )
00608                     {
00609                         memset( pDst, fill, count );
00610                         pDst += count;
00611                     }
00612                     else
00613                     {
00614                         count>>=1;
00615                         memset( pDst, fill, count );
00616                         pDst += count;
00617                     }
00618                 }
00619                 else /* Escape */
00620                 {
00621                     count = *pSrc++;    /* Get code */
00622                     if( count == 0 )
00623                     {
00624                         pDst = pDstEdge += lineSize;
00625                     }
00626                     else if( count == 1 )
00627                         break;
00628                     else if( count == 2 )
00629                     {
00630                         int x = *pSrc++;
00631                         int y = *pSrc++;
00632                         pDstEdge += (lineSize*y);
00633                         pDst = pDstEdge + x;
00634                     }
00635                     else
00636                     {
00637                         count = min(count,(int)(pdEnd-pDst));
00638                         count = min(count,(int)(pEnd-pSrc));
00639                         if( bmi->bmiHeader.biCompression == BI_RLE4 )
00640                         {
00641                             memcpy( pDst, pSrc, count>>1 );
00642                             pDst += count>>1;
00643                             pSrc += count;
00644                         }
00645                         else
00646                         {
00647                             memcpy( pDst, pSrc, count );
00648                             pDst += count;
00649                             pSrc += count;
00650                         }
00651                         /* Read mysterious excess byte */
00652                         if( bmi->bmiHeader.biCompression == BI_RLE8 )
00653                         {
00654                             if( count & 1 )
00655                                 pSrc++;
00656                         }
00657                         else
00658                         {
00659                             if( (count & 3) == 1 || (count & 3) == 2 )
00660                                 pSrc++;
00661                         }
00662                     }
00663                 }
00664             }
00665             return ret;
00666         }
00667         break;
00668     }
00669 }

bool BMI_WriteRow ( const BITMAPINFO *  bmi,
void *  bits,
const RGBQUAD *  pixel,
int  row 
)

Set color values from a line of RGBQUADs to whatever format map Half of translation from one BMI format to another

Parameters:
pixel Buffer containing colors to write, must have at least BMI_Wide(bmi) members
bmi bitmap header
bits bitmap content
row Row in bitmap to put data in
Returns:
true if data was actually written, false if not

Definition at line 275 of file bmp.c.

References assert, and RGBQUAD_Nearest().

Referenced by BMI_Translate().

00276 {
00277     /* Don't choke on bad row */
00278     assert(bmi);
00279     assert(bits);
00280     if( row < 0 || row >= BMI_High(bmi) || (bmi->bmiHeader.biCompression != BI_RGB && bmi->bmiHeader.biCompression != BI_BITFIELDS) )
00281     {
00282         return false;
00283     }
00284     switch( bmi->bmiHeader.biBitCount )
00285     {
00286     case 1:
00287         {
00288             /* 1 bit color indexes */
00289             const RGBQUAD* colors = BMI_ColorData(bmi);
00290             uint8* pixels = (uint8*)BMI_LinePtr(bmi,bits,row);
00291             int wordlen = BMI_Wide(bmi);
00292             while( wordlen )
00293             {
00294                 uint8 bit = 0x80;
00295                 *pixels = 0;
00296                 while( bit && wordlen )
00297                 {
00298                     if( RGBQUAD_Nearest( colors, 2, pixel++ ) )
00299                         *pixels |= bit;
00300                     bit>>=1;
00301                     wordlen--;
00302                 }
00303                 pixels++;
00304             }
00305         }
00306         return true;
00307 
00308     case 4:
00309         {
00310             const RGBQUAD* colors = BMI_ColorData(bmi);
00311             uint8* pixels = (uint8*)BMI_LinePtr(bmi,bits,row);
00312             int wordlen = BMI_Wide(bmi);
00313             int curr;
00314             for( curr = 0; curr < wordlen; ++curr )
00315             {
00316                 unsigned index = (unsigned)RGBQUAD_Nearest( colors, 16, pixel++ );
00317                 if( wordlen & 1 )
00318                     *pixels++ = (uint8)index;
00319                 else
00320                     *pixels |= (uint8)(index<<4);
00321             }
00322         }
00323         return true;
00324 
00325     case 8:
00326         {
00327             /* 8 bit color indexes */
00328             const RGBQUAD* colors = BMI_ColorData(bmi);
00329             uint8* pixels = (uint8*)BMI_LinePtr(bmi,bits,row);
00330             int wordlen = BMI_Wide(bmi);
00331             while( wordlen-- )
00332                 *pixels++ = (uint8)RGBQUAD_Nearest( colors, 256, pixel++ );
00333         }
00334         return true;
00335 
00336     case 16:
00337         if( bmi->bmiHeader.biCompression == BI_BITFIELDS )
00338         {
00339             /* 16 bit masks */
00340             const uint32* masks = (const uint32*)BMI_ColorData(bmi);
00341             uint16 mRed = (uint16)masks[0];
00342             uint16 mGreen = (uint16)masks[1];
00343             uint16 mBlue = (uint16)masks[2];
00344             int bRed = lsb(mRed);
00345             int bGreen = lsb(mGreen);
00346             int bBlue = lsb(mBlue);
00347             int nRed = nbits( mRed );
00348             int nGreen = nbits( mGreen );
00349             int nBlue = nbits( mBlue );
00350             uint16* pixels = (uint16*)BMI_LinePtr(bmi,bits,row);
00351             int wordlen = BMI_Wide(bmi);
00352             while( wordlen-- )
00353             {
00354                 *pixels = 0;
00355                 *pixels |= (((uint16)pixel->rgbBlue & ((1<<nBlue)-1)) >> (8-nBlue)) << bBlue;
00356                 *pixels |= (((uint16)pixel->rgbGreen & ((1<<nGreen)-1)) >> (8-nGreen)) << bGreen;
00357                 *pixels |= (((uint16)pixel->rgbRed & ((1<<nRed)-1)) >> (8-nRed)) << bRed;
00358                 pixel++;
00359                 pixels++;
00360             }
00361         }
00362         else
00363         {
00364             /* lsb 5 bits of blue, green, red, msb=0 */
00365             uint16* pixels = (uint16*)BMI_LinePtr(bmi,bits,row);
00366             int wordlen = BMI_Wide(bmi);
00367             while( wordlen-- )
00368             {
00369                 *pixels = 0;
00370                 *pixels |= ((uint16)pixel->rgbBlue & 0xf8) >> 3;
00371                 *pixels |= ((uint16)pixel->rgbGreen & 0xf8) << 2;
00372                 *pixels |= ((uint16)pixel->rgbRed & 0xf8) << 7;
00373                 pixels++;
00374                 pixel++;
00375             }
00376         }
00377         return true;
00378 
00379     case 24:
00380         {
00381             /* 24 bits of blue,green,red */
00382             uint8* pixels = (uint8*)BMI_LinePtr(bmi,bits,row);
00383             int wordlen = BMI_Wide(bmi);
00384             while( wordlen-- )
00385             {
00386                 *pixels++ = pixel->rgbBlue;
00387                 *pixels++ = pixel->rgbGreen;
00388                 *pixels++ = pixel->rgbRed;
00389                 pixel++;
00390             }
00391         }
00392         return true;
00393 
00394     case 32:
00395         if( bmi->bmiHeader.biCompression == BI_BITFIELDS )
00396         {
00397             /* 32 bit masks */
00398             const uint32* masks = (const uint32*)BMI_ColorData(bmi);
00399             uint32 mRed = (uint32)masks[0];
00400             uint32 mGreen = (uint32)masks[1];
00401             uint32 mBlue = (uint32)masks[2];
00402             int bRed = lsb(mRed);
00403             int bGreen = lsb(mGreen);
00404             int bBlue = lsb(mBlue);
00405             int nRed = nbits( mRed );
00406             int nGreen = nbits( mGreen );
00407             int nBlue = nbits( mBlue );
00408             uint32* pixels = (uint32*)BMI_LinePtr(bmi,bits,row);
00409             int wordlen = BMI_Wide(bmi);
00410             while( wordlen-- )
00411             {
00412                 *pixels = 0;
00413                 *pixels |= (((uint32)pixel->rgbBlue & ((1<<nBlue)-1)) >> (8-nBlue)) << bBlue;
00414                 *pixels |= (((uint32)pixel->rgbGreen & ((1<<nGreen)-1)) >> (8-nGreen)) << bGreen;
00415                 *pixels |= (((uint32)pixel->rgbRed & ((1<<nRed)-1)) >> (8-nRed)) << bRed;
00416                 pixel++;
00417                 pixels++;
00418             }
00419         }
00420         else
00421         {
00422             /* Default is 8 bits each of blue, green, red */
00423             uint8* pixels = (uint8*)BMI_LinePtr(bmi,bits,row);
00424             int wordlen = BMI_Wide(bmi);
00425             while( wordlen-- )
00426             {
00427                 *pixels++ = pixel->rgbBlue;
00428                 *pixels++ = pixel->rgbGreen;
00429                 *pixels++ = pixel->rgbRed;
00430                 *pixels++ = 0;
00431                 pixel++;
00432             }
00433         }
00434         return true;
00435 
00436     default:
00437         break;
00438     }
00439     return false;
00440 }

Here is the call graph for this function:


Generated on Fri Jan 2 15:28:35 2009 for Squat by  doxygen 1.5.6