Back out 3c3bd7bd9093 (bug 722555) because of Linux PGO compiler segfault
authorMatt Brubeck <mbrubeck@mozilla.com>
Fri, 08 Jun 2012 15:46:17 -0700
changeset 96194 ec473a671b9bbe2d7f05e56e9d1036b9b3453062
parent 96193 a7b8279ce16ac933e61fbdd3174db1776ed20ac9
child 96195 301213b90a983582b68e41a7e4203ad5d1d7c6fa
push id10448
push usermbrubeck@mozilla.com
push dateFri, 08 Jun 2012 22:47:16 +0000
treeherdermozilla-inbound@ec473a671b9b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs722555
milestone16.0a1
backs out3c3bd7bd9093ca9ddc82e5a4613dad92cba88d95
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Back out 3c3bd7bd9093 (bug 722555) because of Linux PGO compiler segfault
image/decoders/nsBMPDecoder.cpp
image/decoders/nsBMPDecoder.h
image/encoders/bmp/nsBMPEncoder.cpp
image/encoders/bmp/nsBMPEncoder.h
image/src/BMPFileHeaders.h
--- a/image/decoders/nsBMPDecoder.cpp
+++ b/image/decoders/nsBMPDecoder.cpp
@@ -33,17 +33,17 @@ nsBMPDecoder::nsBMPDecoder(RasterImage &
 {
   mColors = nsnull;
   mRow = nsnull;
   mImageData = nsnull;
   mCurPos = mPos = mNumColors = mRowBytes = 0;
   mOldLine = mCurLine = 1; // Otherwise decoder will never start
   mState = eRLEStateInitial;
   mStateData = 0;
-  mLOH = WIN_V3_HEADER_LENGTH;
+  mLOH = WIN_HEADER_LENGTH;
   mUseAlphaData = mHaveAlphaData = false;
 }
 
 nsBMPDecoder::~nsBMPDecoder()
 {
   delete[] mColors;
   if (mRow) {
       moz_free(mRow);
@@ -374,28 +374,28 @@ nsBMPDecoder::WriteInternal(const char* 
                     colorNum++;
                     break;
             }
             mPos++; aBuffer++; aCount--;
             at = (at + 1) % bytesPerColor;
         }
       }
     }
-    else if (aCount && mBIH.compression == BI_BITFIELDS && mPos < (WIN_V3_HEADER_LENGTH + BITFIELD_LENGTH)) {
+    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_V3_HEADER_LENGTH + BITFIELD_LENGTH) - mPos;
+        PRUint32 toCopy = (WIN_HEADER_LENGTH + BITFIELD_LENGTH) - mPos;
         if (toCopy > aCount)
             toCopy = aCount;
-        memcpy(mRawBuf + (mPos - WIN_V3_HEADER_LENGTH), aBuffer, toCopy);
+        memcpy(mRawBuf + (mPos - WIN_HEADER_LENGTH), aBuffer, toCopy);
         mPos += toCopy;
         aBuffer += toCopy;
         aCount -= toCopy;
     }
-    if (mPos == WIN_V3_HEADER_LENGTH + BITFIELD_LENGTH && 
+    if (mPos == WIN_HEADER_LENGTH + BITFIELD_LENGTH && 
         mBIH.compression == BI_BITFIELDS) {
         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--;
--- a/image/decoders/nsBMPDecoder.h
+++ b/image/decoders/nsBMPDecoder.h
@@ -53,18 +53,18 @@ private:
 
     /** Calculates the red-, green- and blueshift in mBitFields using
      * the bitmasks from mBitFields */
     NS_METHOD CalcBitShift();
 
     PRUint32 mPos;
 
     BMPFILEHEADER mBFH;
-    BITMAPV5HEADER mBIH;
-    char mRawBuf[WIN_V3_INTERNAL_BIH_LENGTH];
+    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
     colorTable *mColors;
 
     bitFields mBitFields;
 
--- a/image/encoders/bmp/nsBMPEncoder.cpp
+++ b/image/encoders/bmp/nsBMPEncoder.cpp
@@ -114,25 +114,24 @@ NS_IMETHODIMP nsBMPEncoder::StartImageEn
   // validate input format
   if (aInputFormat != INPUT_FORMAT_RGB &&
       aInputFormat != INPUT_FORMAT_RGBA &&
       aInputFormat != INPUT_FORMAT_HOSTARGB) {
     return NS_ERROR_INVALID_ARG;
   }
 
   // parse and check any provided output options
-  Version version;
   PRUint32 bpp;
-  nsresult rv = ParseOptions(aOutputOptions, &version, &bpp);
+  nsresult rv = ParseOptions(aOutputOptions, &bpp);
   if (NS_FAILED(rv)) {
     return rv;
   }
 
-  InitFileHeader(version, bpp, aWidth, aHeight);
-  InitInfoHeader(version, bpp, aWidth, aHeight);
+  InitFileHeader(bpp, aWidth, aHeight);
+  InitInfoHeader(bpp, aWidth, aHeight);
 
   mImageBufferSize = mBMPFileHeader.filesize;
   mImageBufferStart = static_cast<PRUint8*>(moz_malloc(mImageBufferSize));
   if (!mImageBufferStart) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
   mImageBufferCurr = mImageBufferStart;
 
@@ -196,26 +195,27 @@ NS_IMETHODIMP nsBMPEncoder::AddImageFram
       ConvertHostARGBRow(&aData[y * aStride], row, mBMPInfoHeader.width);
       if(mBMPInfoHeader.bpp == 24) {
         EncodeImageDataRow24(row);
       } else {
         EncodeImageDataRow32(row);
       }
     }
   } else if (aInputFormat == INPUT_FORMAT_RGBA) {
-    // simple RGBA, no conversion needed
+    // RBGA, but we need to strip the alpha
     for (PRInt32 y = 0; y < mBMPInfoHeader.height; y ++) {
+      StripAlpha(&aData[y * aStride], row, mBMPInfoHeader.width);
       if (mBMPInfoHeader.bpp == 24) {
         EncodeImageDataRow24(row);
       } else {
         EncodeImageDataRow32(row);
       }
     }
   } else if (aInputFormat == INPUT_FORMAT_RGB) {
-    // simple RGB, no conversion needed
+    // simple RBG(A), no conversion needed
     for (PRInt32 y = 0; y < mBMPInfoHeader.height; y ++) {
       if (mBMPInfoHeader.bpp == 24) {
         EncodeImageDataRow24(&aData[y * aStride]);
       } else { 
         EncodeImageDataRow32(&aData[y * aStride]);
       }
     }
   } else {
@@ -244,26 +244,26 @@ NS_IMETHODIMP nsBMPEncoder::EndImageEnco
 
   return NS_OK;
 }
 
 
 // Parses the encoder options and sets the bits per pixel to use
 // See InitFromData for a description of the parse options
 nsresult
-nsBMPEncoder::ParseOptions(const nsAString& aOptions, Version* version,
-                           PRUint32* bpp)
+nsBMPEncoder::ParseOptions(const nsAString& aOptions, PRUint32* bpp)
 {
-  if (version) {
-    *version = VERSION_3;
+  // If no parsing options just use the default of 24BPP
+  if (aOptions.Length() == 0) {
+    if (bpp) {
+      *bpp = 24;
+    }
+    return NS_OK;
   }
-  if (bpp) {
-    *bpp = 24;
-  }
-  
+
   // Parse the input string into a set of name/value pairs.
   // From a format like: name=value;bpp=<bpp_value>;name=value
   // to format: [0] = name=value, [1] = bpp=<bpp_value>, [2] = name=value
   nsTArray<nsCString> nameValuePairs;
   if (!ParseString(NS_ConvertUTF16toUTF8(aOptions), ';', nameValuePairs)) {
     return NS_ERROR_INVALID_ARG;
   }
 
@@ -274,29 +274,16 @@ nsBMPEncoder::ParseOptions(const nsAStri
     nsTArray<nsCString> nameValuePair;
     if (!ParseString(nameValuePairs[i], '=', nameValuePair)) {
       return NS_ERROR_INVALID_ARG;
     }
     if (nameValuePair.Length() != 2) {
       return NS_ERROR_INVALID_ARG;
     }
 
-    // Parse the bpp portion of the string name=value;version=<version_value>;
-    // name=value
-    if (nameValuePair[0].Equals("version",
-                                nsCaseInsensitiveCStringComparator())) {
-      if (nameValuePair[1].Equals("3")) {
-        *version = VERSION_3;
-      } else if (nameValuePair[1].Equals("5")) {
-        *version = VERSION_5;
-      } else {
-        return NS_ERROR_INVALID_ARG;
-      }
-    }
-
     // Parse the bpp portion of the string name=value;bpp=<bpp_value>;name=value
     if (nameValuePair[0].Equals("bpp", nsCaseInsensitiveCStringComparator())) {
       if (nameValuePair[1].Equals("24")) {
         *bpp = 24;
       } else if (nameValuePair[1].Equals("32")) {
         *bpp = 32;
       } else {
         return NS_ERROR_INVALID_ARG;
@@ -436,16 +423,32 @@ nsBMPEncoder::ConvertHostARGBRow(const P
 
       pixelOut[0] = (pixelIn & 0xff0000) >> 16;
       pixelOut[1] = (pixelIn & 0x00ff00) >>  8;
       pixelOut[2] = (pixelIn & 0x0000ff) >>  0;
     }
   }
 }
 
+// nsBMPEncoder::StripAlpha
+//
+//    Input is RGBA, output is RGB
+void
+nsBMPEncoder::StripAlpha(const PRUint8* aSrc, PRUint8* aDest,
+                         PRUint32 aPixelWidth)
+{
+  for (PRUint32 x = 0; x < aPixelWidth; x ++) {
+    const PRUint8* pixelIn = &aSrc[x * 4];
+    PRUint8* pixelOut = &aDest[x * 3];
+    pixelOut[0] = pixelIn[0];
+    pixelOut[1] = pixelIn[1];
+    pixelOut[2] = pixelIn[2];
+  }
+}
+
 void
 nsBMPEncoder::NotifyListener()
 {
   if (mCallback &&
       (GetCurrentImageBufferOffset() - mImageBufferReadPoint >= 
        mNotifyThreshold || mFinished)) {
     nsCOMPtr<nsIInputStreamCallback> callback;
     if (mCallbackTarget) {
@@ -464,204 +467,150 @@ nsBMPEncoder::NotifyListener()
     mNotifyThreshold = 0;
 
     callback->OnInputStreamReady(this);
   }
 }
 
 // Initializes the BMP file header mBMPFileHeader to the passed in values
 void 
-nsBMPEncoder::InitFileHeader(Version aVersion, PRUint32 aBPP, PRUint32 aWidth,
-                             PRUint32 aHeight)
+nsBMPEncoder::InitFileHeader(PRUint32 aBPP, PRUint32 aWidth, PRUint32 aHeight)
 {
   memset(&mBMPFileHeader, 0, sizeof(mBMPFileHeader));
   mBMPFileHeader.signature[0] = 'B';
   mBMPFileHeader.signature[1] = 'M';
   
-  if (aVersion == VERSION_3) {
-    mBMPFileHeader.dataoffset = WIN_V3_HEADER_LENGTH;
-  } else { // aVersion == 5
-    mBMPFileHeader.dataoffset = WIN_V5_HEADER_LENGTH;
-  }
+  mBMPFileHeader.dataoffset = WIN_HEADER_LENGTH;
 
   // The color table is present only if BPP is <= 8
   if (aBPP <= 8) {
     PRUint32 numColors = 1 << aBPP;
     mBMPFileHeader.dataoffset += 4 * numColors;
     mBMPFileHeader.filesize = mBMPFileHeader.dataoffset + aWidth * aHeight;
   } else {
     mBMPFileHeader.filesize = mBMPFileHeader.dataoffset + (aWidth * 
                               BytesPerPixel(aBPP) + PaddingBytes(aBPP, aWidth)) *
                               aHeight;
   }
 
   mBMPFileHeader.reserved = 0;
-
-  if (aVersion == VERSION_3) {
-    mBMPFileHeader.bihsize = WIN_V3_BIH_LENGTH;
-  } else { // aVersion == VERSION_5
-    mBMPFileHeader.bihsize = WIN_V5_BIH_LENGTH;
-  }
-}
-
-template<typename T> static void
-Encode(PRUint8** pImageBufferCurr, const T& value)
-{
-    memcpy(*pImageBufferCurr, &value, sizeof(T));
-    *pImageBufferCurr += sizeof(T);
+  mBMPFileHeader.bihsize = WIN_BIH_LENGTH;
 }
 
 // Initializes the bitmap info header mBMPInfoHeader to the passed in values
 void 
-nsBMPEncoder::InitInfoHeader(Version aVersion, PRUint32 aBPP, PRUint32 aWidth,
-                             PRUint32 aHeight)
+nsBMPEncoder::InitInfoHeader(PRUint32 aBPP, PRUint32 aWidth, PRUint32 aHeight)
 {
   memset(&mBMPInfoHeader, 0, sizeof(mBMPInfoHeader));
+  mBMPInfoHeader.bpp =  aBPP;
+  mBMPInfoHeader.planes = 1;
+  mBMPInfoHeader.colors = 0;
+  mBMPInfoHeader.important_colors = 0;
   mBMPInfoHeader.width = aWidth;
   mBMPInfoHeader.height = aHeight;
-  mBMPInfoHeader.planes = 1;
-  mBMPInfoHeader.bpp = aBPP;
   mBMPInfoHeader.compression = 0;
-  mBMPInfoHeader.colors = 0;
-  mBMPInfoHeader.important_colors = 0;
   if (aBPP <= 8) {
     mBMPInfoHeader.image_size = aWidth * aHeight;
   } else {
     mBMPInfoHeader.image_size = (aWidth * BytesPerPixel(aBPP) + 
                                  PaddingBytes(aBPP, aWidth)) * aHeight;
   }
   mBMPInfoHeader.xppm = 0;
   mBMPInfoHeader.yppm = 0;
-  if (aVersion >= VERSION_5) {
-      mBMPInfoHeader.red_mask   = 0x000000FF;
-      mBMPInfoHeader.green_mask = 0x0000FF00;
-      mBMPInfoHeader.blue_mask  = 0x00FF0000;
-      mBMPInfoHeader.alpha_mask = 0xFF000000;
-      mBMPInfoHeader.color_space = LCS_sRGB;
-      mBMPInfoHeader.white_point.r.x = 0;
-      mBMPInfoHeader.white_point.r.y = 0;
-      mBMPInfoHeader.white_point.r.z = 0;
-      mBMPInfoHeader.white_point.g.x = 0;
-      mBMPInfoHeader.white_point.g.y = 0;
-      mBMPInfoHeader.white_point.g.z = 0;
-      mBMPInfoHeader.white_point.b.x = 0;
-      mBMPInfoHeader.white_point.b.y = 0;
-      mBMPInfoHeader.white_point.b.z = 0;
-      mBMPInfoHeader.gamma_red = 0;
-      mBMPInfoHeader.gamma_green = 0;
-      mBMPInfoHeader.gamma_blue = 0;
-      mBMPInfoHeader.intent = 0;
-      mBMPInfoHeader.profile_offset = 0;
-      mBMPInfoHeader.profile_size = 0;
-      mBMPInfoHeader.reserved = 0;
-  }
-}
-
-template<typename T>
-static inline void
-ConvertToLittle(T& value)
-{
-    value = NATIVE32_TO_LITTLE(value);
 }
 
 // Encodes the BMP file header mBMPFileHeader
 void 
 nsBMPEncoder::EncodeFileHeader() 
 {  
   mozilla::image::BMPFILEHEADER littleEndianBFH = mBMPFileHeader;
-  ConvertToLittle(littleEndianBFH.filesize);
-  ConvertToLittle(littleEndianBFH.reserved);
-  ConvertToLittle(littleEndianBFH.dataoffset);
-  ConvertToLittle(littleEndianBFH.bihsize);
+  littleEndianBFH.filesize = NATIVE32_TO_LITTLE(littleEndianBFH.filesize);
+  littleEndianBFH.reserved = NATIVE32_TO_LITTLE(littleEndianBFH.reserved);
+  littleEndianBFH.dataoffset= NATIVE32_TO_LITTLE(littleEndianBFH.dataoffset);
+  littleEndianBFH.bihsize = NATIVE32_TO_LITTLE(littleEndianBFH.bihsize);
 
-  Encode(&mImageBufferCurr, littleEndianBFH.signature);
-  Encode(&mImageBufferCurr, littleEndianBFH.filesize);
-  Encode(&mImageBufferCurr, littleEndianBFH.reserved);
-  Encode(&mImageBufferCurr, littleEndianBFH.dataoffset);
-  Encode(&mImageBufferCurr, littleEndianBFH.bihsize);
+  memcpy(mImageBufferCurr, &littleEndianBFH.signature, 
+         sizeof(littleEndianBFH.signature));
+  mImageBufferCurr += sizeof(littleEndianBFH.signature);
+  memcpy(mImageBufferCurr, &littleEndianBFH.filesize, 
+         sizeof(littleEndianBFH.filesize));
+  mImageBufferCurr += sizeof(littleEndianBFH.filesize);
+  memcpy(mImageBufferCurr, &littleEndianBFH.reserved, 
+         sizeof(littleEndianBFH.reserved));
+  mImageBufferCurr += sizeof(littleEndianBFH.reserved);
+  memcpy(mImageBufferCurr, &littleEndianBFH.dataoffset, 
+         sizeof(littleEndianBFH.dataoffset));
+  mImageBufferCurr += sizeof(littleEndianBFH.dataoffset);
+  memcpy(mImageBufferCurr, &littleEndianBFH.bihsize, 
+         sizeof(littleEndianBFH.bihsize));
+  mImageBufferCurr += sizeof(littleEndianBFH.bihsize);
 }
 
 // Encodes the BMP infor header mBMPInfoHeader
 void 
 nsBMPEncoder::EncodeInfoHeader()
 {
-  mozilla::image::BITMAPV5HEADER littleEndianmBIH = mBMPInfoHeader;
-  ConvertToLittle(littleEndianmBIH.width);
-  ConvertToLittle(littleEndianmBIH.height);
-  ConvertToLittle(littleEndianmBIH.planes);
-  ConvertToLittle(littleEndianmBIH.bpp);
-  ConvertToLittle(littleEndianmBIH.compression);
-  ConvertToLittle(littleEndianmBIH.image_size);
-  ConvertToLittle(littleEndianmBIH.xppm);
-  ConvertToLittle(littleEndianmBIH.yppm);
-  ConvertToLittle(littleEndianmBIH.colors);
-  ConvertToLittle(littleEndianmBIH.important_colors);
-  ConvertToLittle(littleEndianmBIH.red_mask);
-  ConvertToLittle(littleEndianmBIH.green_mask);
-  ConvertToLittle(littleEndianmBIH.blue_mask);
-  ConvertToLittle(littleEndianmBIH.alpha_mask);
-  ConvertToLittle(littleEndianmBIH.color_space);
-  ConvertToLittle(littleEndianmBIH.white_point.r.x);
-  ConvertToLittle(littleEndianmBIH.white_point.r.y);
-  ConvertToLittle(littleEndianmBIH.white_point.r.z);
-  ConvertToLittle(littleEndianmBIH.white_point.g.x);
-  ConvertToLittle(littleEndianmBIH.white_point.g.y);
-  ConvertToLittle(littleEndianmBIH.white_point.g.z);
-  ConvertToLittle(littleEndianmBIH.white_point.b.x);
-  ConvertToLittle(littleEndianmBIH.white_point.b.y);
-  ConvertToLittle(littleEndianmBIH.white_point.b.z);
-  ConvertToLittle(littleEndianmBIH.gamma_red);
-  ConvertToLittle(littleEndianmBIH.gamma_green);
-  ConvertToLittle(littleEndianmBIH.gamma_blue);
-  ConvertToLittle(littleEndianmBIH.intent);
-  ConvertToLittle(littleEndianmBIH.profile_offset);
-  ConvertToLittle(littleEndianmBIH.profile_size);
-  
-  if (mBMPFileHeader.bihsize == OS2_BIH_LENGTH) {
-      Encode(&mImageBufferCurr, (PRUint16) littleEndianmBIH.width);
-      Encode(&mImageBufferCurr, (PRUint16) littleEndianmBIH.height);
-  } else {
-      Encode(&mImageBufferCurr, littleEndianmBIH.width);
-      Encode(&mImageBufferCurr, littleEndianmBIH.height);
+  mozilla::image::BMPINFOHEADER littleEndianmBIH = mBMPInfoHeader;
+  littleEndianmBIH.width =  NATIVE32_TO_LITTLE(littleEndianmBIH.width);
+  littleEndianmBIH.height = NATIVE32_TO_LITTLE(littleEndianmBIH.height); 
+  littleEndianmBIH.planes = NATIVE16_TO_LITTLE(littleEndianmBIH.planes);
+  littleEndianmBIH.bpp = NATIVE16_TO_LITTLE(littleEndianmBIH.bpp);
+  littleEndianmBIH.compression = NATIVE32_TO_LITTLE(
+                                 littleEndianmBIH.compression);
+  littleEndianmBIH.image_size = NATIVE32_TO_LITTLE(
+                                littleEndianmBIH.image_size);
+  littleEndianmBIH.xppm = NATIVE32_TO_LITTLE(littleEndianmBIH.xppm);
+  littleEndianmBIH.yppm = NATIVE32_TO_LITTLE(littleEndianmBIH.yppm);
+  littleEndianmBIH.colors = NATIVE32_TO_LITTLE(littleEndianmBIH.colors);
+  littleEndianmBIH.important_colors = NATIVE32_TO_LITTLE(
+                                      littleEndianmBIH.important_colors);
+
+  if (mBMPFileHeader.bihsize == 12) { // OS/2 Bitmap
+    memcpy(mImageBufferCurr, &littleEndianmBIH.width, 2);
+    mImageBufferCurr += 2; // Uint16 in OS/2 BMPs
+    memcpy(mImageBufferCurr, &littleEndianmBIH.height, 2);
+    mImageBufferCurr += 2; // Uint16 in OS/2 BMPs
+    memcpy(mImageBufferCurr, &littleEndianmBIH.planes, 
+           sizeof(littleEndianmBIH.planes));
+    mImageBufferCurr += sizeof(littleEndianmBIH.planes);
+    memcpy(mImageBufferCurr, &littleEndianmBIH.bpp, 
+           sizeof(littleEndianmBIH.bpp));
+    mImageBufferCurr += sizeof(littleEndianmBIH.bpp);
   }
-
-  Encode(&mImageBufferCurr, littleEndianmBIH.planes);
-  Encode(&mImageBufferCurr, littleEndianmBIH.bpp);
-
-  if (mBMPFileHeader.bihsize > OS2_BIH_LENGTH) {
-    Encode(&mImageBufferCurr, littleEndianmBIH.compression);
-    Encode(&mImageBufferCurr, littleEndianmBIH.image_size);
-    Encode(&mImageBufferCurr, littleEndianmBIH.xppm);
-    Encode(&mImageBufferCurr, littleEndianmBIH.yppm);
-    Encode(&mImageBufferCurr, littleEndianmBIH.colors);
-    Encode(&mImageBufferCurr, littleEndianmBIH.important_colors);
-  }
-
-  if (mBMPFileHeader.bihsize > WIN_V3_BIH_LENGTH) {
-    Encode(&mImageBufferCurr, littleEndianmBIH.red_mask);
-    Encode(&mImageBufferCurr, littleEndianmBIH.green_mask);
-    Encode(&mImageBufferCurr, littleEndianmBIH.blue_mask);
-    Encode(&mImageBufferCurr, littleEndianmBIH.alpha_mask);
-    Encode(&mImageBufferCurr, littleEndianmBIH.color_space);
-    Encode(&mImageBufferCurr, littleEndianmBIH.white_point.r.x);
-    Encode(&mImageBufferCurr, littleEndianmBIH.white_point.r.y);
-    Encode(&mImageBufferCurr, littleEndianmBIH.white_point.r.z);
-    Encode(&mImageBufferCurr, littleEndianmBIH.white_point.g.x);
-    Encode(&mImageBufferCurr, littleEndianmBIH.white_point.g.y);
-    Encode(&mImageBufferCurr, littleEndianmBIH.white_point.g.z);
-    Encode(&mImageBufferCurr, littleEndianmBIH.white_point.b.x);
-    Encode(&mImageBufferCurr, littleEndianmBIH.white_point.b.y);
-    Encode(&mImageBufferCurr, littleEndianmBIH.white_point.b.z);
-    Encode(&mImageBufferCurr, littleEndianmBIH.gamma_red);
-    Encode(&mImageBufferCurr, littleEndianmBIH.gamma_green);
-    Encode(&mImageBufferCurr, littleEndianmBIH.gamma_blue);
-    Encode(&mImageBufferCurr, littleEndianmBIH.intent);
-    Encode(&mImageBufferCurr, littleEndianmBIH.profile_offset);
-    Encode(&mImageBufferCurr, littleEndianmBIH.profile_size);
-    Encode(&mImageBufferCurr, littleEndianmBIH.reserved);
+  else {
+    memcpy(mImageBufferCurr, &littleEndianmBIH.width, 
+           sizeof(littleEndianmBIH.width));
+    mImageBufferCurr += sizeof(littleEndianmBIH.width);
+    memcpy(mImageBufferCurr, &littleEndianmBIH.height, 
+           sizeof(littleEndianmBIH.height));
+    mImageBufferCurr += sizeof(littleEndianmBIH.height);
+    memcpy(mImageBufferCurr, &littleEndianmBIH.planes, 
+           sizeof(littleEndianmBIH.planes));
+    mImageBufferCurr += sizeof(littleEndianmBIH.planes);
+    memcpy(mImageBufferCurr, &littleEndianmBIH.bpp, 
+           sizeof(littleEndianmBIH.bpp));
+    mImageBufferCurr += sizeof(littleEndianmBIH.bpp);
+    memcpy(mImageBufferCurr, &littleEndianmBIH.compression, 
+           sizeof(littleEndianmBIH.compression));
+    mImageBufferCurr += sizeof(littleEndianmBIH.compression);
+    memcpy(mImageBufferCurr, &littleEndianmBIH.image_size, 
+           sizeof(littleEndianmBIH.image_size));
+    mImageBufferCurr += sizeof(littleEndianmBIH.image_size);
+    memcpy(mImageBufferCurr, &littleEndianmBIH.xppm, 
+           sizeof(littleEndianmBIH.xppm));
+    mImageBufferCurr += sizeof(littleEndianmBIH.xppm);
+    memcpy(mImageBufferCurr, &littleEndianmBIH.yppm, 
+           sizeof(littleEndianmBIH.yppm));
+    mImageBufferCurr += sizeof(littleEndianmBIH.yppm);
+    memcpy(mImageBufferCurr, &littleEndianmBIH.colors, 
+           sizeof(littleEndianmBIH.colors));
+    mImageBufferCurr += sizeof(littleEndianmBIH.colors);
+    memcpy(mImageBufferCurr, &littleEndianmBIH.important_colors, 
+           sizeof(littleEndianmBIH.important_colors));
+    mImageBufferCurr += sizeof(littleEndianmBIH.important_colors);
   }
 }
 
 // Sets a pixel in the image buffer that doesn't have alpha data
 static inline void 
   SetPixel24(PRUint8*& imageBufferCurr, PRUint8 aRed, PRUint8 aGreen, 
   PRUint8 aBlue)
 {
--- a/image/encoders/bmp/nsBMPEncoder.h
+++ b/image/encoders/bmp/nsBMPEncoder.h
@@ -29,37 +29,31 @@ public:
   NS_DECL_IMGIENCODER
   NS_DECL_NSIINPUTSTREAM
   NS_DECL_NSIASYNCINPUTSTREAM
 
   nsBMPEncoder();
   ~nsBMPEncoder();
 
 protected:
-  enum Version {
-      VERSION_3 = 3,
-      VERSION_5 = 5
-  };
-
   // See InitData in the cpp for valid parse options
-  nsresult ParseOptions(const nsAString& aOptions, Version* version,
-                        PRUint32* bpp);
+  nsresult ParseOptions(const nsAString& aOptions, PRUint32* bpp);
   // Obtains data with no alpha in machine-independent byte order
   void ConvertHostARGBRow(const PRUint8* aSrc, PRUint8* aDest,
                           PRUint32 aPixelWidth);
+  // Strips the alpha from aSrc and puts it in aDest
+  void StripAlpha(const PRUint8* aSrc, PRUint8* aDest,
+                  PRUint32 aPixelWidth);
   // Thread safe notify listener
   void NotifyListener();
 
   // Initializes the bitmap file header member mBMPFileHeader
-  void InitFileHeader(Version aVersion, PRUint32 aBPP, PRUint32 aWidth,
-                      PRUint32 aHeight);
+  void InitFileHeader(PRUint32 aBPP, PRUint32 aWidth, PRUint32 aHeight);
   // Initializes the bitmap info header member mBMPInfoHeader
-  void InitInfoHeader(Version aVersion, PRUint32 aBPP, PRUint32 aWidth,
-                      PRUint32 aHeight);
-
+  void InitInfoHeader(PRUint32 aBPP, PRUint32 aWidth, PRUint32 aHeight);
   // Encodes the bitmap file header member mBMPFileHeader
   void EncodeFileHeader();
   // Encodes the bitmap info header member mBMPInfoHeader
   void EncodeInfoHeader();
   // Encodes a row of image data which does not have alpha data
   void EncodeImageDataRow24(const PRUint8* aData);
   // Encodes a row of image data which does have alpha data
   void EncodeImageDataRow32(const PRUint8* aData);
@@ -67,17 +61,17 @@ protected:
   inline PRInt32 GetCurrentImageBufferOffset()
   {
     return static_cast<PRInt32>(mImageBufferCurr - mImageBufferStart);
   }
 
   // These headers will always contain endian independent stuff 
   // They store the BMP headers which will be encoded
   mozilla::image::BMPFILEHEADER mBMPFileHeader;
-  mozilla::image::BITMAPV5HEADER mBMPInfoHeader;
+  mozilla::image::BMPINFOHEADER mBMPInfoHeader;
 
   // Keeps track of the start of the image buffer
   PRUint8* mImageBufferStart;
   // Keeps track of the current position in the image buffer
   PRUint8* mImageBufferCurr;
   // Keeps track of the image buffer size
   PRUint32 mImageBufferSize;
   // Keeps track of the number of bytes in the image buffer which are read
--- a/image/src/BMPFileHeaders.h
+++ b/image/src/BMPFileHeaders.h
@@ -19,64 +19,36 @@ namespace mozilla {
 
 // The length of the bitmap file header as defined in the BMP spec.
 #define BFH_LENGTH 14 
 // Internally we store the bitmap file header with an additional 4 bytes which
 // is used to store the bitmap information header size.
 #define BFH_INTERNAL_LENGTH 18
 
 #define OS2_INTERNAL_BIH_LENGTH 8
-#define WIN_V3_INTERNAL_BIH_LENGTH 36
-#define WIN_V5_INTERNAL_BIH_LENGTH 120
+#define WIN_INTERNAL_BIH_LENGTH 36
 
 #define OS2_BIH_LENGTH 12 // This is the real BIH size (as contained in the bihsize field of BMPFILEHEADER)
-#define WIN_V3_BIH_LENGTH 40 // This is the real BIH size (as contained in the bihsize field of BMPFILEHEADER)
-#define WIN_V5_BIH_LENGTH 124 // This is the real BIH size (as contained in the bihsize field of BMPFILEHEADER)
+#define WIN_BIH_LENGTH 40 // This is the real BIH size (as contained in the bihsize field of BMPFILEHEADER)
 
 #define OS2_HEADER_LENGTH (BFH_INTERNAL_LENGTH + OS2_INTERNAL_BIH_LENGTH)
-#define WIN_V3_HEADER_LENGTH (BFH_INTERNAL_LENGTH + WIN_V3_INTERNAL_BIH_LENGTH)
-#define WIN_V5_HEADER_LENGTH (BFH_INTERNAL_LENGTH + WIN_V5_INTERNAL_BIH_LENGTH)
+#define WIN_HEADER_LENGTH (BFH_INTERNAL_LENGTH + WIN_INTERNAL_BIH_LENGTH)
 
-#define LCS_sRGB 0x73524742
-    
-    struct xyz {
-      PRInt32 x, y, z;
-    };
-
-    struct xyzTriple {
-      xyz r, g, b;
-    };
-
-    struct BITMAPV5HEADER {
+    struct BMPINFOHEADER {
       PRInt32 width; // Uint16 in OS/2 BMPs
       PRInt32 height; // Uint16 in OS/2 BMPs
       PRUint16 planes; // =1
       PRUint16 bpp; // Bits per pixel.
       // The rest of the header is not available in OS/2 BMP Files
       PRUint32 compression; // 0=no compression 1=8bit RLE 2=4bit RLE
       PRUint32 image_size; // (compressed) image size. Can be 0 if compression==0
       PRUint32 xppm; // Pixels per meter, horizontal
       PRUint32 yppm; // Pixels per meter, vertical
       PRUint32 colors; // Used Colors
       PRUint32 important_colors; // Number of important colors. 0=all
-      PRUint32 red_mask;   // Bits used for red component
-      PRUint32 green_mask; // Bits used for green component
-      PRUint32 blue_mask;  // Bits used for blue component
-      PRUint32 alpha_mask; // Bits used for alpha component
-      PRUint32 color_space; // 0x73524742=LCS_sRGB ...
-      // These members are unused unless color_space == LCS_CALIBRATED_RGB
-      xyzTriple white_point; // Logical white point
-      PRUint32 gamma_red;   // Red gamma component
-      PRUint32 gamma_green; // Green gamma component
-      PRUint32 gamma_blue;  // Blue gamma component
-      PRUint32 intent; // Rendering intent
-      // These members are unused unless color_space == LCS_PROFILE_*
-      PRUint32 profile_offset; // Offset to profile data in bytes
-      PRUint32 profile_size; // Size of profile data in bytes
-      PRUint32 reserved; // =0
     };
 
     struct colorTable {
       PRUint8 red;
       PRUint8 green;
       PRUint8 blue;
     };