Bug 1218823 - use UniquePtr<> in preference to delete[] in image/; r=seth
authorNathan Froyd <froydnj@mozilla.com>
Tue, 27 Oct 2015 10:47:51 -0400
changeset 305033 912688ff102a86671bb7318e562f82f3519e4c93
parent 305032 e7929212ce5c8ca6511ad5b425e2c821bc1aa174
child 305034 1a1d5630602c120dddc54c931fa3227a729d1153
push id1001
push userraliiev@mozilla.com
push dateMon, 18 Jan 2016 19:06:03 +0000
treeherdermozilla-release@8b89261f3ac4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersseth
bugs1218823
milestone44.0a1
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
Bug 1218823 - use UniquePtr<> in preference to delete[] in image/; r=seth
image/SourceBuffer.h
image/decoders/icon/win/nsIconChannel.cpp
image/decoders/nsBMPDecoder.cpp
image/decoders/nsBMPDecoder.h
image/encoders/jpeg/nsJPEGEncoder.cpp
image/encoders/png/nsPNGEncoder.cpp
--- a/image/SourceBuffer.h
+++ b/image/SourceBuffer.h
@@ -268,63 +268,61 @@ private:
   class Chunk
   {
   public:
     explicit Chunk(size_t aCapacity)
       : mCapacity(aCapacity)
       , mLength(0)
     {
       MOZ_ASSERT(aCapacity > 0, "Creating zero-capacity chunk");
-      mData = new (fallible) char[mCapacity];
+      mData.reset(new (fallible) char[mCapacity]);
     }
 
-    ~Chunk() { delete[] mData; }
-
     Chunk(Chunk&& aOther)
       : mCapacity(aOther.mCapacity)
       , mLength(aOther.mLength)
-      , mData(aOther.mData)
+      , mData(Move(aOther.mData))
     {
       aOther.mCapacity = aOther.mLength = 0;
       aOther.mData = nullptr;
     }
 
     Chunk& operator=(Chunk&& aOther)
     {
       mCapacity = aOther.mCapacity;
       mLength = aOther.mLength;
-      mData = aOther.mData;
+      mData = Move(aOther.mData);
       aOther.mCapacity = aOther.mLength = 0;
       aOther.mData = nullptr;
       return *this;
     }
 
     bool AllocationFailed() const { return !mData; }
     size_t Capacity() const { return mCapacity; }
     size_t Length() const { return mLength; }
 
     char* Data() const
     {
       MOZ_ASSERT(mData, "Allocation failed but nobody checked for it");
-      return mData;
+      return mData.get();
     }
 
     void AddLength(size_t aAdditionalLength)
     {
       MOZ_ASSERT(mLength + aAdditionalLength <= mCapacity);
       mLength += aAdditionalLength;
     }
 
   private:
     Chunk(const Chunk&) = delete;
     Chunk& operator=(const Chunk&) = delete;
 
     size_t mCapacity;
     size_t mLength;
-    char* mData;
+    UniquePtr<char[]> mData;
   };
 
   nsresult AppendChunk(Maybe<Chunk>&& aChunk);
   Maybe<Chunk> CreateChunk(size_t aCapacity, bool aRoundUp = true);
   nsresult Compact();
   static size_t RoundedUpCapacity(size_t aCapacity);
   size_t FibonacciCapacityWithMinimum(size_t aMinCapacity);
 
--- a/image/decoders/icon/win/nsIconChannel.cpp
+++ b/image/decoders/icon/win/nsIconChannel.cpp
@@ -570,21 +570,21 @@ nsIconChannel::MakeInputStream(nsIInputS
           (colorTableSize = GetColorTableSize(&colorHeader)) >= 0 &&
           (maskTableSize  = GetColorTableSize(&maskHeader))  >= 0) {
         uint32_t iconSize = sizeof(ICONFILEHEADER) +
                             sizeof(ICONENTRY) +
                             sizeof(BITMAPINFOHEADER) +
                             colorHeader.biSizeImage +
                             maskHeader.biSizeImage;
 
-        char* buffer = new char[iconSize];
+        UniquePtr<char[]> buffer = MakeUnique<char[]>(iconSize);
         if (!buffer) {
           rv = NS_ERROR_OUT_OF_MEMORY;
         } else {
-          char* whereTo = buffer;
+          char* whereTo = buffer.get();
           int howMuch;
 
           // the data starts with an icon file header
           ICONFILEHEADER iconHeader;
           iconHeader.ifhReserved = 0;
           iconHeader.ifhType = 1;
           iconHeader.ifhCount = 1;
           howMuch = sizeof(ICONFILEHEADER);
@@ -635,27 +635,26 @@ nsIconChannel::MakeInputStream(nsIInputS
               // Now, create a pipe and stuff our data into it
               nsCOMPtr<nsIInputStream> inStream;
               nsCOMPtr<nsIOutputStream> outStream;
               rv = NS_NewPipe(getter_AddRefs(inStream),
                               getter_AddRefs(outStream),
                               iconSize, iconSize, aNonBlocking);
               if (NS_SUCCEEDED(rv)) {
                 uint32_t written;
-                rv = outStream->Write(buffer, iconSize, &written);
+                rv = outStream->Write(buffer.get(), iconSize, &written);
                 if (NS_SUCCEEDED(rv)) {
                   NS_ADDREF(*_retval = inStream);
                 }
               }
 
             } // if we got bitmap bits
             delete maskInfo;
           } // if we got mask bits
           delete colorInfo;
-          delete [] buffer;
         } // if we allocated the buffer
       } // if we got mask size
 
       DeleteDC(hDC);
       DeleteObject(iconInfo.hbmColor);
       DeleteObject(iconInfo.hbmMask);
     } // if we got icon info
     DestroyIcon(hIcon);
--- a/image/decoders/nsBMPDecoder.cpp
+++ b/image/decoders/nsBMPDecoder.cpp
@@ -132,30 +132,31 @@ using namespace bmp;
 static void
 SetPixel(uint32_t*& aDecoded, uint8_t aRed, uint8_t aGreen,
          uint8_t aBlue, uint8_t aAlpha = 0xFF)
 {
   *aDecoded++ = gfxPackedPixel(aAlpha, aRed, aGreen, aBlue);
 }
 
 static void
-SetPixel(uint32_t*& aDecoded, uint8_t idx, bmp::ColorTableEntry* aColors)
+SetPixel(uint32_t*& aDecoded, uint8_t idx,
+         const UniquePtr<ColorTableEntry[]>& aColors)
 {
   SetPixel(aDecoded,
            aColors[idx].mRed, aColors[idx].mGreen, aColors[idx].mBlue);
 }
 
 /// Sets two (or one if aCount = 1) pixels
 /// @param aDecoded where the data is stored. Will be moved 4 resp 8 bytes
 /// depending on whether one or two pixels are written.
 /// @param aData The values for the two pixels
 /// @param aCount Current count. Is decremented by one or two.
 static void
 Set4BitPixel(uint32_t*& aDecoded, uint8_t aData, uint32_t& aCount,
-             bmp::ColorTableEntry* aColors)
+             const UniquePtr<ColorTableEntry[]>& aColors)
 {
   uint8_t idx = aData >> 4;
   SetPixel(aDecoded, idx, aColors);
   if (--aCount > 0) {
     idx = aData & 0xF;
     SetPixel(aDecoded, idx, aColors);
     --aCount;
   }
@@ -186,17 +187,16 @@ nsBMPDecoder::nsBMPDecoder(RasterImage* 
   , mAbsoluteModeNumPixels(0)
 {
   memset(&mBFH, 0, sizeof(mBFH));
   memset(&mBIH, 0, sizeof(mBIH));
 }
 
 nsBMPDecoder::~nsBMPDecoder()
 {
-  delete[] mColors;
 }
 
 // Obtains the bits per pixel from the internal BIH header.
 int32_t
 nsBMPDecoder::GetBitsPerPixel() const
 {
   return mBIH.bpp;
 }
@@ -666,18 +666,18 @@ nsBMPDecoder::ReadBitfields(const char* 
   if (mBIH.bpp <= 8) {
     mNumColors = 1 << mBIH.bpp;
     if (0 < mBIH.colors && mBIH.colors < mNumColors) {
       mNumColors = mBIH.colors;
     }
 
     // Always allocate and zero 256 entries, even though mNumColors might be
     // smaller, because the file might erroneously index past mNumColors.
-    mColors = new ColorTableEntry[256];
-    memset(mColors, 0, 256 * sizeof(ColorTableEntry));
+    mColors = MakeUnique<ColorTableEntry[]>(256);
+    memset(mColors.get(), 0, 256 * sizeof(ColorTableEntry));
 
     // OS/2 Bitmaps have no padding byte.
     mBytesPerColor = (mBIH.bihsize == InfoHeaderLength::WIN_V2) ? 3 : 4;
   }
 
   MOZ_ASSERT(!mImageData, "Already have a buffer allocated?");
   IntSize targetSize = mDownscaler ? mDownscaler->TargetSize() : GetSize();
   nsresult rv = AllocateFrame(/* aFrameNum = */ 0, targetSize,
--- a/image/decoders/nsBMPDecoder.h
+++ b/image/decoders/nsBMPDecoder.h
@@ -6,16 +6,17 @@
 
 #ifndef mozilla_image_decoders_nsBMPDecoder_h
 #define mozilla_image_decoders_nsBMPDecoder_h
 
 #include "BMPFileHeaders.h"
 #include "Decoder.h"
 #include "gfxColor.h"
 #include "StreamingLexer.h"
+#include "mozilla/UniquePtr.h"
 
 namespace mozilla {
 namespace image {
 
 namespace bmp {
 
 /// An entry in the color table.
 struct ColorTableEntry {
@@ -185,17 +186,17 @@ private:
   bool mMayHaveTransparency;
 
   // Does the image have transparency? Determined during full decoding, so only
   // use this after that has been completed.
   bool mDoesHaveTransparency;
 
   uint32_t mNumColors;      // The number of used colors, i.e. the number of
                             // entries in mColors, if it's present.
-  bmp::ColorTableEntry* mColors; // The color table, if it's present.
+  UniquePtr<bmp::ColorTableEntry[]> mColors; // The color table, if it's present.
   uint32_t mBytesPerColor;  // 3 or 4, depending on the format
 
   // The number of bytes prior to the optional gap that have been read. This
   // is used to find the start of the pixel data.
   uint32_t mPreGapLength;
 
   uint32_t mPixelRowSize;   // The number of bytes per pixel row.
 
--- a/image/encoders/jpeg/nsJPEGEncoder.cpp
+++ b/image/encoders/jpeg/nsJPEGEncoder.cpp
@@ -157,29 +157,29 @@ nsJPEGEncoder::InitFromData(const uint8_
 
   // feed it the rows
   if (aInputFormat == INPUT_FORMAT_RGB) {
     while (cinfo.next_scanline < cinfo.image_height) {
       const uint8_t* row = &aData[cinfo.next_scanline * aStride];
       jpeg_write_scanlines(&cinfo, const_cast<uint8_t**>(&row), 1);
     }
   } else if (aInputFormat == INPUT_FORMAT_RGBA) {
-    uint8_t* row = new uint8_t[aWidth * 3];
+    UniquePtr<uint8_t[]> rowptr = MakeUnique<uint8_t[]>(aWidth * 3);
+    uint8_t* row = rowptr.get();
     while (cinfo.next_scanline < cinfo.image_height) {
       ConvertRGBARow(&aData[cinfo.next_scanline * aStride], row, aWidth);
       jpeg_write_scanlines(&cinfo, &row, 1);
     }
-    delete[] row;
   } else if (aInputFormat == INPUT_FORMAT_HOSTARGB) {
-    uint8_t* row = new uint8_t[aWidth * 3];
+    UniquePtr<uint8_t[]> rowptr = MakeUnique<uint8_t[]>(aWidth * 3);
+    uint8_t* row = rowptr.get();
     while (cinfo.next_scanline < cinfo.image_height) {
       ConvertHostARGBRow(&aData[cinfo.next_scanline * aStride], row, aWidth);
       jpeg_write_scanlines(&cinfo, &row, 1);
     }
-    delete[] row;
   }
 
   jpeg_finish_compress(&cinfo);
   jpeg_destroy_compress(&cinfo);
 
   mFinished = true;
   NotifyListener();
 
--- a/image/encoders/png/nsPNGEncoder.cpp
+++ b/image/encoders/png/nsPNGEncoder.cpp
@@ -282,32 +282,28 @@ nsPNGEncoder::AddImageFrame(const uint8_
   png_set_filter(mPNG, PNG_FILTER_TYPE_BASE, PNG_FILTER_VALUE_NONE);
 #endif
 
   // write each row: if we add more input formats, we may want to
   // generalize the conversions
   if (aInputFormat == INPUT_FORMAT_HOSTARGB) {
     // PNG requires RGBA with post-multiplied alpha, so we need to
     // convert
-    uint8_t* row = new uint8_t[aWidth * 4];
+    UniquePtr<uint8_t[]> row = MakeUnique<uint8_t[]>(aWidth * 4);
     for (uint32_t y = 0; y < aHeight; y++) {
-      ConvertHostARGBRow(&aData[y * aStride], row, aWidth, useTransparency);
-      png_write_row(mPNG, row);
+      ConvertHostARGBRow(&aData[y * aStride], row.get(), aWidth, useTransparency);
+      png_write_row(mPNG, row.get());
     }
-    delete[] row;
-
   } else if (aInputFormat == INPUT_FORMAT_RGBA && !useTransparency) {
     // RBGA, but we need to strip the alpha
-    uint8_t* row = new uint8_t[aWidth * 4];
+    UniquePtr<uint8_t[]> row = MakeUnique<uint8_t[]>(aWidth * 4);
     for (uint32_t y = 0; y < aHeight; y++) {
-      StripAlpha(&aData[y * aStride], row, aWidth);
-      png_write_row(mPNG, row);
+      StripAlpha(&aData[y * aStride], row.get(), aWidth);
+      png_write_row(mPNG, row.get());
     }
-    delete[] row;
-
   } else if (aInputFormat == INPUT_FORMAT_RGB ||
              aInputFormat == INPUT_FORMAT_RGBA) {
     // simple RBG(A), no conversion needed
     for (uint32_t y = 0; y < aHeight; y++) {
       png_write_row(mPNG, (uint8_t*)&aData[y * aStride]);
     }
 
   } else {