Question

This is some of my bitmask code (monochrome bitmaps). There is no problem with the Bitmask_Create() function. I have tested it with opening, loading and saving windows monochrome bitmaps, and it works great. However, the GetPixel and SetPixel functions I've made don't seem to work right. In some instances they seem to work fine depending on the bitmap dimensions.

If anyone could help, I would appreciate it. It's driving me insane. Thanks.

typedef struct _GL_BITMASK GL_BITMASK;
struct _GL_BITMASK {
    int nWidth; // Width in pixels
    int nHeight; // Height in pixels
    int nPitch; // Width of scanline in bytes (may have extra padding to align to DWORD)
    BYTE *pData; // Pointer to the first byte of the first scanline (top down)
};

int BitMask_GetPixel(GL_BITMASK *pBitMask, int x, int y)
{
    INT nElement = ((y * pBitMask->nPitch) + (x / 8));
    PBYTE pElement = pBitMask->pData + nElement;
    BYTE bMask = 1 << (7 - (x % 8));

    return *pElement & bMask;
}

void BitMask_SetPixel(GL_BITMASK *pBitMask, int x, int y, int nPixelColor)
{
    INT nElement = x / 8;
    INT nScanLineOffset = y * pBitMask->nPitch;
    PBYTE pElement = pBitMask->pData + nScanLineOffset + nElement;
    BYTE bMask = 1 << (7 - (x % 8));

    if(*pElement & bMask)
    {
        if(!nPixelColor) return;
        else *pElement ^= bMask;
    }
    else
    {
        if(nPixelColor) return;
        else *pElement |= bMask;
    }
}

GL_BITMASK *BitMask_Create(INT nWidth, INT nHeight)
{
    GL_BITMASK *pBitMask;
    int nPitch;

    nPitch = ((nWidth / 8) + 3) & ~3;

    pBitMask = (GL_BITMASK *)GlobalAlloc(GMEM_FIXED, (nPitch * nHeight) + sizeof(GL_BITMASK));
    if(!pBitMask) 
        return (GL_BITMASK *)NULL;

    pBitMask->nPitch = nPitch;
    pBitMask->nWidth = nWidth;
    pBitMask->nHeight = nHeight;
    pBitMask->pData = (PBYTE)pBitMask + sizeof(GL_BITMASK);

    return pBitMask;
}
Was it helpful?

Solution

I think your formula for calculating pitch is just a little bit off. It works when the width is a multiple of 8, but not otherwise. Try:

nPitch = ((nWidth + 31) / 8) & ~3;

OTHER TIPS

I figured it out... I had the two tests backwards for nPixelColor in SetPixel()

if(*pElement & bMask)
{
    if(nPixelColor) return; // this was !nPixelColor
    else *pElement ^= bMask;
}
else
{
    if(!nPixelColor) return; // this was nPixelColor
    else *pElement |= bMask;
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top