Back to index

lightning-sunbird  0.9+nobinonly
Public Member Functions | Private Member Functions | Static Private Member Functions | Private Attributes
nsBMPDecoder Class Reference

Decoder for BMP-Files, as used by Windows and OS/2. More...

#include <nsBMPDecoder.h>

Inheritance diagram for nsBMPDecoder:
Inheritance graph
[legend]
Collaboration diagram for nsBMPDecoder:
Collaboration graph
[legend]

List of all members.

Public Member Functions

NS_DECL_ISUPPORTS
NS_DECL_IMGIDECODER 
nsBMPDecoder ()
 ~nsBMPDecoder ()
void init (in imgILoad aLoad)
 Initalize an image decoder.
void close ()
 Closes the stream.
void flush ()
 Flushes the stream.
unsigned long writeFrom (in nsIInputStream inStr, in unsigned long count)
 Writes data into the stream from an input stream.

Private Member Functions

NS_METHOD ProcessData (const char *aBuffer, PRUint32 aCount)
 Processes the data.
NS_METHOD CalcBitShift ()
 Calculates the red-, green- and blueshift in mBitFields using the bitmasks from mBitFields.
nsresult SetData ()
 Sets the image data.
nsresult WriteRLERows (PRUint32 rows)
 Sets the rle data.
void ProcessFileHeader ()
 Set mBFH from the raw data in mRawBuf, converting from little-endian data to native data as necessary.
void ProcessInfoHeader ()
 Set mBIH from the raw data in mRawBuf, converting from little-endian data to native data as necessary.

Static Private Member Functions

static NS_METHOD ReadSegCb (nsIInputStream *aIn, void *aClosure, const char *aFromRawSegment, PRUint32 aToOffset, PRUint32 aCount, PRUint32 *aWriteCount)
 Callback for ReadSegments to avoid copying the data.

Private Attributes

nsCOMPtr< imgIDecoderObservermObserver
nsCOMPtr< imgIContainermImage
nsCOMPtr< gfxIImageFramemFrame
PRUint32 mPos
BMPFILEHEADER mBFH
BMPINFOHEADER mBIH
char mRawBuf [36]
PRUint32 mLOH
 Length of the header.
PRUint32 mNumColors
 The number of used colors, i.e. the number of entries in mColors.
colorTablemColors
bitFields mBitFields
PRUint8mRow
 Holds one raw line of the image.
PRUint32 mRowBytes
 How many bytes of the row were already received.
PRInt32 mCurLine
 Index of the line of the image that's currently being decoded.
PRUint8mAlpha
 Holds one line of unpacked alpha data.
PRUint8mAlphaPtr
 Pointer within unpacked alpha data.
PRUint8mDecoded
 Holds one line of color image data.
PRUint8mDecoding
 Pointer within image data.
ERLEState mState
 Maintains the current state of the RLE decoding.
PRUint32 mStateData
 Decoding information that is needed depending on mState.
PRUint32 mBpr
 Cached image bytes per row.

Detailed Description

Decoder for BMP-Files, as used by Windows and OS/2.

Definition at line 158 of file nsBMPDecoder.h.


Constructor & Destructor Documentation

Definition at line 61 of file nsBMPDecoder.cpp.

{
    mColors = nsnull;
    mRow = nsnull;
    mPos = mNumColors = mRowBytes = 0;
    mCurLine = 1; // Otherwise decoder will never start
    mState = eRLEStateInitial;
    mStateData = 0;
    mAlpha = mAlphaPtr = mDecoded = mDecoding = nsnull;
    mLOH = WIN_HEADER_LENGTH;
}

Definition at line 73 of file nsBMPDecoder.cpp.

{
    delete[] mColors;
    free(mRow);
    if (mAlpha)
        free(mAlpha);
    if (mDecoded)
        free(mDecoded);
}

Member Function Documentation

Calculates the red-, green- and blueshift in mBitFields using the bitmasks from mBitFields.

Definition at line 199 of file nsBMPDecoder.cpp.

{
    PRUint8 begin, length;
    // red
    calcBitmask(mBitFields.red, begin, length);
    mBitFields.redRightShift = begin;
    mBitFields.redLeftShift = 8 - length;
    // green
    calcBitmask(mBitFields.green, begin, length);
    mBitFields.greenRightShift = begin;
    mBitFields.greenLeftShift = 8 - length;
    // blue
    calcBitmask(mBitFields.blue, begin, length);
    mBitFields.blueRightShift = begin;
    mBitFields.blueLeftShift = 8 - length;
    return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void imgIDecoder::close ( ) [inherited]

Closes the stream.

void imgIDecoder::flush ( ) [inherited]

Flushes the stream.

void imgIDecoder::init ( in imgILoad  aLoad) [inherited]

Initalize an image decoder.

Parameters:
aRequestthe request that owns the decoder.
Note:
The decode should QI aLoad to an imgIDecoderObserver and should send decoder notifications to the request. The decoder should always pass NULL as the first two parameters to all of the imgIDecoderObserver APIs.
NS_METHOD nsBMPDecoder::ProcessData ( const char *  aBuffer,
PRUint32  aCount 
) [private]

Processes the data.

Parameters:
aBufferData to process. count Number of bytes in mBuffer

Definition at line 217 of file nsBMPDecoder.cpp.

{
    PR_LOG(gBMPLog, PR_LOG_DEBUG, ("nsBMPDecoder::ProcessData(%p, %lu)", aBuffer, aCount));
    if (!aCount || !mCurLine) // aCount=0 means EOF, mCurLine=0 means we're past end of image
        return NS_OK;

    nsresult rv;
    if (mPos < BFH_LENGTH) { /* In BITMAPFILEHEADER */
        PRUint32 toCopy = BFH_LENGTH - mPos;
        if (toCopy > aCount)
            toCopy = aCount;
        memcpy(mRawBuf + mPos, aBuffer, toCopy);
        mPos += toCopy;
        aCount -= toCopy;
        aBuffer += toCopy;
    }
    if (mPos == BFH_LENGTH) {
        rv = mObserver->OnStartDecode(nsnull);
        NS_ENSURE_SUCCESS(rv, rv);
        ProcessFileHeader();
        if (mBFH.signature[0] != 'B' || mBFH.signature[1] != 'M')
            return NS_ERROR_FAILURE;
        if (mBFH.bihsize == OS2_BIH_LENGTH)
            mLOH = OS2_HEADER_LENGTH;
    }
    if (mPos >= BFH_LENGTH && mPos < mLOH) { /* In BITMAPINFOHEADER */
        PRUint32 toCopy = mLOH - mPos;
        if (toCopy > aCount)
            toCopy = aCount;
        memcpy(mRawBuf + (mPos - BFH_LENGTH), aBuffer, toCopy);
        mPos += toCopy;
        aCount -= toCopy;
        aBuffer += toCopy;
    }
    if (mPos == mLOH) {
        ProcessInfoHeader();
        PR_LOG(gBMPLog, PR_LOG_DEBUG, ("BMP image is %lix%lix%lu. compression=%lu\n",
            mBIH.width, mBIH.height, mBIH.bpp, mBIH.compression));
        // Verify we support this bit depth
        if (mBIH.bpp != 1 && mBIH.bpp != 4 && mBIH.bpp != 8 &&
            mBIH.bpp != 16 && mBIH.bpp != 24 && mBIH.bpp != 32)
          return NS_ERROR_UNEXPECTED;

        if (mBIH.bpp <= 8) {
            mNumColors = 1 << mBIH.bpp;
            if (mBIH.colors && mBIH.colors < mNumColors)
                mNumColors = mBIH.colors;

            // Always allocate 256 even though mNumColors might be smaller
            mColors = new colorTable[256];
            if (!mColors)
                return NS_ERROR_OUT_OF_MEMORY;

            memset(mColors, 0, 256 * sizeof(colorTable));
        }
        else if (mBIH.compression != BI_BITFIELDS && mBIH.bpp == 16) {
            // Use default 5-5-5 format
            mBitFields.red   = 0x7C00;
            mBitFields.green = 0x03E0;
            mBitFields.blue  = 0x001F;
            CalcBitShift();
        }
        // BMPs with negative width are invalid
        // Reject extremely wide images to keep the math sane
        const PRInt32 k64KWidth = 0x0000FFFF;
        if (mBIH.width < 0 || mBIH.width > k64KWidth)
            return NS_ERROR_FAILURE;

        PRUint32 real_height = (mBIH.height > 0) ? mBIH.height : -mBIH.height;
        rv = mImage->Init(mBIH.width, real_height, mObserver);
        NS_ENSURE_SUCCESS(rv, rv);
        rv = mObserver->OnStartContainer(nsnull, mImage);
        NS_ENSURE_SUCCESS(rv, rv);
        mCurLine = real_height;

        mRow = (PRUint8*)malloc((mBIH.width * mBIH.bpp)/8 + 4);
        // +4 because the line is padded to a 4 bit boundary, but I don't want
        // to make exact calculations here, that's unnecessary.
        // Also, it compensates rounding error.
        if (!mRow) {
            return NS_ERROR_OUT_OF_MEMORY;
        }
        if ((mBIH.compression == BI_RLE8) || (mBIH.compression == BI_RLE4)) {
            rv = mFrame->Init(0, 0, mBIH.width, real_height, RLE_GFXFORMAT_ALPHA, 24);
        } else {
            rv = mFrame->Init(0, 0, mBIH.width, real_height, BMP_GFXFORMAT, 24);
        }
        NS_ENSURE_SUCCESS(rv, rv);
        rv = mImage->AppendFrame(mFrame);
        NS_ENSURE_SUCCESS(rv, rv);
        mObserver->OnStartFrame(nsnull, mFrame);
        NS_ENSURE_SUCCESS(rv, rv);
        rv = mFrame->GetImageBytesPerRow(&mBpr);
        NS_ENSURE_SUCCESS(rv, rv);
    }
    PRUint8 bpc; // bytes per color
    bpc = (mBFH.bihsize == OS2_BIH_LENGTH) ? 3 : 4; // OS/2 Bitmaps have no padding byte
    if (mColors && (mPos >= mLOH && (mPos < (mLOH + mNumColors * bpc)))) {
        // We will receive (mNumColors * bpc) bytes of color data
        PRUint32 colorBytes = mPos - mLOH; // Number of bytes already received
        PRUint8 colorNum = colorBytes / bpc; // Color which is currently received
        PRUint8 at = colorBytes % bpc;
        while (aCount && (mPos < (mLOH + mNumColors * bpc))) {
            switch (at) {
                case 0:
                    mColors[colorNum].blue = *aBuffer;
                    break;
                case 1:
                    mColors[colorNum].green = *aBuffer;
                    break;
                case 2:
                    mColors[colorNum].red = *aBuffer;
                    colorNum++;
                    break;
                case 3:
                    // This is a padding byte
                    break;
            }
            mPos++; aBuffer++; aCount--;
            at = (at + 1) % bpc;
        }
    }
    else if (aCount && mBIH.compression == BI_BITFIELDS && mPos < (WIN_HEADER_LENGTH + BITFIELD_LENGTH)) {
        // If compression is used, this is a windows bitmap, hence we can
        // use WIN_HEADER_LENGTH instead of mLOH
        PRUint32 toCopy = (WIN_HEADER_LENGTH + BITFIELD_LENGTH) - mPos;
        if (toCopy > aCount)
            toCopy = aCount;
        memcpy(mRawBuf + (mPos - WIN_HEADER_LENGTH), aBuffer, toCopy);
        mPos += toCopy;
        aBuffer += toCopy;
        aCount -= toCopy;
    }
    if (mBIH.compression == BI_BITFIELDS && mPos == WIN_HEADER_LENGTH + BITFIELD_LENGTH) {
        mBitFields.red = LITTLE_TO_NATIVE32(*(PRUint32*)mRawBuf);
        mBitFields.green = LITTLE_TO_NATIVE32(*(PRUint32*)(mRawBuf + 4));
        mBitFields.blue = LITTLE_TO_NATIVE32(*(PRUint32*)(mRawBuf + 8));
        CalcBitShift();
    }
    while (aCount && (mPos < mBFH.dataoffset)) { // Skip whatever is between header and data
        mPos++; aBuffer++; aCount--;
    }
    if (aCount && ++mPos >= mBFH.dataoffset) {
        // Need to increment mPos, else we might get to mPos==mLOH again
        // From now on, mPos is irrelevant
        if (!mBIH.compression || mBIH.compression == BI_BITFIELDS) {
            PRUint32 rowSize = (mBIH.bpp * mBIH.width + 7) / 8; // +7 to round up
            if (rowSize % 4)
                rowSize += (4 - (rowSize % 4)); // Pad to DWORD Boundary
            PRUint32 toCopy;
            do {
                toCopy = rowSize - mRowBytes;
                if (toCopy) {
                    if (toCopy > aCount)
                        toCopy = aCount;
                    memcpy(mRow + mRowBytes, aBuffer, toCopy);
                    aCount -= toCopy;
                    aBuffer += toCopy;
                    mRowBytes += toCopy;
                }
                if ((rowSize - mRowBytes) == 0) {
                    if (!mDecoded) {
                        mDecoded = (PRUint8*)malloc(mBpr);
                        if (!mDecoded)
                            return NS_ERROR_OUT_OF_MEMORY;
                    }

                    PRUint8* p = mRow;
                    PRUint8* d = mDecoded;
                    PRUint32 lpos = mBIH.width;
                    switch (mBIH.bpp) {
                      case 1:
                        while (lpos > 0) {
                          PRInt8 bit;
                          PRUint8 idx;
                          for (bit = 7; bit >= 0 && lpos > 0; bit--) {
                              idx = (*p >> bit) & 1;
                              SetPixel(d, idx, mColors);
                              --lpos;
                          }
                          ++p;
                        }
                        break;
                      case 4:
                        while (lpos > 0) {
                          Set4BitPixel(d, *p, lpos, mColors);
                          ++p;
                        }
                        break;
                      case 8:
                        while (lpos > 0) {
                          SetPixel(d, *p, mColors);
                          --lpos;
                          ++p;
                        }
                        break;
                      case 16:
                        while (lpos > 0) {
                          PRUint16 val = LITTLE_TO_NATIVE16(*(PRUint16*)p);
                          SetPixel(d,
                                  (val & mBitFields.red) >> mBitFields.redRightShift << mBitFields.redLeftShift,
                                  (val & mBitFields.green) >> mBitFields.greenRightShift << mBitFields.greenLeftShift,
                                  (val & mBitFields.blue) >> mBitFields.blueRightShift << mBitFields.blueLeftShift);
                          --lpos;
                          p+=2;
                        }
                        break;
                      case 32:
                      case 24:
                        while (lpos > 0) {
                          SetPixel(d, p[2], p[1], p[0]);
                          p += 2;
                          --lpos;
                          if (mBIH.bpp == 32)
                            p++; // Padding byte
                          ++p;
                        }
                        break;
                      default:
                        NS_NOTREACHED("Unsupported color depth, but earlier check didn't catch it");
                    }
                      
                    nsresult rv = SetData();
                    NS_ENSURE_SUCCESS(rv, rv);

                    if (mCurLine == 0) { // Finished last line
                        return mObserver->OnStopFrame(nsnull, mFrame);
                    }
                    mRowBytes = 0;

                }
            } while (aCount > 0);
        } 
        else if ((mBIH.compression == BI_RLE8) || (mBIH.compression == BI_RLE4)) {
            if (((mBIH.compression == BI_RLE8) && (mBIH.bpp != 8)) 
             || ((mBIH.compression == BI_RLE4) && (mBIH.bpp != 4) && (mBIH.bpp != 1))) {
                PR_LOG(gBMPLog, PR_LOG_DEBUG, ("BMP RLE8/RLE4 compression only supports 8/4 bits per pixel\n"));
                return NS_ERROR_FAILURE;
            }

            if (!mAlpha) {
                PRUint32 alpha;
                rv = mFrame->GetAlphaBytesPerRow(&alpha);
                NS_ENSURE_SUCCESS(rv, rv);
                // Allocate an unpacked buffer
                mAlpha = (PRUint8*)calloc(alpha, 8);
                if (!mAlpha)
                  return NS_ERROR_OUT_OF_MEMORY;
                mAlphaPtr = mAlpha;
            }

            if (!mDecoded) {
                mDecoded = (PRUint8*)calloc(mBpr, 1);
                if (!mDecoded)
                  return NS_ERROR_OUT_OF_MEMORY;
                mDecoding = mDecoded;
            }

            while (aCount > 0) {
                PRUint8 byte;

                switch(mState) {
                    case eRLEStateInitial:
                        mStateData = (PRUint8)*aBuffer++;
                        aCount--;

                        mState = eRLEStateNeedSecondEscapeByte;
                        continue;

                    case eRLEStateNeedSecondEscapeByte:
                        byte = *aBuffer++;
                        aCount--;
                        if (mStateData != RLE_ESCAPE) { // encoded mode
                            // Encoded mode consists of two bytes: 
                            // the first byte (mStateData) specifies the
                            // number of consecutive pixels to be drawn 
                            // using the color index contained in
                            // the second byte
                            // Work around bitmaps that specify too many pixels
                            if (mAlphaPtr + mStateData > mAlpha + mBIH.width)
                                mStateData = (PRUint32)(mAlpha + mBIH.width - mAlphaPtr);
                            memset(mAlphaPtr, 0xFF, mStateData);
                            mAlphaPtr += mStateData;
                            if (mBIH.compression == BI_RLE8) {
                                while (mStateData > 0) {
                                    SetPixel(mDecoding, byte, mColors);
                                    mStateData--;
                                }
                            } else {
                                while (mStateData > 0) {
                                    Set4BitPixel(mDecoding, byte, mStateData, mColors);
                                }
                            }
                            
                            mState = eRLEStateInitial;
                            continue;
                        }

                        switch(byte) {
                            case RLE_ESCAPE_EOL:
                                // End of Line: Write out current row
                                // and reset our row buffer
                                rv = WriteRLERows(1);
                                NS_ENSURE_SUCCESS(rv, rv);
                                mAlphaPtr = mAlpha;
                                mDecoding = mDecoded;

                                mState = eRLEStateInitial;
                                break;

                            case RLE_ESCAPE_EOF: // EndOfFile
                                rv = WriteRLERows(mCurLine);
                                NS_ENSURE_SUCCESS(rv, rv);
                                break;

                            case RLE_ESCAPE_DELTA:
                                mState = eRLEStateNeedXDelta;
                                continue;

                            default : // absolute mode
                                // Save the number of pixels to read
                                mStateData = byte;
                                if (mAlphaPtr + mStateData > mAlpha + mBIH.width) {
                                    // We can work around bitmaps that specify one
                                    // pixel too many, but only if their width is odd.
                                    mStateData -= mBIH.width & 1;
                                    if (mAlphaPtr + mStateData > mAlpha + mBIH.width)
                                        return NS_ERROR_FAILURE;
                                }
                                memset(mAlphaPtr, 0xFF, mStateData);
                                mAlphaPtr += mStateData;

                                // See if we will need to skip a byte
                                // to word align the pixel data
                                // mStateData is a number of pixels
                                // so allow for the RLE compression type
                                // Pixels RLE8=1 RLE4=2
                                //    1    Pad    Pad
                                //    2    No     Pad
                                //    3    Pad    No
                                //    4    No     No
                                if (((mStateData - 1) & mBIH.compression) != 0)
                                    mState = eRLEStateAbsoluteMode;
                                else
                                    mState = eRLEStateAbsoluteModePadded;
                                continue;
                        }
                        break;

                    case eRLEStateNeedXDelta:
                        // Handle the XDelta and proceed to get Y Delta
                        byte = *aBuffer++;
                        aCount--;
                        mAlphaPtr += byte;
                        if (mAlphaPtr > mAlpha + mBIH.width)
                            mAlphaPtr = mAlpha + mBIH.width;
                        mDecoding += byte * GFXBYTESPERPIXEL;

                        mState = eRLEStateNeedYDelta;
                        continue;

                    case eRLEStateNeedYDelta:
                        // Get the Y Delta and then "handle" the move
                        byte = *aBuffer++;
                        aCount--;
                        mState = eRLEStateInitial;
                        if (byte == 0)
                            continue; // Nothing more to do

                        rv = WriteRLERows(PR_MIN(byte, mCurLine));
                        NS_ENSURE_SUCCESS(rv, rv);
                        break;

                    case eRLEStateAbsoluteMode: // Absolute Mode
                    case eRLEStateAbsoluteModePadded:
                        // In absolute mode, the second byte (mStateData)
                        // represents the number of pixels 
                        // that follow, each of which contains 
                        // the color index of a single pixel.
                        if (mBIH.compression == BI_RLE8) {
                            while (aCount > 0 && mStateData > 0) {
                                byte = *aBuffer++;
                                aCount--;
                                SetPixel(mDecoding, byte, mColors);
                                mStateData--;
                            }
                        } else {
                            while (aCount > 0 && mStateData > 0) {
                                byte = *aBuffer++;
                                aCount--;
                                Set4BitPixel(mDecoding, byte, mStateData, mColors);
                            }
                        }

                        if (mStateData == 0) {
                            // In absolute mode, each run must 
                            // be aligned on a word boundary

                            if (mState == eRLEStateAbsoluteMode) { // Word Aligned
                                mState = eRLEStateInitial;
                            } else if (aCount > 0) {               // Not word Aligned
                                // "next" byte is just a padding byte
                                // so "move" past it and we can continue
                                aBuffer++;
                                aCount--;
                                mState = eRLEStateInitial;
                            }
                        }
                        // else state is still eRLEStateAbsoluteMode
                        continue;

                    default :
                        NS_NOTREACHED("BMP RLE decompression: unknown state!");
                        return NS_ERROR_FAILURE;
                }
                // Because of the use of the continue statement
                // we only get here for eol, eof or y delta
                if (mCurLine == 0) { // Finished last line
                    return mObserver->OnStopFrame(nsnull, mFrame);
                }
            }
        }
    }
    
    return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Set mBFH from the raw data in mRawBuf, converting from little-endian data to native data as necessary.

Definition at line 644 of file nsBMPDecoder.cpp.

Here is the call graph for this function:

Here is the caller graph for this function:

Set mBIH from the raw data in mRawBuf, converting from little-endian data to native data as necessary.

Definition at line 659 of file nsBMPDecoder.cpp.

Here is the call graph for this function:

Here is the caller graph for this function:

NS_METHOD nsBMPDecoder::ReadSegCb ( nsIInputStream aIn,
void aClosure,
const char *  aFromRawSegment,
PRUint32  aToOffset,
PRUint32  aCount,
PRUint32 aWriteCount 
) [static, private]

Callback for ReadSegments to avoid copying the data.

Definition at line 119 of file nsBMPDecoder.cpp.

                                                                     {
    nsBMPDecoder *decoder = NS_REINTERPRET_CAST(nsBMPDecoder*, aClosure);
    *aWriteCount = aCount;
    return decoder->ProcessData(aFromRawSegment, aCount);
}

Here is the call graph for this function:

Sets the image data.

mCurLine is used to get the row, mDecoded is used to get the data

Definition at line 138 of file nsBMPDecoder.cpp.

{
    PRInt32 line = (mBIH.height < 0) ? (-mBIH.height - mCurLine--) : --mCurLine;
    nsresult rv = mFrame->SetImageData(mDecoded, mBpr, line * mBpr);
    NS_ENSURE_SUCCESS(rv, rv);

    nsIntRect r(0, line, mBIH.width, 1);
    return mObserver->OnDataAvailable(nsnull, mFrame, &r);
}

Here is the caller graph for this function:

unsigned long imgIDecoder::writeFrom ( in nsIInputStream  inStr,
in unsigned long  count 
) [inherited]

Writes data into the stream from an input stream.

Implementer's note: This method is defined by this interface in order to allow the output stream to efficiently copy the data from the input stream into its internal buffer (if any). If this method was provide as an external facility, a separate char* buffer would need to be used in order to call the output stream's other Write method.

Parameters:
fromStreamthe stream from which the data is read
countthe maximun number of bytes to write
Returns:
aWriteCount out parameter to hold the number of bytes written. if an error occurs, the writecount is undefined

Sets the rle data.

mCurLine is used to get the row, mDecoded is used to get the data for the first row, all subsequent rows are blank.

Parameters:
rowsNumber of rows of data to set

Definition at line 148 of file nsBMPDecoder.cpp.

{
    PRUint32 alpha, cnt, line;
    PRUint8 bit;
    PRUint8* pos = mAlpha;

    // First pack the alpha data
    nsresult rv = mFrame->GetAlphaBytesPerRow(&alpha);
    NS_ENSURE_SUCCESS(rv, rv);
    for (cnt = 0; cnt < alpha; cnt++) {
        PRUint8 byte = 0;
        for (bit = 128; bit; bit >>= 1)
            byte |= *pos++ & bit;
        mAlpha[cnt] = byte;
    }

    for (cnt = 0; cnt < rows; cnt++) {
        line = (mBIH.height < 0) ? (-mBIH.height - mCurLine--) : --mCurLine;
        rv = mFrame->SetAlphaData(mAlpha, alpha, line * alpha);
        NS_ENSURE_SUCCESS(rv, rv);
        rv = mFrame->SetImageData(mDecoded, mBpr, line * mBpr);
        NS_ENSURE_SUCCESS(rv, rv);
        if (cnt == 0) {
            memset(mAlpha, 0, mBIH.width);
            memset(mDecoded, 0, mBpr);
        }
    }

    line = (mBIH.height < 0) ? (-mBIH.height - mCurLine - rows) : mCurLine;
    nsIntRect r(0, line, mBIH.width, rows);
    return mObserver->OnDataAvailable(nsnull, mFrame, &r);
}

Here is the call graph for this function:

Here is the caller graph for this function:


Member Data Documentation

Holds one line of unpacked alpha data.

Definition at line 213 of file nsBMPDecoder.h.

Pointer within unpacked alpha data.

Definition at line 214 of file nsBMPDecoder.h.

Definition at line 199 of file nsBMPDecoder.h.

Definition at line 200 of file nsBMPDecoder.h.

Definition at line 208 of file nsBMPDecoder.h.

Cached image bytes per row.

Definition at line 221 of file nsBMPDecoder.h.

Definition at line 206 of file nsBMPDecoder.h.

Index of the line of the image that's currently being decoded.

Definition at line 212 of file nsBMPDecoder.h.

Holds one line of color image data.

Definition at line 215 of file nsBMPDecoder.h.

Pointer within image data.

Definition at line 216 of file nsBMPDecoder.h.

Definition at line 195 of file nsBMPDecoder.h.

Definition at line 194 of file nsBMPDecoder.h.

Length of the header.

Definition at line 203 of file nsBMPDecoder.h.

The number of used colors, i.e. the number of entries in mColors.

Definition at line 205 of file nsBMPDecoder.h.

Definition at line 192 of file nsBMPDecoder.h.

Definition at line 197 of file nsBMPDecoder.h.

char nsBMPDecoder::mRawBuf[36] [private]

Definition at line 201 of file nsBMPDecoder.h.

Holds one raw line of the image.

Definition at line 210 of file nsBMPDecoder.h.

How many bytes of the row were already received.

Definition at line 211 of file nsBMPDecoder.h.

Maintains the current state of the RLE decoding.

Definition at line 218 of file nsBMPDecoder.h.

Decoding information that is needed depending on mState.

Definition at line 219 of file nsBMPDecoder.h.


The documentation for this class was generated from the following files: