//************************************************************************ BOOL CDib::LoadFromResource(HINSTANCE hInstance, LPCSTR szResource, BOOL fDecodeRLE) //************************************************************************ { HRSRC hDibRes; HGLOBAL hDib; LPTR lpDib; LPBITMAPINFO lpbmInfo; DWORD dwBits; if ( !(hDibRes = FindResource(hInstance, szResource, RT_BITMAP)) ) return(FALSE); if (! (hDib = LoadResource(hInstance, hDibRes)) ) return(FALSE); lpDib = (LPTR)LockResource(hDib); if (!lpDib) return(FALSE); lpbmInfo = (LPBITMAPINFO)lpDib; m_bmiHeader = lpbmInfo->bmiHeader; FixHeader(); hmemcpy(m_rgbQuad, lpbmInfo->bmiColors, GetNumColors() * sizeof(RGBQUAD)); lpDib += m_bmiHeader.biSize + (GetNumColors() * sizeof(RGBQUAD)); // Can we get enough memory to hold the DIB bits if ( (m_lp = AllocX( dwBits = GetSizeImage(), GMEM_ZEROINIT )) != NULL ) hmemcpy(m_lp, lpDib, dwBits); UnlockResource(hDib); FreeResource(hDib); return(CheckDecodeRLE(fDecodeRLE)); }
// --- static WORD GetPaletteSize( LPSTR lpBI ) { // if handle to DIB is invalid, return 0 if (lpBI == NULL) return 0; // calculate the size required by the palette BOOL bWin30; bWin30 = (IS_WIN30_DIB (lpBI)); if (bWin30) return (WORD)(GetNumColors(lpBI) * sizeof(RGBQUAD)); else return (WORD)(GetNumColors(lpBI) * sizeof(RGBTRIPLE)); }
// Returns a buffer filled with the bitmap file header in little endian: // Signature 2 bytes 'BM' // FileSize 4 bytes File size in bytes // reserved 4 bytes unused (=0) // DataOffset 4 bytes File offset to Raster Data // Returns true if successful bool nsICODecoder::FillBitmapFileHeaderBuffer(PRInt8 *bfh) { memset(bfh, 0, 14); bfh[0] = 'B'; bfh[1] = 'M'; PRInt32 dataOffset = 0; PRInt32 fileSize = 0; dataOffset = BFH_LENGTH + BITMAPINFOSIZE; // The color table is present only if BPP is <= 8 if (mDirEntry.mBitCount <= 8) { PRUint16 numColors = GetNumColors(); if (numColors == (PRUint16)-1) { return false; } dataOffset += 4 * numColors; fileSize = dataOffset + GetRealWidth() * GetRealHeight(); } else { fileSize = dataOffset + (mDirEntry.mBitCount * GetRealWidth() * GetRealHeight()) / 8; } fileSize = NATIVE32_TO_LITTLE(fileSize); memcpy(bfh + 2, &fileSize, sizeof(fileSize)); dataOffset = NATIVE32_TO_LITTLE(dataOffset); memcpy(bfh + 10, &dataOffset, sizeof(dataOffset)); return true; }
BOOL eglDib::LoadBitmapFromFile(const char *filename) { HANDLE hFile; DWORD FileSize, ReadCount; hFile = CreateFile(filename, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if(INVALID_HANDLE_VALUE == hFile) { return FALSE; } FileSize = GetFileSize(hFile, NULL); if(mBMPFileHeader) free(mBMPFileHeader); mBMPFileHeader = (BITMAPFILEHEADER*)malloc(FileSize); ReadFile(hFile, mBMPFileHeader, FileSize, &ReadCount, NULL); CloseHandle(hFile); mRawData = (PBYTE)mBMPFileHeader + mBMPFileHeader->bfOffBits; mBMPInfo = (BITMAPINFO*)((PBYTE)mBMPFileHeader+sizeof(BITMAPFILEHEADER)); mBMPInfoHeader = (BITMAPINFOHEADER*)((PBYTE)mBMPFileHeader+sizeof(BITMAPFILEHEADER)); mRGBTable = (RGBQUAD*)((PBYTE)mBMPInfoHeader + mBMPInfoHeader->biSize); if(mBMPInfoHeader->biBitCount == 8) { CreateLogicalPallete(); } mNumColors= GetNumColors(); return TRUE; }
// Given the input 'filter' option, return an OR'd bit-set of filters to try. static uint32_t GetFilterMap(const uint8_t* alpha, int width, int height, int filter, int effort_level) { uint32_t bit_map = 0U; if (filter == WEBP_FILTER_FAST) { // Quick estimate of the best candidate. int try_filter_none = (effort_level > 3); const int kMinColorsForFilterNone = 16; const int kMaxColorsForFilterNone = 192; const int num_colors = GetNumColors(alpha, width, height, width); // For low number of colors, NONE yeilds better compression. filter = (num_colors <= kMinColorsForFilterNone) ? WEBP_FILTER_NONE : EstimateBestFilter(alpha, width, height, width); bit_map |= 1 << filter; // For large number of colors, try FILTER_NONE in addition to the best // filter as well. if (try_filter_none || num_colors > kMaxColorsForFilterNone) { bit_map |= 1 << WEBP_FILTER_NONE; } } else if (filter == WEBP_FILTER_NONE) { bit_map = 1 << WEBP_FILTER_NONE; } else { // WEBP_FILTER_BEST bit_map = (1 << WEBP_FILTER_LAST) - 1; // try all. } return bit_map; }
//************************************************************************ void CDib::FixHeader() //************************************************************************ { m_bmiHeader.biSizeImage = GetSizeImage(); m_bmiHeader.biClrUsed = GetNumColors(); if ( !m_bmiHeader.biClrUsed && m_bmiHeader.biCompression == BI_BITFIELDS ) ; // m_bmiHeader.biClrUsed = 3; }
// Map the colors of the DIB (using GetNearestPaletteIndex) to a palette //************************************************************************ void CDib::MapToPalette( HPALETTE hpal ) //************************************************************************ { int n, nDibColors; LPBYTE lpBits; LPRGBQUAD lpRgb; BYTE xlat[256]; DWORD SizeImage; BOOL bChanged; if ( !hpal ) return; if ( m_bmiHeader.biBitCount != 8 ) return; if ( GetColorTableType() == DIB_PAL_COLORS ) return; // build a xlat table. from the current DIB colors to the given palette nDibColors = GetNumColors(); lpRgb = GetColors(); bChanged = NO; for ( n=0; n<nDibColors; n++ ) { xlat[n] = (BYTE)GetNearestPaletteIndex( hpal, RGB(lpRgb->rgbRed, lpRgb->rgbGreen, lpRgb->rgbBlue) ); if ( xlat[n] != n ) bChanged = YES; lpRgb++; } if ( !bChanged ) { // Now reset the DIB color table to match the palette SetColorTable( hpal, DIB_RGB_COLORS ); return; } // translate the DIB bits lpBits = (LPBYTE)GetPtr(); SizeImage = GetSizeImage(); switch (m_bmiHeader.biCompression) { case BI_RLE8: xlatRle8(lpBits, SizeImage, xlat); break; case BI_RGB: xlatClut8(lpBits, SizeImage, xlat); break; } // Now reset the DIB color table to match the palette SetColorTable( hpal, DIB_RGB_COLORS ); }
const unsigned char * avtColorTables::GetColors(const std::string &ctName) { const unsigned char *retval = NULL; int index; if((index = ctAtts->GetColorTableIndex(ctName)) != -1) { const ColorControlPointList &ct = ctAtts->operator[](index); ct.GetColors(tmpColors, GetNumColors()); retval = tmpColors; } return retval; }
// Save a palette to an open MMIO handle BOOL CDIBPal::Save(HMMIO hmmio) { // Create a RIFF chunk for a PAL file MMCKINFO ckFile; ckFile.cksize = 0; // corrected later ckFile.fccType = mmioFOURCC('P','A','L',' '); if (mmioCreateChunk(hmmio, &ckFile, MMIO_CREATERIFF) != 0) { TRACE("Failed to create RIFF-PAL chunk"); return FALSE; } // create the LOGPALETTE data which will become // the data chunk int iColors = GetNumColors(); ASSERT(iColors > 0); int iSize = sizeof(LOGPALETTE) + (iColors-1) * sizeof(PALETTEENTRY); LOGPALETTE* plp = (LOGPALETTE*) malloc(iSize); ASSERT(plp); plp->palVersion = 0x300; plp->palNumEntries = iColors; GetPaletteEntries(0, iColors, plp->palPalEntry); // create the data chunk MMCKINFO ckData; ckData.cksize = iSize; ckData.ckid = mmioFOURCC('d','a','t','a'); if (mmioCreateChunk(hmmio, &ckData, 0) != 0) { TRACE("Failed to create data chunk"); return FALSE; } // write the data chunk if (mmioWrite(hmmio, (char*)plp, iSize) != iSize) { TRACE("Failed to write data chunk"); free(plp); return FALSE; } free(plp); // Ascend from the data chunk which will correct the length mmioAscend(hmmio, &ckData, 0); // Ascend from the RIFF/PAL chunk mmioAscend(hmmio, &ckFile, 0); return TRUE; }
////////////////// // Create the palette. Use halftone palette for hi-color bitmaps. // HPALETTE PLWinBmpEx::CreatePalette(void) { // should not already have palette ASSERT( m_pal == 0 ); HPALETTE hRet = HPALETTE(0); if (m_pClrTab) { // RGBQUAD* colors = new RGBQUAD[MAXPALCOLORS]; UINT nColors = GetNumColors(); // 256, really... // Allocate memory for logical palette int len = sizeof(LOGPALETTE) + sizeof(PALETTEENTRY) * nColors; LOGPALETTE* pLogPal = (LOGPALETTE*)new char[len]; if (!pLogPal) return hRet; // set version and number of palette entries pLogPal->palVersion = PALVERSION; pLogPal->palNumEntries = (WORD) nColors; // copy color entries for (UINT i = 0; i < nColors; i++) { PLBYTE * pb = (PLBYTE *) (m_pClrTab+i); pLogPal->palPalEntry[i].peRed = pb[PL_RGBA_RED ]; pLogPal->palPalEntry[i].peGreen = pb[PL_RGBA_GREEN]; pLogPal->palPalEntry[i].peBlue = pb[PL_RGBA_BLUE ]; pLogPal->palPalEntry[i].peFlags = 0; } // create the palette and destroy LOGPAL hRet = ::CreatePalette(pLogPal); delete [] (char*)pLogPal; } else { // If the file itself did not contain a colormap, we will use // a default palette and rely on DrawDib's halftoning. // When displaying higher-color images on 8bpp hardware, // this is suboptimal though. Ideally we should build the // palette according to an histogram of the actual RGB values. // "SeeDib" from MS Source Code Samples does that nicely HDC dcScreen = ::GetWindowDC(NULL); hRet = ::CreateHalftonePalette(dcScreen); ::ReleaseDC (NULL, dcScreen); } return hRet; }
// **************************************************************************** // Method: avtColorTables::GetAlphas // // Purpose: // Like GetColors, but gets the alpha values instead. // // Arguments: // ctName : The name of the color table for which we want the colors. // // Programmer: Jeremy Meredith // Creation: February 20, 2009 // // **************************************************************************** const unsigned char * avtColorTables::GetAlphas(const std::string &ctName) { unsigned char dummy[256*3]; const unsigned char *retval = NULL; int index; if((index = ctAtts->GetColorTableIndex(ctName)) != -1) { const ColorControlPointList &ct = ctAtts->operator[](index); ct.GetColors(dummy, GetNumColors(), tmpAlphas); retval = tmpAlphas; } return retval; }
void CDIBPal::Draw(HDC hDC, RECT* pRect, BOOL bBkgnd) { int iColors = GetNumColors(); HPALETTE hOldPal = ::SelectPalette(hDC, (HPALETTE)m_hObject, bBkgnd); ::RealizePalette(hDC); int i, j, top, left, bottom, right, w, h; w = pRect->right - pRect->left; h = pRect->bottom - pRect->top; for (j=0, top=pRect->top; j<16 && iColors; j++, top=bottom) { bottom = pRect->top + (j+1) * h / 16 + 1; for(i=0, left=pRect->left; i<16 && iColors; i++, left=right) { right = pRect->left + (i+1) * w / 16 + 1; CBrush br (PALETTEINDEX(j * 16 + i)); HBRUSH brold = (HBRUSH)::SelectObject(hDC, br.m_hObject); ::Rectangle(hDC, left-1, top-1, right, bottom); ::SelectObject(hDC, brold); iColors--; } } ::SelectPalette(hDC, hOldPal, FALSE); }
void CDIBPal::Draw(CDC* pDC, CRect* pRect, BOOL bBkgnd) { #if 0 int iColors = GetNumColors(); CPalette *pOldPal = pDC->SelectPalette(this, bBkgnd); pDC->RealizePalette(); int i, j, top, left, bottom, right; for (j=0, top=0; j<16 && iColors; j++, top=bottom) { bottom = (j+1) * pRect->bottom / 16 + 1; for(i=0, left=0; i<16 && iColors; i++, left=right) { right = (i+1) * pRect->right / 16 + 1; CBrush br (PALETTEINDEX(j * 16 + i)); CBrush *brold = pDC->SelectObject(&br); pDC->Rectangle(left-1, top-1, right, bottom); pDC->SelectObject(brold); iColors--; } } pDC->SelectPalette(pOldPal, FALSE); #else Draw(pDC->GetSafeHdc(), pRect, bBkgnd); #endif }
void nsICODecoder::WriteInternal(const char* aBuffer, uint32_t aCount, DecodeStrategy aStrategy) { NS_ABORT_IF_FALSE(!HasError(), "Shouldn't call WriteInternal after error!"); if (!aCount) { if (mContainedDecoder) { WriteToContainedDecoder(aBuffer, aCount, aStrategy); } return; } while (aCount && (mPos < ICONCOUNTOFFSET)) { // Skip to the # of icons. if (mPos == 2) { // if the third byte is 1: This is an icon, 2: a cursor if ((*aBuffer != 1) && (*aBuffer != 2)) { PostDataError(); return; } mIsCursor = (*aBuffer == 2); } mPos++; aBuffer++; aCount--; } if (mPos == ICONCOUNTOFFSET && aCount >= 2) { mNumIcons = LittleEndian::readUint16(reinterpret_cast<const uint16_t*>(aBuffer)); aBuffer += 2; mPos += 2; aCount -= 2; } if (mNumIcons == 0) return; // Nothing to do. uint16_t colorDepth = 0; nsIntSize prefSize = mImage.GetRequestedResolution(); if (prefSize.width == 0 && prefSize.height == 0) { prefSize.SizeTo(PREFICONSIZE, PREFICONSIZE); } // A measure of the difference in size between the entry we've found // and the requested size. We will choose the smallest image that is // >= requested size (i.e. we assume it's better to downscale a larger // icon than to upscale a smaller one). int32_t diff = INT_MIN; // Loop through each entry's dir entry while (mCurrIcon < mNumIcons) { if (mPos >= DIRENTRYOFFSET + (mCurrIcon * sizeof(mDirEntryArray)) && mPos < DIRENTRYOFFSET + ((mCurrIcon + 1) * sizeof(mDirEntryArray))) { uint32_t toCopy = sizeof(mDirEntryArray) - (mPos - DIRENTRYOFFSET - mCurrIcon * sizeof(mDirEntryArray)); if (toCopy > aCount) { toCopy = aCount; } memcpy(mDirEntryArray + sizeof(mDirEntryArray) - toCopy, aBuffer, toCopy); mPos += toCopy; aCount -= toCopy; aBuffer += toCopy; } if (aCount == 0) return; // Need more data IconDirEntry e; if (mPos == (DIRENTRYOFFSET + ICODIRENTRYSIZE) + (mCurrIcon * sizeof(mDirEntryArray))) { mCurrIcon++; ProcessDirEntry(e); // We can't use GetRealWidth and GetRealHeight here because those operate // on mDirEntry, here we are going through each item in the directory. // Calculate the delta between this image's size and the desired size, // so we can see if it is better than our current-best option. // In the case of several equally-good images, we use the last one. int32_t delta = (e.mWidth == 0 ? 256 : e.mWidth) - prefSize.width + (e.mHeight == 0 ? 256 : e.mHeight) - prefSize.height; if (e.mBitCount >= colorDepth && ((diff < 0 && delta >= diff) || (delta >= 0 && delta <= diff))) { diff = delta; mImageOffset = e.mImageOffset; // ensure mImageOffset is >= size of the direntry headers (bug #245631) uint32_t minImageOffset = DIRENTRYOFFSET + mNumIcons * sizeof(mDirEntryArray); if (mImageOffset < minImageOffset) { PostDataError(); return; } colorDepth = e.mBitCount; memcpy(&mDirEntry, &e, sizeof(IconDirEntry)); } } } if (mPos < mImageOffset) { // Skip to (or at least towards) the desired image offset uint32_t toSkip = mImageOffset - mPos; if (toSkip > aCount) toSkip = aCount; mPos += toSkip; aBuffer += toSkip; aCount -= toSkip; } // If we are within the first PNGSIGNATURESIZE bytes of the image data, // then we have either a BMP or a PNG. We use the first PNGSIGNATURESIZE // bytes to determine which one we have. if (mCurrIcon == mNumIcons && mPos >= mImageOffset && mPos < mImageOffset + PNGSIGNATURESIZE) { uint32_t toCopy = PNGSIGNATURESIZE - (mPos - mImageOffset); if (toCopy > aCount) { toCopy = aCount; } memcpy(mSignature + (mPos - mImageOffset), aBuffer, toCopy); mPos += toCopy; aCount -= toCopy; aBuffer += toCopy; mIsPNG = !memcmp(mSignature, nsPNGDecoder::pngSignatureBytes, PNGSIGNATURESIZE); if (mIsPNG) { mContainedDecoder = new nsPNGDecoder(mImage); mContainedDecoder->SetObserver(mObserver); mContainedDecoder->SetSizeDecode(IsSizeDecode()); mContainedDecoder->InitSharedDecoder(mImageData, mImageDataLength, mColormap, mColormapSize, mCurrentFrame); if (!WriteToContainedDecoder(mSignature, PNGSIGNATURESIZE, aStrategy)) { return; } } } // If we have a PNG, let the PNG decoder do all of the rest of the work if (mIsPNG && mContainedDecoder && mPos >= mImageOffset + PNGSIGNATURESIZE) { if (!WriteToContainedDecoder(aBuffer, aCount, aStrategy)) { return; } if (!HasSize() && mContainedDecoder->HasSize()) { PostSize(mContainedDecoder->GetImageMetadata().GetWidth(), mContainedDecoder->GetImageMetadata().GetHeight()); } mPos += aCount; aBuffer += aCount; aCount = 0; // Raymond Chen says that 32bpp only are valid PNG ICOs // http://blogs.msdn.com/b/oldnewthing/archive/2010/10/22/10079192.aspx if (!IsSizeDecode() && !static_cast<nsPNGDecoder*>(mContainedDecoder.get())->IsValidICO()) { PostDataError(); } return; } // We've processed all of the icon dir entries and are within the // bitmap info size if (!mIsPNG && mCurrIcon == mNumIcons && mPos >= mImageOffset && mPos >= mImageOffset + PNGSIGNATURESIZE && mPos < mImageOffset + BITMAPINFOSIZE) { // As we were decoding, we did not know if we had a PNG signature or the // start of a bitmap information header. At this point we know we had // a bitmap information header and not a PNG signature, so fill the bitmap // information header with the data it should already have. memcpy(mBIHraw, mSignature, PNGSIGNATURESIZE); // We've found the icon. uint32_t toCopy = sizeof(mBIHraw) - (mPos - mImageOffset); if (toCopy > aCount) toCopy = aCount; memcpy(mBIHraw + (mPos - mImageOffset), aBuffer, toCopy); mPos += toCopy; aCount -= toCopy; aBuffer += toCopy; } // If we have a BMP inside the ICO and we have read the BIH header if (!mIsPNG && mPos == mImageOffset + BITMAPINFOSIZE) { // Make sure we have a sane value for the bitmap information header int32_t bihSize = ExtractBIHSizeFromBitmap(reinterpret_cast<int8_t*>(mBIHraw)); if (bihSize != BITMAPINFOSIZE) { PostDataError(); return; } // We are extracting the BPP from the BIH header as it should be trusted // over the one we have from the icon header mBPP = ExtractBPPFromBitmap(reinterpret_cast<int8_t*>(mBIHraw)); // Init the bitmap decoder which will do most of the work for us // It will do everything except the AND mask which isn't present in bitmaps // bmpDecoder is for local scope ease, it will be freed by mContainedDecoder nsBMPDecoder *bmpDecoder = new nsBMPDecoder(mImage); mContainedDecoder = bmpDecoder; bmpDecoder->SetUseAlphaData(true); mContainedDecoder->SetObserver(mObserver); mContainedDecoder->SetSizeDecode(IsSizeDecode()); mContainedDecoder->InitSharedDecoder(mImageData, mImageDataLength, mColormap, mColormapSize, mCurrentFrame); // The ICO format when containing a BMP does not include the 14 byte // bitmap file header. To use the code of the BMP decoder we need to // generate this header ourselves and feed it to the BMP decoder. int8_t bfhBuffer[BMPFILEHEADERSIZE]; if (!FillBitmapFileHeaderBuffer(bfhBuffer)) { PostDataError(); return; } if (!WriteToContainedDecoder((const char*)bfhBuffer, sizeof(bfhBuffer), aStrategy)) { return; } // Setup the cursor hot spot if one is present SetHotSpotIfCursor(); // Fix the ICO height from the BIH. // Fix the height on the BIH to be /2 so our BMP decoder will understand. if (!FixBitmapHeight(reinterpret_cast<int8_t*>(mBIHraw))) { PostDataError(); return; } // Fix the ICO width from the BIH. if (!FixBitmapWidth(reinterpret_cast<int8_t*>(mBIHraw))) { PostDataError(); return; } // Write out the BMP's bitmap info header if (!WriteToContainedDecoder(mBIHraw, sizeof(mBIHraw), aStrategy)) { return; } PostSize(mContainedDecoder->GetImageMetadata().GetWidth(), mContainedDecoder->GetImageMetadata().GetHeight()); // We have the size. If we're doing a size decode, we got what // we came for. if (IsSizeDecode()) return; // Sometimes the ICO BPP header field is not filled out // so we should trust the contained resource over our own // information. mBPP = bmpDecoder->GetBitsPerPixel(); // Check to make sure we have valid color settings uint16_t numColors = GetNumColors(); if (numColors == (uint16_t)-1) { PostDataError(); return; } } // If we have a BMP if (!mIsPNG && mContainedDecoder && mPos >= mImageOffset + BITMAPINFOSIZE) { uint16_t numColors = GetNumColors(); if (numColors == (uint16_t)-1) { PostDataError(); return; } // Feed the actual image data (not including headers) into the BMP decoder uint32_t bmpDataOffset = mDirEntry.mImageOffset + BITMAPINFOSIZE; uint32_t bmpDataEnd = mDirEntry.mImageOffset + BITMAPINFOSIZE + static_cast<nsBMPDecoder*>(mContainedDecoder.get())->GetCompressedImageSize() + 4 * numColors; // If we are feeding in the core image data, but we have not yet // reached the ICO's 'AND buffer mask' if (mPos >= bmpDataOffset && mPos < bmpDataEnd) { // Figure out how much data the BMP decoder wants uint32_t toFeed = bmpDataEnd - mPos; if (toFeed > aCount) { toFeed = aCount; } if (!WriteToContainedDecoder(aBuffer, toFeed, aStrategy)) { return; } mPos += toFeed; aCount -= toFeed; aBuffer += toFeed; } // If the bitmap is fully processed, treat any left over data as the ICO's // 'AND buffer mask' which appears after the bitmap resource. if (!mIsPNG && mPos >= bmpDataEnd) { // There may be an optional AND bit mask after the data. This is // only used if the alpha data is not already set. The alpha data // is used for 32bpp bitmaps as per the comment in ICODecoder.h // The alpha mask should be checked in all other cases. if (static_cast<nsBMPDecoder*>(mContainedDecoder.get())->GetBitsPerPixel() != 32 || !static_cast<nsBMPDecoder*>(mContainedDecoder.get())->HasAlphaData()) { uint32_t rowSize = ((GetRealWidth() + 31) / 32) * 4; // + 31 to round up if (mPos == bmpDataEnd) { mPos++; mRowBytes = 0; mCurLine = GetRealHeight(); mRow = (uint8_t*)moz_realloc(mRow, rowSize); if (!mRow) { PostDecoderError(NS_ERROR_OUT_OF_MEMORY); return; } } // Ensure memory has been allocated before decoding. NS_ABORT_IF_FALSE(mRow, "mRow is null"); if (!mRow) { PostDataError(); return; } while (mCurLine > 0 && aCount > 0) { uint32_t toCopy = std::min(rowSize - mRowBytes, aCount); if (toCopy) { memcpy(mRow + mRowBytes, aBuffer, toCopy); aCount -= toCopy; aBuffer += toCopy; mRowBytes += toCopy; } if (rowSize == mRowBytes) { mCurLine--; mRowBytes = 0; uint32_t* imageData = static_cast<nsBMPDecoder*>(mContainedDecoder.get())->GetImageData(); if (!imageData) { PostDataError(); return; } uint32_t* decoded = imageData + mCurLine * GetRealWidth(); uint32_t* decoded_end = decoded + GetRealWidth(); uint8_t* p = mRow, *p_end = mRow + rowSize; while (p < p_end) { uint8_t idx = *p++; for (uint8_t bit = 0x80; bit && decoded<decoded_end; bit >>= 1) { // Clear pixel completely for transparency. if (idx & bit) { *decoded = 0; } decoded++; } } } } }
/* * GenerateConfiguration - write out a config file */ vi_rc GenerateConfiguration( const char *fname, bool is_cmdline ) { FILE *fp; int i; char token[128]; const char *str; char *buff; int num; rgb c; const char *res; char tmpstr[MAX_STR]; if( fname == NULL ) { fname = CFG_NAME; } fp = fopen( fname, "w" ); if( fp == NULL ) { return( ERR_FILE_OPEN ); } isCmdLine = is_cmdline; buff = MemAllocUnsafe( VBUF_SIZE ); if( buff != NULL ) { setvbuf( fp, buff, _IOFBF, VBUF_SIZE ); } MyFprintf( fp, "#\n# %s configuration file\n# %s\n#\n", #if defined( __WIN__ ) banner1w1( "Text Editor for Windows" ), banner1w2( _VI_VERSION_ ) ); #else banner1w1( "Vi Text Editor" ), banner1w2( _VI_VERSION_ ) ); #endif if( is_cmdline ) { GetDateTimeString( token ); MyFprintf( fp, "# File generated on %s\n#\n", token ); } writeTitle( fp, "Hook script assignments" ); doHookAssign( fp, SRC_HOOK_WRITE ); doHookAssign( fp, SRC_HOOK_READ ); doHookAssign( fp, SRC_HOOK_BUFFIN ); doHookAssign( fp, SRC_HOOK_BUFFOUT ); doHookAssign( fp, SRC_HOOK_COMMAND ); doHookAssign( fp, SRC_HOOK_MODIFIED ); doHookAssign( fp, SRC_HOOK_MENU ); doHookAssign( fp, SRC_HOOK_MOUSE_LINESEL ); doHookAssign( fp, SRC_HOOK_MOUSE_CHARSEL ); writeTitle( fp, "General Settings" ); num = GetNumberOfTokens( SetVarTokens ); for( i = 0; i < num; i++ ) { if( i == SETVAR_T_TILECOLOR || i == SETVAR_T_FIGNORE || i == SETVAR_T_FILENAME ) { continue; } res = GetASetVal( GetTokenStringCVT( SetVarTokens, i, token, true ), tmpstr ); switch( i ) { case SETVAR_T_STATUSSTRING: case SETVAR_T_FILEENDSTRING: case SETVAR_T_HISTORYFILE: case SETVAR_T_TMPDIR: /* strings with possible spaces */ MyFprintf( fp, "set %s = \"%s\"\n", token, res ); break; case SETVAR_T_GADGETSTRING: if( !IsGadgetStringChanged( res ) ) break; // fall through default: MyFprintf( fp, "set %s = %s\n", token, res ); break; } } writeTitle( fp, "Boolean Settings" ); num = GetNumberOfTokens( SetFlagTokens ); for( i = 0; i < num; i++ ) { str = GetASetVal( GetTokenStringCVT( SetFlagTokens, i, token, true ), tmpstr ); MyFprintf( fp, "set %s%s\n", (*str == '0') ? "no" : "", token ); } writeTitle( fp, "Match pairs" ); for( i = INITIAL_MATCH_COUNT; i < MatchCount; i += 2 ) { MyFprintf( fp, "match /" ); outputMatchData( fp, MatchData[i] ); outputMatchData( fp, MatchData[i + 1] ); MyFprintf( fp, "\n" ); } writeTitle( fp, "Command Mode Mappings" ); doMaps( fp, KeyMaps, "" ); writeTitle( fp, "Insert Mode Mappings" ); doMaps( fp, InputKeyMaps, "!" ); writeTitle( fp, "Color Settings" ); for( i = 0; i < GetNumColors(); i++ ) { if( GetColorSetting( i, &c ) ) { MyFprintf( fp, "setcolor %d %d %d %d\n", i, c.red, c.green, c.blue ); } } #ifdef __WIN__ writeTitle( fp, "Font Settings" ); BarfFontData( fp ); #endif writeTitle( fp, "Window Configuration" ); doWindow( fp, PCL_T_COMMANDWINDOW, &cmdlinew_info, false ); doWindow( fp, PCL_T_STATUSWINDOW, &statusw_info, false ); doWindow( fp, PCL_T_COUNTWINDOW, &repcntw_info, false ); doWindow( fp, PCL_T_EDITWINDOW, &editw_info, false ); doWindow( fp, PCL_T_FILECWINDOW, &filecw_info, false ); doWindow( fp, PCL_T_DIRWINDOW, &dirw_info, false ); doWindow( fp, PCL_T_FILEWINDOW, &filelistw_info, false ); doWindow( fp, PCL_T_MESSAGEWINDOW, &messagew_info, false ); #ifndef __WIN__ doWindow( fp, PCL_T_SETWINDOW, &setw_info, false ); doWindow( fp, PCL_T_LINENUMBERWINDOW, &linenumw_info, false ); doWindow( fp, PCL_T_EXTRAINFOWINDOW, &extraw_info, false ); doWindow( fp, PCL_T_SETVALWINDOW, &setvalw_info, false ); doWindow( fp, PCL_T_MENUWINDOW, &menuw_info, false ); doWindow( fp, PCL_T_MENUBARWINDOW, &menubarw_info, true ); doWindow( fp, PCL_T_ACTIVEMENUWINDOW, &activemenu_info, true ); doWindow( fp, PCL_T_GREYEDMENUWINDOW, &greyedmenu_info, true ); doWindow( fp, PCL_T_ACTIVEGREYEDMENUWINDOW, &activegreyedmenu_info, true ); #endif writeTitle( fp, "Menu Configuration" ); BarfMenuData( fp ); #ifdef __WIN__ writeTitle( fp, "ToolBar Configuration" ); BarfToolBarData( fp ); #endif writeTitle( fp, "File Type Source" ); FTSBarfData( fp ); fclose( fp ); if( is_cmdline ) { Message1( "Configuration file \"%s\" generated", fname ); } MemFree( buff ); return( DO_NOT_CLEAR_MESSAGE_WINDOW ); } /* GenerateConfiguration */
/* * GenerateConfiguration - write out a config file */ vi_rc GenerateConfiguration( char *fname, bool is_cmdline ) { FILE *f; int i; char token[128]; char *str; char boolstr[3]; char *buff; int num; rgb c; char *fmt; char *res; if( fname == NULL ) { fname = CFG_NAME; } f = fopen( fname, "w" ); if( f == NULL ) { return( ERR_FILE_OPEN ); } isCmdLine = is_cmdline; buff = MemAllocUnsafe( VBUF_SIZE ); if( buff != NULL ) { setvbuf( f, buff, _IOFBF, VBUF_SIZE ); } MyFprintf( f, "#\n# WATCOM %s %s configuration file\n# %s\n#\n", TITLE, VERSIONT, AUTHOR ); if( is_cmdline ) { GetDateTimeString( token ); MyFprintf( f, "# File generated on %s\n#\n", token ); } writeTitle( f, "Hook script assignments" ); doHookAssign( f, SRC_HOOK_WRITE ); doHookAssign( f, SRC_HOOK_READ ); doHookAssign( f, SRC_HOOK_BUFFIN ); doHookAssign( f, SRC_HOOK_BUFFOUT ); doHookAssign( f, SRC_HOOK_COMMAND ); doHookAssign( f, SRC_HOOK_MODIFIED ); doHookAssign( f, SRC_HOOK_MENU ); doHookAssign( f, SRC_HOOK_MOUSE_LINESEL ); doHookAssign( f, SRC_HOOK_MOUSE_CHARSEL ); writeTitle( f, "General Settings" ); num = GetNumberOfTokens( SetTokens1 ); for( i = 0; i < num; i++ ) { if( i == SET1_T_TILECOLOR || i == SET1_T_FIGNORE || i == SET1_T_FILENAME ) { continue; } strcpy( token, GetTokenString( SetTokens1, i ) ); strlwr( token ); res = GetASetVal( token ); if( i == SET1_T_STATUSSTRING || i == SET1_T_FILEENDSTRING || i == SET1_T_HISTORYFILE || i == SET1_T_TMPDIR ) { /* strings with possible spaces */ fmt = "set %s = \"%s\"\n"; } else { fmt = "set %s = %s\n"; } MyFprintf( f, fmt, token, res ); } writeTitle( f, "Boolean Settings" ); num = GetNumberOfTokens( SetTokens2 ); for( i = 0; i < num; i++ ) { strcpy( token, GetTokenString( SetTokens2, i ) ); strlwr( token ); str = GetASetVal( token ); boolstr[0] = 0; if( str[0] == '0' ) { boolstr[0] = 'n'; boolstr[1] = 'o'; boolstr[2] = 0; } MyFprintf( f, "set %s%s\n", boolstr, token ); } writeTitle( f, "Match pairs" ); for( i = INITIAL_MATCH_COUNT; i < MatchCount; i += 2 ) { MyFprintf( f, "match /" ); outputMatchData( f, MatchData[i] ); outputMatchData( f, MatchData[i + 1] ); MyFprintf( f, "\n" ); } writeTitle( f, "Command Mode Mappings" ); doMaps( f, KeyMaps, "" ); writeTitle( f, "Insert Mode Mappings" ); doMaps( f, InputKeyMaps, "!" ); writeTitle( f, "Color Settings" ); for( i = 0; i < GetNumColors(); i++ ) { if( GetColorSetting( i, &c ) ) { MyFprintf( f, "setcolor %d %d %d %d\n", i, c.red, c.green, c.blue ); } } #ifdef __WIN__ writeTitle( f, "Font Settings" ); BarfFontData( f ); #endif writeTitle( f, "Window Configuration" ); doWindow( f, PCL_T_COMMANDWINDOW, &cmdlinew_info, FALSE ); doWindow( f, PCL_T_STATUSWINDOW, &statusw_info, FALSE ); doWindow( f, PCL_T_COUNTWINDOW, &repcntw_info, FALSE ); doWindow( f, PCL_T_EDITWINDOW, &editw_info, FALSE ); doWindow( f, PCL_T_FILECWINDOW, &filecw_info, FALSE ); doWindow( f, PCL_T_DIRWINDOW, &dirw_info, FALSE ); doWindow( f, PCL_T_FILEWINDOW, &filelistw_info, FALSE ); doWindow( f, PCL_T_MESSAGEWINDOW, &messagew_info, FALSE ); #ifndef __WIN__ doWindow( f, PCL_T_SETWINDOW, &setw_info, FALSE ); doWindow( f, PCL_T_LINENUMBERWINDOW, &linenumw_info, FALSE ); doWindow( f, PCL_T_EXTRAINFOWINDOW, &extraw_info, FALSE ); doWindow( f, PCL_T_SETVALWINDOW, &setvalw_info, FALSE ); doWindow( f, PCL_T_MENUWINDOW, &menuw_info, FALSE ); doWindow( f, PCL_T_MENUBARWINDOW, &menubarw_info, TRUE ); doWindow( f, PCL_T_ACTIVEMENUWINDOW, &activemenu_info, TRUE ); doWindow( f, PCL_T_GREYEDMENUWINDOW, &greyedmenu_info, TRUE ); doWindow( f, PCL_T_ACTIVEGREYEDMENUWINDOW, &activegreyedmenu_info, TRUE ); #endif writeTitle( f, "Menu Configuration" ); BarfMenuData( f ); #ifdef __WIN__ writeTitle( f, "ToolBar Configuration" ); BarfToolBarData( f ); #endif writeTitle( f, "File Type Source" ); FTSBarfData( f ); fclose( f ); if( is_cmdline ) { Message1( "Configuration file \"%s\" generated", fname ); } MemFree( buff ); return( DO_NOT_CLEAR_MESSAGE_WINDOW ); } /* GenerateConfiguration */
// Create a GDI palette from a DIB color table //************************************************************************ HPALETTE CDib::CreatePalette() //************************************************************************ { // create an identity palette from the DIB's color table return ( CreateIdentityPalette( GetColors(), GetNumColors() ) ); }
// Will read a file in DIB format and return a global HANDLE to its // BITMAPINFO. This function will work with both "old" and "new" // bitmap formats, but will always return a "new" BITMAPINFO //************************************************************************ BOOL CDib::ReadBitmapInfo( HFILE fh ) //************************************************************************ { DWORD off, size; HANDLE hbi = NULL; int i, nNumColors; LPRGBQUAD pRgb; BITMAPINFOHEADER bi; BITMAPCOREHEADER bc; BITMAPFILEHEADER bf; if ( fh < 0 ) return FALSE; off = _llseek(fh,0L,SEEK_CUR); if (sizeof(bf) != _lread(fh,(LPSTR)&bf,sizeof(bf))) return FALSE; // do we have a RC HEADER? if (bf.bfType != BFT_BITMAP) { bf.bfOffBits = 0L; _llseek(fh,off,SEEK_SET); } if (sizeof(bi) != _lread(fh,(LPSTR)&bi,sizeof(bi))) return FALSE; // what type of bitmap info is this? if ( (size = bi.biSize) == sizeof(BITMAPCOREHEADER) ) { bc = *(LPBITMAPCOREHEADER)&bi; bi.biSize = sizeof(BITMAPINFOHEADER); bi.biWidth = (DWORD)bc.bcWidth; bi.biHeight = (DWORD)bc.bcHeight; bi.biPlanes = (UINT)bc.bcPlanes; bi.biBitCount = (UINT)bc.bcBitCount; bi.biCompression = BI_RGB; bi.biSizeImage = 0; bi.biXPelsPerMeter = 0; bi.biYPelsPerMeter = 0; bi.biClrUsed = 0; bi.biClrImportant = 0; _llseek(fh,(long)sizeof(BITMAPCOREHEADER)-sizeof(BITMAPINFOHEADER),SEEK_CUR); } //!!! hack for BI_BITFIELDS if ( bi.biCompression == BI_BITFIELDS && !bi.biClrUsed ) bi.biClrUsed = 3; // Copy in the bitmap info header m_bmiHeader = bi; FixHeader(); nNumColors = GetNumColors(); pRgb = GetColors(); if (nNumColors) { if (size == sizeof(BITMAPCOREHEADER)) { // convert old color table (3 byte entries) to new (4 byte entries) _lread(fh,(LPVOID)pRgb,nNumColors * sizeof(RGBTRIPLE)); for (i=nNumColors-1; i>=0; i--) { RGBQUAD rgb; rgb.rgbRed = ((LPRGBTRIPLE)pRgb)[i].rgbtRed; rgb.rgbBlue = ((LPRGBTRIPLE)pRgb)[i].rgbtBlue; rgb.rgbGreen = ((LPRGBTRIPLE)pRgb)[i].rgbtGreen; rgb.rgbReserved = (BYTE)0; pRgb[i] = rgb; } } else { _lread(fh,(LPVOID)pRgb,nNumColors * sizeof(RGBQUAD)); } } if (bf.bfOffBits) _llseek(fh,off + bf.bfOffBits,SEEK_SET); return TRUE; }
void nsICODecoder::WriteInternal(const char* aBuffer, PRUint32 aCount) { NS_ABORT_IF_FALSE(!HasError(), "Shouldn't call WriteInternal after error!"); if (!aCount) // aCount=0 means EOF return; while (aCount && (mPos < ICONCOUNTOFFSET)) { // Skip to the # of icons. if (mPos == 2) { // if the third byte is 1: This is an icon, 2: a cursor if ((*aBuffer != 1) && (*aBuffer != 2)) { PostDataError(); return; } mIsCursor = (*aBuffer == 2); } mPos++; aBuffer++; aCount--; } if (mPos == ICONCOUNTOFFSET && aCount >= 2) { mNumIcons = LITTLE_TO_NATIVE16(((PRUint16*)aBuffer)[0]); aBuffer += 2; mPos += 2; aCount -= 2; } if (mNumIcons == 0) return; // Nothing to do. PRUint16 colorDepth = 0; // Loop through each entry's dir entry while (mCurrIcon < mNumIcons) { if (mPos >= DIRENTRYOFFSET + (mCurrIcon * sizeof(mDirEntryArray)) && mPos < DIRENTRYOFFSET + ((mCurrIcon + 1) * sizeof(mDirEntryArray))) { PRUint32 toCopy = sizeof(mDirEntryArray) - (mPos - DIRENTRYOFFSET - mCurrIcon * sizeof(mDirEntryArray)); if (toCopy > aCount) { toCopy = aCount; } memcpy(mDirEntryArray + sizeof(mDirEntryArray) - toCopy, aBuffer, toCopy); mPos += toCopy; aCount -= toCopy; aBuffer += toCopy; } if (aCount == 0) return; // Need more data IconDirEntry e; if (mPos == (DIRENTRYOFFSET + ICODIRENTRYSIZE) + (mCurrIcon * sizeof(mDirEntryArray))) { mCurrIcon++; ProcessDirEntry(e); // We can't use GetRealWidth and GetRealHeight here because those operate // on mDirEntry, here we are going through each item in the directory if (((e.mWidth == 0 ? 256 : e.mWidth) == PREFICONSIZE && (e.mHeight == 0 ? 256 : e.mHeight) == PREFICONSIZE && (e.mBitCount >= colorDepth)) || (mCurrIcon == mNumIcons && mImageOffset == 0)) { mImageOffset = e.mImageOffset; // ensure mImageOffset is >= size of the direntry headers (bug #245631) PRUint32 minImageOffset = DIRENTRYOFFSET + mNumIcons * sizeof(mDirEntryArray); if (mImageOffset < minImageOffset) { PostDataError(); return; } colorDepth = e.mBitCount; memcpy(&mDirEntry, &e, sizeof(IconDirEntry)); } } } if (mPos < mImageOffset) { // Skip to (or at least towards) the desired image offset PRUint32 toSkip = mImageOffset - mPos; if (toSkip > aCount) toSkip = aCount; mPos += toSkip; aBuffer += toSkip; aCount -= toSkip; } // If we are within the first PNGSIGNATURESIZE bytes of the image data, // then we have either a BMP or a PNG. We use the first PNGSIGNATURESIZE // bytes to determine which one we have. if (mCurrIcon == mNumIcons && mPos >= mImageOffset && mPos < mImageOffset + PNGSIGNATURESIZE) { PRUint32 toCopy = PNGSIGNATURESIZE - (mPos - mImageOffset); if (toCopy > aCount) { toCopy = aCount; } memcpy(mSignature + (mPos - mImageOffset), aBuffer, toCopy); mPos += toCopy; aCount -= toCopy; aBuffer += toCopy; mIsPNG = !memcmp(mSignature, nsPNGDecoder::pngSignatureBytes, PNGSIGNATURESIZE); if (mIsPNG) { mContainedDecoder = new nsPNGDecoder(); mContainedDecoder->InitSharedDecoder(mImage, mObserver); mContainedDecoder->Write(mSignature, PNGSIGNATURESIZE); mDataError = mContainedDecoder->HasDataError(); if (mContainedDecoder->HasDataError()) { return; } } } // If we have a PNG, let the PNG decoder do all of the rest of the work if (mIsPNG && mContainedDecoder && mPos >= mImageOffset + PNGSIGNATURESIZE) { mContainedDecoder->Write(aBuffer, aCount); mDataError = mContainedDecoder->HasDataError(); if (mContainedDecoder->HasDataError()) { return; } mPos += aCount; aBuffer += aCount; aCount = 0; // Raymond Chen says that 32bpp only are valid PNG ICOs // http://blogs.msdn.com/b/oldnewthing/archive/2010/10/22/10079192.aspx if (static_cast<nsPNGDecoder*>(mContainedDecoder.get())->HasValidInfo() && static_cast<nsPNGDecoder*>(mContainedDecoder.get())->GetPixelDepth() != 32) { PostDataError(); } return; } // We've processed all of the icon dir entries and are within the // bitmap info size if (!mIsPNG && mCurrIcon == mNumIcons && mPos >= mImageOffset && mPos >= mImageOffset + PNGSIGNATURESIZE && mPos < mImageOffset + BITMAPINFOSIZE) { // As we were decoding, we did not know if we had a PNG signature or the // start of a bitmap information header. At this point we know we had // a bitmap information header and not a PNG signature, so fill the bitmap // information header with the data it should already have. memcpy(mBIHraw, mSignature, PNGSIGNATURESIZE); // We've found the icon. PRUint32 toCopy = sizeof(mBIHraw) - (mPos - mImageOffset); if (toCopy > aCount) toCopy = aCount; memcpy(mBIHraw + (mPos - mImageOffset), aBuffer, toCopy); mPos += toCopy; aCount -= toCopy; aBuffer += toCopy; } // If we have a BMP inside the ICO and we have read the BIH header if (!mIsPNG && mPos == mImageOffset + BITMAPINFOSIZE) { // Make sure we have a sane value for the bitmap information header PRInt32 bihSize = ExtractBIHSizeFromBitmap(reinterpret_cast<PRInt8*>(mBIHraw)); if (bihSize != BITMAPINFOSIZE) { PostDataError(); return; } // We are extracting the BPP from the BIH header as it should be trusted // over the one we have from the icon header mBPP = ExtractBPPFromBitmap(reinterpret_cast<PRInt8*>(mBIHraw)); // Init the bitmap decoder which will do most of the work for us // It will do everything except the AND mask which isn't present in bitmaps // bmpDecoder is for local scope ease, it will be freed by mContainedDecoder nsBMPDecoder *bmpDecoder = new nsBMPDecoder(); mContainedDecoder = bmpDecoder; bmpDecoder->SetUseAlphaData(PR_TRUE); mContainedDecoder->SetSizeDecode(IsSizeDecode()); mContainedDecoder->InitSharedDecoder(mImage, mObserver); // The ICO format when containing a BMP does not include the 14 byte // bitmap file header. To use the code of the BMP decoder we need to // generate this header ourselves and feed it to the BMP decoder. PRInt8 bfhBuffer[BMPFILEHEADERSIZE]; if (!FillBitmapFileHeaderBuffer(bfhBuffer)) { PostDataError(); return; } mContainedDecoder->Write((const char*)bfhBuffer, sizeof(bfhBuffer)); mDataError = mContainedDecoder->HasDataError(); if (mContainedDecoder->HasDataError()) { return; } // Setup the cursor hot spot if one is present SetHotSpotIfCursor(); // Fix the height on the BMP resource FillBitmapInformationBufferHeight((PRInt8*)mBIHraw); // Write out the BMP's bitmap info header mContainedDecoder->Write(mBIHraw, sizeof(mBIHraw)); mDataError = mContainedDecoder->HasDataError(); if (mContainedDecoder->HasDataError()) { return; } // We have the size. If we're doing a size decode, we got what // we came for. if (IsSizeDecode()) return; // Sometimes the ICO BPP header field is not filled out // so we should trust the contained resource over our own // information. mBPP = bmpDecoder->GetBitsPerPixel(); // Check to make sure we have valid color settings PRUint16 numColors = GetNumColors(); if (numColors == (PRUint16)-1) { PostDataError(); return; } } // If we have a BMP if (!mIsPNG && mContainedDecoder && mPos >= mImageOffset + BITMAPINFOSIZE) { PRUint16 numColors = GetNumColors(); if (numColors == (PRUint16)-1) { PostDataError(); return; } // Feed the actual image data (not including headers) into the BMP decoder PRInt32 bmpDataOffset = mDirEntry.mImageOffset + BITMAPINFOSIZE; PRInt32 bmpDataEnd = mDirEntry.mImageOffset + BITMAPINFOSIZE + static_cast<nsBMPDecoder*>(mContainedDecoder.get())->GetCompressedImageSize() + 4 * numColors; // If we are feeding in the core image data, but we have not yet // reached the ICO's 'AND buffer mask' if (mPos >= bmpDataOffset && mPos < bmpDataEnd) { // Figure out how much data the BMP decoder wants PRUint32 toFeed = bmpDataEnd - mPos; if (toFeed > aCount) { toFeed = aCount; } mContainedDecoder->Write(aBuffer, toFeed); mDataError = mContainedDecoder->HasDataError(); if (mContainedDecoder->HasDataError()) { return; } mPos += toFeed; aCount -= toFeed; aBuffer += toFeed; } // If the bitmap is fully processed, treat any left over data as the ICO's // 'AND buffer mask' which appears after the bitmap resource. if (!mIsPNG && mPos >= bmpDataEnd) { // There may be an optional AND bit mask after the data. This is // only used if the alpha data is not already set. The alpha data // is used for 32bpp bitmaps as per the comment in ICODecoder.h // The alpha mask should be checked in all other cases. if (static_cast<nsBMPDecoder*>(mContainedDecoder.get())->GetBitsPerPixel() != 32 || !static_cast<nsBMPDecoder*>(mContainedDecoder.get())->HasAlphaData()) { PRUint32 rowSize = ((GetRealWidth() + 31) / 32) * 4; // + 31 to round up if (mPos == bmpDataEnd) { mPos++; mRowBytes = 0; mCurLine = GetRealHeight(); mRow = (PRUint8*)moz_realloc(mRow, rowSize); if (!mRow) { PostDecoderError(NS_ERROR_OUT_OF_MEMORY); return; } } // Ensure memory has been allocated before decoding. NS_ABORT_IF_FALSE(mRow, "mRow is null"); NS_ABORT_IF_FALSE(mImage, "mImage is null"); if (!mRow || !mImage) { PostDataError(); return; } while (mCurLine > 0 && aCount > 0) { PRUint32 toCopy = NS_MIN(rowSize - mRowBytes, aCount); if (toCopy) { memcpy(mRow + mRowBytes, aBuffer, toCopy); aCount -= toCopy; aBuffer += toCopy; mRowBytes += toCopy; } if (rowSize == mRowBytes) { mCurLine--; mRowBytes = 0; PRUint32* imageData = static_cast<nsBMPDecoder*>(mContainedDecoder.get())->GetImageData(); if (!imageData) { PostDataError(); return; } PRUint32* decoded = imageData + mCurLine * GetRealWidth(); PRUint32* decoded_end = decoded + GetRealWidth(); PRUint8* p = mRow, *p_end = mRow + rowSize; while (p < p_end) { PRUint8 idx = *p++; for (PRUint8 bit = 0x80; bit && decoded<decoded_end; bit >>= 1) { // Clear pixel completely for transparency. if (idx & bit) { *decoded = 0; } decoded++; } } } } }