Back to index

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

#include <nsXBMDecoder.h>

Inheritance diagram for nsXBMDecoder:
Inheritance graph
Collaboration diagram for nsXBMDecoder:
Collaboration graph

List of all members.

Public Member Functions

nsXBMDecoder ()
virtual ~nsXBMDecoder ()
nsresult ProcessData (const char *aData, PRUint32 aCount)
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 Types


Static Private Member Functions

static NS_METHOD ReadSegCb (nsIInputStream *aIn, void *aClosure, const char *aFromRawSegment, PRUint32 aToOffset, PRUint32 aCount, PRUint32 *aWriteCount)

Private Attributes

nsCOMPtr< imgIDecoderObservermObserver
nsCOMPtr< imgIContainermImage
nsCOMPtr< gfxIImageFramemFrame
PRUint32 mCurRow
PRUint32 mCurCol
char * mBuf
char * mPos
PRUint32 mBufSize
PRUint32 mWidth
PRUint32 mHeight
PRUint32 mXHotspot
PRUint32 mYHotspot
PRPackedBool mIsCursor
PRPackedBool mIsX10
enum nsXBMDecoder:: { ... }  mState

Detailed Description

Definition at line 57 of file nsXBMDecoder.h.

Member Enumeration Documentation

anonymous enum [private]

Definition at line 94 of file nsXBMDecoder.h.

Constructor & Destructor Documentation

Definition at line 65 of file nsXBMDecoder.cpp.

Definition at line 69 of file nsXBMDecoder.cpp.

    if (mBuf)

    if (mAlphaRow)

Member Function Documentation

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.

aRequestthe request that owns the decoder.
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.
nsresult nsXBMDecoder::ProcessData ( const char *  aData,
PRUint32  aCount 

Definition at line 134 of file nsXBMDecoder.cpp.

    char *endPtr;
    // calculate the offset since the absolute position might no longer
    // be valid after realloc
    const PRPtrdiff posOffset = mPos ? (mPos - mBuf) : 0;

    // expand the buffer to hold the new data
    char* oldbuf = mBuf;
    PRUint32 newbufsize = mBufSize + aCount + 1;
    if (newbufsize < mBufSize)
        mBuf = nsnull;  // size wrapped around, give up
        mBuf = (char*)realloc(mBuf, newbufsize);

    if (!mBuf) {
        mState = RECV_DONE;
        if (oldbuf)
        return NS_ERROR_OUT_OF_MEMORY;
    memcpy(mBuf + mBufSize, aData, aCount);
    mBufSize += aCount;
    mBuf[mBufSize] = 0;
    mPos = mBuf + posOffset;

    // process latest data according to current state
    if (mState == RECV_HEADER) {
        mPos = strstr(mBuf, "#define");
        if (!mPos)
            // #define not found. return for now, waiting for more data.
            return NS_OK;

        // Convert width and height to numbers.  Convert hotspot for cursor functionality, if present
        if (sscanf(mPos, "#define %*s %u #define %*s %u #define %*s %u #define %*s %u unsigned", &mWidth, &mHeight, &mXHotspot, &mYHotspot) == 4)
            mIsCursor = PR_TRUE;
        else if (sscanf(mPos, "#define %*s %u #define %*s %u unsigned", &mWidth, &mHeight) == 2)
            mIsCursor = PR_FALSE;
             // No identifiers found.  Return for now, waiting for more data.
            return NS_OK;

        // Check for X11 flavor
        if (strstr(mPos, " char "))
            mIsX10 = PR_FALSE;
        // Check for X10 flavor
        else if (strstr(mPos, " short "))
            mIsX10 = PR_TRUE;
            // Neither identifier found.  Return for now, waiting for more data.
            return NS_OK;

        mImage->Init(mWidth, mHeight, mObserver);
        mObserver->OnStartContainer(nsnull, mImage);

        nsresult rv = mFrame->Init(0, 0, mWidth, mHeight, GFXFORMAT, 24);
        if (NS_FAILED(rv))
            return rv;

        if (mIsCursor) {
            nsCOMPtr<nsIProperties> props(do_QueryInterface(mImage));
            if (props) {
                nsCOMPtr<nsISupportsPRUint32> intwrapx = do_CreateInstance(";1");
                nsCOMPtr<nsISupportsPRUint32> intwrapy = do_CreateInstance(";1");

                if (intwrapx && intwrapy) {

                    props->Set("hotspotX", intwrapx);
                    props->Set("hotspotY", intwrapy);

        mObserver->OnStartFrame(nsnull, mFrame);

        PRUint32 bpr;
        PRUint32 abpr;

        mAlphaRow = (PRUint8*)malloc(abpr);
        if (!mAlphaRow) {
          mState = RECV_DONE;
          return NS_ERROR_OUT_OF_MEMORY;

        memset(mAlphaRow, 0, abpr);

        mState = RECV_SEEK;

        mCurRow = 0;
        mCurCol = 0;

    if (mState == RECV_SEEK) {
        if ((endPtr = strchr(mPos, '{')) != NULL) {
            mPos = endPtr+1;
            mState = RECV_DATA;
        } else {
            mPos = mBuf + mBufSize;
            return NS_OK;
    if (mState == RECV_DATA) {
        PRUint32 bpr;
        PRUint32 abpr;
        PRBool hiByte = PR_TRUE;

        do {
            PRUint32 pixel = strtoul(mPos, &endPtr, 0);
            if (endPtr == mPos)
                return NS_OK;   // no number to be found - need more data
            if (!*endPtr)
                return NS_OK;   // number at the end - might be missing a digit
            if (pixel == 0 && *endPtr == 'x')
                return NS_OK;   // 0x at the end, actual number is missing
            while (*endPtr && isspace(*endPtr))
                endPtr++;       // skip whitespace looking for comma

            if (!*endPtr) {
                // Need more data
                return NS_OK;
            } else if (*endPtr != ',') {
                *endPtr = '\0';
                mState = RECV_DONE;  // strange character (or ending '}')
            if (!mIsX10 || !hiByte)
                mPos = endPtr; // go to next value only when done with this one
            if (mIsX10) {
                // handle X10 flavor short values
                if (hiByte)
                    pixel >>= 8;
                hiByte = !hiByte;

            mAlphaRow[mCurCol/8] = 0;
            for (int i = 0; i < 8; i++) {
                PRUint8 val = (pixel & (1 << i)) >> i;
                mAlphaRow[mCurCol/8] |= val << (7 - i);

            mCurCol = PR_MIN(mCurCol + 8, mWidth);
            if (mCurCol == mWidth || mState == RECV_DONE) {
                // Row finished. Set Data.
                mFrame->SetAlphaData(mAlphaRow, abpr, mCurRow * abpr);
                // nsnull gets interpreted as all-zeroes, which is what we
                // want
                mFrame->SetImageData(nsnull, bpr, mCurRow * bpr);
                nsIntRect r(0, mCurRow, mWidth, 1);
                mObserver->OnDataAvailable(nsnull, mFrame, &r);

                if ((mCurRow + 1) == mHeight) {
                    mState = RECV_DONE;
                    return mObserver->OnStopFrame(nsnull, mFrame);
                mCurCol = 0;

            // Skip the comma
            NS_ASSERTION(mState != RECV_DATA || *mPos == ',' ||
                         (mIsX10 && hiByte),
                         "Must be a comma");
            if (*mPos == ',')
        } while ((mState == RECV_DATA) && *mPos);

    return NS_OK;

Here is the call graph for this function:

Here is the caller graph for this function:

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

Definition at line 121 of file nsXBMDecoder.cpp.

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

Here is the call 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.

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

Member Data Documentation

Definition at line 89 of file nsXBMDecoder.h.

char* nsXBMDecoder::mBuf [private]

Definition at line 80 of file nsXBMDecoder.h.

Definition at line 82 of file nsXBMDecoder.h.

Definition at line 78 of file nsXBMDecoder.h.

Definition at line 77 of file nsXBMDecoder.h.

Definition at line 75 of file nsXBMDecoder.h.

Definition at line 85 of file nsXBMDecoder.h.

Definition at line 74 of file nsXBMDecoder.h.

Definition at line 91 of file nsXBMDecoder.h.

Definition at line 92 of file nsXBMDecoder.h.

Definition at line 72 of file nsXBMDecoder.h.

char* nsXBMDecoder::mPos [private]

Definition at line 81 of file nsXBMDecoder.h.

enum { ... } nsXBMDecoder::mState [private]

Definition at line 84 of file nsXBMDecoder.h.

Definition at line 86 of file nsXBMDecoder.h.

Definition at line 87 of file nsXBMDecoder.h.

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