Bug 1530774 - Part 2. Remove support for paletted surface pipes. r=tnikkel
authorAndrew Osmond <aosmond@mozilla.com>
Mon, 11 Mar 2019 14:05:59 -0400
changeset 464730 6dd55ee8961128d0c9e314d60e7509604e7548b2
parent 464729 e3315d7842089083b389fc666b51c693c05924fc
child 464731 52390d9090fbd8d46b00ea29034e7039511ff8a4
push id112472
push useraosmond@gmail.com
push dateMon, 18 Mar 2019 11:30:51 +0000
treeherdermozilla-inbound@52390d9090fb [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstnikkel
bugs1530774
milestone68.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 1530774 - Part 2. Remove support for paletted surface pipes. r=tnikkel Differential Revision: https://phabricator.services.mozilla.com/D23715
image/DownscalingFilter.h
image/SurfaceFilters.h
image/SurfacePipe.cpp
image/SurfacePipe.h
image/SurfacePipeFactory.h
image/test/gtest/TestADAM7InterpolatingFilter.cpp
image/test/gtest/TestDeinterlacingFilter.cpp
image/test/gtest/TestDownscalingFilter.cpp
image/test/gtest/TestRemoveFrameRectFilter.cpp
image/test/gtest/TestSurfacePipeIntegration.cpp
image/test/gtest/TestSurfaceSink.cpp
--- a/image/DownscalingFilter.h
+++ b/image/DownscalingFilter.h
@@ -107,20 +107,16 @@ class DownscalingFilter final : public S
 
   template <typename... Rest>
   nsresult Configure(const DownscalingConfig& aConfig, const Rest&... aRest) {
     nsresult rv = mNext.Configure(aRest...);
     if (NS_FAILED(rv)) {
       return rv;
     }
 
-    if (mNext.IsValidPalettedPipe()) {
-      NS_WARNING("Created a downscaler for a paletted surface?");
-      return NS_ERROR_INVALID_ARG;
-    }
     if (mNext.InputSize() == aConfig.mInputSize) {
       NS_WARNING("Created a downscaler, but not downscaling?");
       return NS_ERROR_INVALID_ARG;
     }
     if (mNext.InputSize().width > aConfig.mInputSize.width) {
       NS_WARNING("Created a downscaler, but width is larger");
       return NS_ERROR_INVALID_ARG;
     }
--- a/image/SurfaceFilters.h
+++ b/image/SurfaceFilters.h
@@ -69,25 +69,16 @@ class DeinterlacingFilter final : public
   template <typename... Rest>
   nsresult Configure(const DeinterlacingConfig<PixelType>& aConfig,
                      const Rest&... aRest) {
     nsresult rv = mNext.Configure(aRest...);
     if (NS_FAILED(rv)) {
       return rv;
     }
 
-    if (sizeof(PixelType) == 1 && !mNext.IsValidPalettedPipe()) {
-      NS_WARNING("Paletted DeinterlacingFilter used with non-paletted pipe?");
-      return NS_ERROR_INVALID_ARG;
-    }
-    if (sizeof(PixelType) == 4 && mNext.IsValidPalettedPipe()) {
-      NS_WARNING("Non-paletted DeinterlacingFilter used with paletted pipe?");
-      return NS_ERROR_INVALID_ARG;
-    }
-
     gfx::IntSize outputSize = mNext.InputSize();
     mProgressiveDisplay = aConfig.mProgressiveDisplay;
 
     const uint32_t bufferSize =
         outputSize.width * outputSize.height * sizeof(PixelType);
 
     // Use the size of the SurfaceCache as a heuristic to avoid gigantic
     // allocations. Even if DownscalingFilter allowed us to allocate space for
@@ -110,20 +101,16 @@ class DeinterlacingFilter final : public
 
     // Clear the buffer to avoid writing uninitialized memory to the output.
     memset(mBuffer.get(), 0, bufferSize);
 
     ConfigureFilter(outputSize, sizeof(PixelType));
     return NS_OK;
   }
 
-  bool IsValidPalettedPipe() const override {
-    return sizeof(PixelType) == 1 && mNext.IsValidPalettedPipe();
-  }
-
   Maybe<SurfaceInvalidRect> TakeInvalidRect() override {
     return mNext.TakeInvalidRect();
   }
 
  protected:
   uint8_t* DoResetToFirstRow() override {
     mNext.ResetToFirstRow();
     mPass = 0;
@@ -776,21 +763,16 @@ class RemoveFrameRectFilter final : publ
   template <typename... Rest>
   nsresult Configure(const RemoveFrameRectConfig& aConfig,
                      const Rest&... aRest) {
     nsresult rv = mNext.Configure(aRest...);
     if (NS_FAILED(rv)) {
       return rv;
     }
 
-    if (mNext.IsValidPalettedPipe()) {
-      NS_WARNING("RemoveFrameRectFilter used with paletted pipe?");
-      return NS_ERROR_INVALID_ARG;
-    }
-
     mFrameRect = mUnclampedFrameRect = aConfig.mFrameRect;
     gfx::IntSize outputSize = mNext.InputSize();
 
     // Forbid frame rects with negative size.
     if (aConfig.mFrameRect.Width() < 0 || aConfig.mFrameRect.Height() < 0) {
       return NS_ERROR_INVALID_ARG;
     }
 
@@ -1006,21 +988,16 @@ class ADAM7InterpolatingFilter final : p
   template <typename... Rest>
   nsresult Configure(const ADAM7InterpolatingConfig& aConfig,
                      const Rest&... aRest) {
     nsresult rv = mNext.Configure(aRest...);
     if (NS_FAILED(rv)) {
       return rv;
     }
 
-    if (mNext.IsValidPalettedPipe()) {
-      NS_WARNING("ADAM7InterpolatingFilter used with paletted pipe?");
-      return NS_ERROR_INVALID_ARG;
-    }
-
     // We have two intermediate buffers, one for the previous row with final
     // pixel values and one for the row that the previous filter in the chain is
     // currently writing to.
     size_t inputWidthInBytes = mNext.InputSize().width * sizeof(uint32_t);
     mPreviousRow.reset(new (fallible) uint8_t[inputWidthInBytes]);
     if (MOZ_UNLIKELY(!mPreviousRow)) {
       return NS_ERROR_OUT_OF_MEMORY;
     }
--- a/image/SurfacePipe.cpp
+++ b/image/SurfacePipe.cpp
@@ -95,56 +95,10 @@ uint8_t* SurfaceSink::GetRowPointer() co
   MOZ_ASSERT(rowPtr >= mImageData);
   MOZ_ASSERT(rowPtr < mImageData + mImageDataLength);
   MOZ_ASSERT(rowPtr + InputSize().width * sizeof(uint32_t) <=
              mImageData + mImageDataLength);
 
   return rowPtr;
 }
 
-nsresult PalettedSurfaceSink::Configure(const PalettedSurfaceConfig& aConfig) {
-  MOZ_ASSERT(aConfig.mFormat == SurfaceFormat::B8G8R8A8);
-
-  // For paletted surfaces, the surface size is the size of the frame rect.
-  IntSize surfaceSize = aConfig.mFrameRect.Size();
-
-  // Allocate the frame.
-  // XXX(seth): Once every Decoder subclass uses SurfacePipe, we probably want
-  // to allocate the frame directly here and get rid of Decoder::AllocateFrame
-  // altogether.
-  nsresult rv = aConfig.mDecoder->AllocateFrame(
-      aConfig.mOutputSize, aConfig.mFrameRect, aConfig.mFormat,
-      aConfig.mPaletteDepth, aConfig.mAnimParams);
-  if (NS_FAILED(rv)) {
-    return rv;
-  }
-
-  mImageData = aConfig.mDecoder->mImageData;
-  mImageDataLength = aConfig.mDecoder->mImageDataLength;
-  mFlipVertically = aConfig.mFlipVertically;
-  mFrameRect = aConfig.mFrameRect;
-
-  MOZ_ASSERT(mImageData);
-  MOZ_ASSERT(
-      mImageDataLength ==
-      uint32_t(mFrameRect.Width() * mFrameRect.Height() * sizeof(uint8_t)));
-
-  ConfigureFilter(surfaceSize, sizeof(uint8_t));
-  return NS_OK;
-}
-
-uint8_t* PalettedSurfaceSink::GetRowPointer() const {
-  // If we're flipping vertically, reverse the order in which we traverse the
-  // rows.
-  uint32_t row = mFlipVertically ? InputSize().height - (mRow + 1) : mRow;
-
-  uint8_t* rowPtr = mImageData + row * InputSize().width * sizeof(uint8_t);
-
-  MOZ_ASSERT(rowPtr >= mImageData);
-  MOZ_ASSERT(rowPtr < mImageData + mImageDataLength);
-  MOZ_ASSERT(rowPtr + InputSize().width * sizeof(uint8_t) <=
-             mImageData + mImageDataLength);
-
-  return rowPtr;
-}
-
 }  // namespace image
 }  // namespace mozilla
--- a/image/SurfacePipe.h
+++ b/image/SurfacePipe.h
@@ -419,19 +419,16 @@ class SurfaceFilter {
     return IsSurfaceFinished() ? WriteState::FINISHED
                                : WriteState::NEED_MORE_DATA;
   }
 
   //////////////////////////////////////////////////////////////////////////////
   // Methods Subclasses Should Override
   //////////////////////////////////////////////////////////////////////////////
 
-  /// @return true if this SurfaceFilter can be used with paletted surfaces.
-  virtual bool IsValidPalettedPipe() const { return false; }
-
   /**
    * @return a SurfaceInvalidRect representing the region of the surface that
    *         has been written to since the last time TakeInvalidRect() was
    *         called, or Nothing() if the region is empty (i.e. nothing has been
    *         written).
    */
   virtual Maybe<SurfaceInvalidRect> TakeInvalidRect() = 0;
 
@@ -742,67 +739,25 @@ struct SurfaceConfig {
   Decoder* mDecoder;           /// Which Decoder to use to allocate the surface.
   gfx::IntSize mOutputSize;    /// The size of the surface.
   gfx::SurfaceFormat mFormat;  /// The surface format (BGRA or BGRX).
   bool mFlipVertically;        /// If true, write the rows from bottom to top.
   Maybe<AnimationParams> mAnimParams;  /// Given for animated images.
 };
 
 /**
- * A sink for normal (i.e., non-paletted) surfaces. It handles the allocation of
- * the surface and protects against buffer overflow. This sink should be used
- * for all non-animated images and for the first frame of animated images.
+ * A sink for surfaces. It handles the allocation of the surface and protects
+ * against buffer overflow. This sink should be used for images.
  *
  * Sinks must always be at the end of the SurfaceFilter chain.
  */
 class SurfaceSink final : public AbstractSurfaceSink {
  public:
   nsresult Configure(const SurfaceConfig& aConfig);
 
  protected:
   uint8_t* GetRowPointer() const override;
 };
 
-class PalettedSurfaceSink;
-
-struct PalettedSurfaceConfig {
-  using Filter = PalettedSurfaceSink;
-  Decoder* mDecoder;           /// Which Decoder to use to allocate the surface.
-  gfx::IntSize mOutputSize;    /// The logical size of the surface.
-  gfx::IntRect mFrameRect;     /// The surface subrect which contains data.
-  gfx::SurfaceFormat mFormat;  /// The surface format (BGRA or BGRX).
-  uint8_t mPaletteDepth;       /// The palette depth of this surface.
-  bool mFlipVertically;        /// If true, write the rows from bottom to top.
-  Maybe<AnimationParams> mAnimParams;  /// Given for animated images.
-};
-
-/**
- * A sink for paletted surfaces. It handles the allocation of the surface and
- * protects against buffer overflow. This sink can be used for frames of
- * animated images except the first.
- *
- * Sinks must always be at the end of the SurfaceFilter chain.
- *
- * XXX(seth): We'll remove all support for paletted surfaces in bug 1247520,
- * which means we can remove PalettedSurfaceSink entirely.
- */
-class PalettedSurfaceSink final : public AbstractSurfaceSink {
- public:
-  bool IsValidPalettedPipe() const override { return true; }
-
-  nsresult Configure(const PalettedSurfaceConfig& aConfig);
-
- protected:
-  uint8_t* GetRowPointer() const override;
-
- private:
-  /**
-   * The surface subrect which contains data. Note that the surface size we
-   * actually allocate is the size of the frame rect, not the logical size of
-   * the surface.
-   */
-  gfx::IntRect mFrameRect;
-};
-
 }  // namespace image
 }  // namespace mozilla
 
 #endif  // mozilla_image_SurfacePipe_h
--- a/image/SurfacePipeFactory.h
+++ b/image/SurfacePipeFactory.h
@@ -190,66 +190,16 @@ class SurfacePipeFactory {
           pipe = MakePipe(surfaceConfig);
         }
       }
     }
 
     return pipe;
   }
 
-  /**
-   * Creates and initializes a paletted SurfacePipe.
-   *
-   * XXX(seth): We'll remove all support for paletted surfaces in bug 1247520,
-   * which means we can remove CreatePalettedSurfacePipe() entirely.
-   *
-   * @param aDecoder The decoder whose current frame the SurfacePipe will write
-   *                 to.
-   * @param aInputSize The original size of the image.
-   * @param aFrameRect The portion of the image that actually contains data.
-   * @param aFormat The surface format of the image; generally B8G8R8A8 or
-   *                B8G8R8X8.
-   * @param aPaletteDepth The palette depth of the image.
-   * @param aAnimParams Extra parameters used by animated images.
-   * @param aFlags Flags enabling or disabling various functionality for the
-   *               SurfacePipe; see the SurfacePipeFlags documentation for more
-   *               information.
-   *
-   * @return A SurfacePipe if the parameters allowed one to be created
-   *         successfully, or Nothing() if the SurfacePipe could not be
-   *         initialized.
-   */
-  static Maybe<SurfacePipe> CreatePalettedSurfacePipe(
-      Decoder* aDecoder, const nsIntSize& aInputSize,
-      const nsIntRect& aFrameRect, gfx::SurfaceFormat aFormat,
-      uint8_t aPaletteDepth, const Maybe<AnimationParams>& aAnimParams,
-      SurfacePipeFlags aFlags) {
-    const bool deinterlace = bool(aFlags & SurfacePipeFlags::DEINTERLACE);
-    const bool flipVertically =
-        bool(aFlags & SurfacePipeFlags::FLIP_VERTICALLY);
-    const bool progressiveDisplay =
-        bool(aFlags & SurfacePipeFlags::PROGRESSIVE_DISPLAY);
-
-    // Construct configurations for the SurfaceFilters.
-    DeinterlacingConfig<uint8_t> deinterlacingConfig{progressiveDisplay};
-    PalettedSurfaceConfig palettedSurfaceConfig{
-        aDecoder,      aInputSize,     aFrameRect, aFormat,
-        aPaletteDepth, flipVertically, aAnimParams};
-
-    Maybe<SurfacePipe> pipe;
-
-    if (deinterlace) {
-      pipe = MakePipe(deinterlacingConfig, palettedSurfaceConfig);
-    } else {
-      pipe = MakePipe(palettedSurfaceConfig);
-    }
-
-    return pipe;
-  }
-
  private:
   template <typename... Configs>
   static Maybe<SurfacePipe> MakePipe(const Configs&... aConfigs) {
     auto pipe = MakeUnique<typename detail::FilterPipeline<Configs...>::Type>();
     nsresult rv = pipe->Configure(aConfigs...);
     if (NS_FAILED(rv)) {
       return Nothing();
     }
--- a/image/test/gtest/TestADAM7InterpolatingFilter.cpp
+++ b/image/test/gtest/TestADAM7InterpolatingFilter.cpp
@@ -588,21 +588,8 @@ TEST(ImageADAM7InterpolatingFilter, ADAM
   // A 0x0 input size is invalid, so configuration should fail.
   AssertConfiguringADAM7InterpolatingFilterFails(IntSize(0, 0));
 }
 
 TEST(ImageADAM7InterpolatingFilter, ADAM7InterpolationFailsForMinus1_Minus1) {
   // A negative input size is invalid, so configuration should fail.
   AssertConfiguringADAM7InterpolatingFilterFails(IntSize(-1, -1));
 }
-
-TEST(ImageADAM7InterpolatingFilter,
-     ConfiguringPalettedADAM7InterpolatingFilterFails) {
-  RefPtr<Decoder> decoder = CreateTrivialDecoder();
-  ASSERT_TRUE(decoder != nullptr);
-
-  // ADAM7InterpolatingFilter does not support paletted images, so configuration
-  // should fail.
-  AssertConfiguringPipelineFails(
-      decoder, ADAM7InterpolatingConfig{},
-      PalettedSurfaceConfig{decoder, IntSize(100, 100), IntRect(0, 0, 50, 50),
-                            SurfaceFormat::B8G8R8A8, 8, false});
-}
--- a/image/test/gtest/TestDeinterlacingFilter.cpp
+++ b/image/test/gtest/TestDeinterlacingFilter.cpp
@@ -25,28 +25,16 @@ void WithDeinterlacingFilter(const IntSi
   ASSERT_TRUE(bool(decoder));
 
   WithFilterPipeline(
       decoder, std::forward<Func>(aFunc),
       DeinterlacingConfig<uint32_t>{aProgressiveDisplay},
       SurfaceConfig{decoder, aSize, SurfaceFormat::B8G8R8A8, false});
 }
 
-template <typename Func>
-void WithPalettedDeinterlacingFilter(const IntSize& aSize, Func aFunc) {
-  RefPtr<Decoder> decoder = CreateTrivialDecoder();
-  ASSERT_TRUE(decoder != nullptr);
-
-  WithFilterPipeline(
-      decoder, std::forward<Func>(aFunc),
-      DeinterlacingConfig<uint8_t>{/* mProgressiveDisplay = */ true},
-      PalettedSurfaceConfig{decoder, aSize, IntRect(0, 0, 100, 100),
-                            SurfaceFormat::B8G8R8A8, 8, false});
-}
-
 void AssertConfiguringDeinterlacingFilterFails(const IntSize& aSize) {
   RefPtr<Decoder> decoder = CreateTrivialDecoder();
   ASSERT_TRUE(decoder != nullptr);
 
   AssertConfiguringPipelineFails(
       decoder, DeinterlacingConfig<uint32_t>{/* mProgressiveDisplay = */ true},
       SurfaceConfig{decoder, aSize, SurfaceFormat::B8G8R8A8, false});
 }
@@ -111,23 +99,16 @@ TEST_F(ImageDeinterlacingFilter, WritePi
                           [](Decoder* aDecoder, SurfaceFilter* aFilter) {
                             CheckWritePixels(
                                 aDecoder, aFilter,
                                 /* aOutputRect = */ Some(IntRect(0, 0, 1, 1)),
                                 /* aInputRect = */ Some(IntRect(0, 0, 1, 1)));
                           });
 }
 
-TEST_F(ImageDeinterlacingFilter, PalettedWritePixels) {
-  WithPalettedDeinterlacingFilter(
-      IntSize(100, 100), [](Decoder* aDecoder, SurfaceFilter* aFilter) {
-        CheckPalettedWritePixels(aDecoder, aFilter);
-      });
-}
-
 TEST_F(ImageDeinterlacingFilter, WritePixelsNonProgressiveOutput51_52) {
   WithDeinterlacingFilter(
       IntSize(51, 52), /* aProgressiveDisplay = */ false,
       [](Decoder* aDecoder, SurfaceFilter* aFilter) {
         // Fill the image. The output should be green for even rows and red for
         // odd rows but we need to write the rows in the order that the
         // deinterlacer expects them.
         uint32_t count = 0;
--- a/image/test/gtest/TestDownscalingFilter.cpp
+++ b/image/test/gtest/TestDownscalingFilter.cpp
@@ -209,20 +209,8 @@ TEST(ImageDownscalingFilter, WritePixels
         EXPECT_TRUE(RowsAreSolidColor(surface, 6, 3, BGRAColor::Red(),
                                       /* aFuzz = */ 3));
         EXPECT_TRUE(RowsAreSolidColor(surface, 11, 3, BGRAColor::Green(),
                                       /* aFuzz = */ 3));
         EXPECT_TRUE(RowsAreSolidColor(surface, 16, 4, BGRAColor::Red(),
                                       /* aFuzz = */ 3));
       });
 }
-
-TEST(ImageDownscalingFilter, ConfiguringPalettedDownscaleFails) {
-  RefPtr<Decoder> decoder = CreateTrivialDecoder();
-  ASSERT_TRUE(decoder != nullptr);
-
-  // DownscalingFilter does not support paletted images, so configuration should
-  // fail.
-  AssertConfiguringPipelineFails(
-      decoder, DownscalingConfig{IntSize(100, 100), SurfaceFormat::B8G8R8A8},
-      PalettedSurfaceConfig{decoder, IntSize(20, 20), IntRect(0, 0, 20, 20),
-                            SurfaceFormat::B8G8R8A8, 8, false});
-}
--- a/image/test/gtest/TestRemoveFrameRectFilter.cpp
+++ b/image/test/gtest/TestRemoveFrameRectFilter.cpp
@@ -284,20 +284,8 @@ TEST(ImageRemoveFrameRectFilter, RemoveF
 }
 
 TEST(ImageRemoveFrameRectFilter,
      RemoveFrameRectFailsFor100_100_to_0_0_Minus1_Minus1) {
   // A negative size frame rect is disallowed.
   AssertConfiguringRemoveFrameRectFilterFails(IntSize(100, 100),
                                               IntRect(0, 0, -1, -1));
 }
-
-TEST(ImageRemoveFrameRectFilter, ConfiguringPalettedRemoveFrameRectFails) {
-  RefPtr<Decoder> decoder = CreateTrivialDecoder();
-  ASSERT_TRUE(decoder != nullptr);
-
-  // RemoveFrameRectFilter does not support paletted images, so configuration
-  // should fail.
-  AssertConfiguringPipelineFails(
-      decoder, RemoveFrameRectConfig{IntRect(0, 0, 50, 50)},
-      PalettedSurfaceConfig{decoder, IntSize(100, 100), IntRect(0, 0, 50, 50),
-                            SurfaceFormat::B8G8R8A8, 8, false});
-}
--- a/image/test/gtest/TestSurfacePipeIntegration.cpp
+++ b/image/test/gtest/TestSurfacePipeIntegration.cpp
@@ -75,57 +75,16 @@ void CheckSurfacePipeMethodResults(Surfa
   EXPECT_EQ(IntRect(0, 0, 100, 100), invalidRect->mOutputSpaceRect);
 
   aPipe->ResetToFirstRow();
   EXPECT_FALSE(aPipe->IsSurfaceFinished());
   invalidRect = aPipe->TakeInvalidRect();
   EXPECT_TRUE(invalidRect.isNothing());
 }
 
-void CheckPalettedSurfacePipeMethodResults(
-    SurfacePipe* aPipe, Decoder* aDecoder,
-    const IntRect& aRect = IntRect(0, 0, 100, 100)) {
-  // Check that the pipeline ended up in the state we expect.  Note that we're
-  // explicitly testing the SurfacePipe versions of these methods, so we don't
-  // want to use AssertCorrectPipelineFinalState() here.
-  EXPECT_TRUE(aPipe->IsSurfaceFinished());
-  Maybe<SurfaceInvalidRect> invalidRect = aPipe->TakeInvalidRect();
-  EXPECT_TRUE(invalidRect.isSome());
-  EXPECT_EQ(IntRect(0, 0, 100, 100), invalidRect->mInputSpaceRect);
-  EXPECT_EQ(IntRect(0, 0, 100, 100), invalidRect->mOutputSpaceRect);
-
-  // Check the generated image.
-  CheckGeneratedPalettedImage(aDecoder, aRect);
-
-  // Reset and clear the image before the next test.
-  aPipe->ResetToFirstRow();
-  EXPECT_FALSE(aPipe->IsSurfaceFinished());
-  invalidRect = aPipe->TakeInvalidRect();
-  EXPECT_TRUE(invalidRect.isNothing());
-
-  uint32_t count = 0;
-  auto result = aPipe->WritePixels<uint8_t>([&]() {
-    ++count;
-    return AsVariant(uint8_t(0));
-  });
-  EXPECT_EQ(WriteState::FINISHED, result);
-  EXPECT_EQ(100u * 100u, count);
-
-  EXPECT_TRUE(aPipe->IsSurfaceFinished());
-  invalidRect = aPipe->TakeInvalidRect();
-  EXPECT_TRUE(invalidRect.isSome());
-  EXPECT_EQ(IntRect(0, 0, 100, 100), invalidRect->mInputSpaceRect);
-  EXPECT_EQ(IntRect(0, 0, 100, 100), invalidRect->mOutputSpaceRect);
-
-  aPipe->ResetToFirstRow();
-  EXPECT_FALSE(aPipe->IsSurfaceFinished());
-  invalidRect = aPipe->TakeInvalidRect();
-  EXPECT_TRUE(invalidRect.isNothing());
-}
-
 class ImageSurfacePipeIntegration : public ::testing::Test {
  protected:
   AutoInitializeImageLib mInit;
 };
 
 TEST_F(ImageSurfacePipeIntegration, SurfacePipe) {
   // Test that SurfacePipe objects can be initialized and move constructed.
   SurfacePipe pipe = TestSurfacePipeFactory::SimpleSurfacePipe();
@@ -220,110 +179,16 @@ TEST_F(ImageSurfacePipeIntegration, Surf
     CheckSurfacePipeMethodResults(&pipe, decoder, IntRect(0, 0, 0, 0));
   }
 
   // Mark the frame as finished so we don't get an assertion.
   RawAccessFrameRef currentFrame = decoder->GetCurrentFrameRef();
   currentFrame->Finish();
 }
 
-TEST_F(ImageSurfacePipeIntegration, PalettedSurfacePipe) {
-  // Create a SurfacePipe containing a PalettedSurfaceSink.
-  RefPtr<Decoder> decoder = CreateTrivialDecoder();
-  ASSERT_TRUE(decoder != nullptr);
-
-  auto sink = MakeUnique<PalettedSurfaceSink>();
-  nsresult rv = sink->Configure(
-      PalettedSurfaceConfig{decoder, IntSize(100, 100), IntRect(0, 0, 100, 100),
-                            SurfaceFormat::B8G8R8A8, 8, false});
-  ASSERT_TRUE(NS_SUCCEEDED(rv));
-
-  SurfacePipe pipe = TestSurfacePipeFactory::SurfacePipeFromPipeline(sink);
-
-  // Test that WritePixels() gets passed through to the underlying pipeline.
-  {
-    uint32_t count = 0;
-    auto result = pipe.WritePixels<uint8_t>([&]() {
-      ++count;
-      return AsVariant(uint8_t(255));
-    });
-    EXPECT_EQ(WriteState::FINISHED, result);
-    EXPECT_EQ(100u * 100u, count);
-    CheckPalettedSurfacePipeMethodResults(&pipe, decoder);
-  }
-
-  // Create a buffer the same size as one row of the surface, containing all
-  // 255 pixels. We'll use this for the WriteBuffer() tests.
-  uint8_t buffer[100];
-  for (int i = 0; i < 100; ++i) {
-    buffer[i] = 255;
-  }
-
-  // Test that WriteBuffer() gets passed through to the underlying pipeline.
-  {
-    uint32_t count = 0;
-    WriteState result = WriteState::NEED_MORE_DATA;
-    while (result == WriteState::NEED_MORE_DATA) {
-      result = pipe.WriteBuffer(buffer);
-      ++count;
-    }
-    EXPECT_EQ(WriteState::FINISHED, result);
-    EXPECT_EQ(100u, count);
-    CheckPalettedSurfacePipeMethodResults(&pipe, decoder);
-  }
-
-  // Test that the 3 argument version of WriteBuffer() gets passed through to
-  // the underlying pipeline.
-  {
-    uint32_t count = 0;
-    WriteState result = WriteState::NEED_MORE_DATA;
-    while (result == WriteState::NEED_MORE_DATA) {
-      result = pipe.WriteBuffer(buffer, 0, 100);
-      ++count;
-    }
-    EXPECT_EQ(WriteState::FINISHED, result);
-    EXPECT_EQ(100u, count);
-    CheckPalettedSurfacePipeMethodResults(&pipe, decoder);
-  }
-
-  // Test that WritePixelBlocks() gets passed through to the underlying
-  // pipeline.
-  {
-    uint32_t count = 0;
-    WriteState result = pipe.WritePixelBlocks<uint8_t>(
-        [&](uint8_t* aBlockStart, int32_t aLength) {
-          ++count;
-          EXPECT_EQ(int32_t(100), aLength);
-          memcpy(aBlockStart, buffer, 100 * sizeof(uint8_t));
-          return MakeTuple(int32_t(100), Maybe<WriteState>());
-        });
-
-    EXPECT_EQ(WriteState::FINISHED, result);
-    EXPECT_EQ(100u, count);
-    CheckPalettedSurfacePipeMethodResults(&pipe, decoder);
-  }
-
-  // Test that WriteEmptyRow() gets passed through to the underlying pipeline.
-  {
-    uint32_t count = 0;
-    WriteState result = WriteState::NEED_MORE_DATA;
-    while (result == WriteState::NEED_MORE_DATA) {
-      result = pipe.WriteEmptyRow();
-      ++count;
-    }
-    EXPECT_EQ(WriteState::FINISHED, result);
-    EXPECT_EQ(100u, count);
-    CheckPalettedSurfacePipeMethodResults(&pipe, decoder, IntRect(0, 0, 0, 0));
-  }
-
-  // Mark the frame as finished so we don't get an assertion.
-  RawAccessFrameRef currentFrame = decoder->GetCurrentFrameRef();
-  currentFrame->Finish();
-}
-
 TEST_F(ImageSurfacePipeIntegration, DeinterlaceDownscaleWritePixels) {
   RefPtr<Decoder> decoder = CreateTrivialDecoder();
   ASSERT_TRUE(decoder != nullptr);
 
   auto test = [](Decoder* aDecoder, SurfaceFilter* aFilter) {
     CheckWritePixels(aDecoder, aFilter,
                      /* aOutputRect = */ Some(IntRect(0, 0, 25, 25)));
   };
@@ -463,44 +328,16 @@ TEST_F(ImageSurfacePipeIntegration,
   WithFilterPipeline(
       decoder, test,
       DeinterlacingConfig<uint32_t>{/* mProgressiveDisplay = */ true},
       RemoveFrameRectConfig{IntRect(50, 50, 100, 100)},
       DownscalingConfig{IntSize(100, 100), SurfaceFormat::B8G8R8A8},
       SurfaceConfig{decoder, IntSize(20, 20), SurfaceFormat::B8G8R8A8, false});
 }
 
-TEST_F(ImageSurfacePipeIntegration,
-       ConfiguringPalettedRemoveFrameRectDownscaleFails) {
-  RefPtr<Decoder> decoder = CreateTrivialDecoder();
-  ASSERT_TRUE(decoder != nullptr);
-
-  // This is an invalid pipeline for paletted images, so configuration should
-  // fail.
-  AssertConfiguringPipelineFails(
-      decoder, RemoveFrameRectConfig{IntRect(0, 0, 50, 50)},
-      DownscalingConfig{IntSize(100, 100), SurfaceFormat::B8G8R8A8},
-      PalettedSurfaceConfig{decoder, IntSize(100, 100), IntRect(0, 0, 50, 50),
-                            SurfaceFormat::B8G8R8A8, 8, false});
-}
-
-TEST_F(ImageSurfacePipeIntegration,
-       ConfiguringPalettedDeinterlaceDownscaleFails) {
-  RefPtr<Decoder> decoder = CreateTrivialDecoder();
-  ASSERT_TRUE(decoder != nullptr);
-
-  // This is an invalid pipeline for paletted images, so configuration should
-  // fail.
-  AssertConfiguringPipelineFails(
-      decoder, DeinterlacingConfig<uint8_t>{/* mProgressiveDisplay = */ true},
-      DownscalingConfig{IntSize(100, 100), SurfaceFormat::B8G8R8A8},
-      PalettedSurfaceConfig{decoder, IntSize(100, 100), IntRect(0, 0, 20, 20),
-                            SurfaceFormat::B8G8R8A8, 8, false});
-}
-
 TEST_F(ImageSurfacePipeIntegration, ConfiguringHugeDeinterlacingBufferFails) {
   RefPtr<Decoder> decoder = CreateTrivialDecoder();
   ASSERT_TRUE(decoder != nullptr);
 
   // When DownscalingFilter is used, we may succeed in allocating an output
   // surface for huge images, because we only need to store the scaled-down
   // version of the image. However, regardless of downscaling,
   // DeinterlacingFilter needs to allocate a buffer as large as the size of the
--- a/image/test/gtest/TestSurfaceSink.cpp
+++ b/image/test/gtest/TestSurfaceSink.cpp
@@ -41,27 +41,16 @@ void WithSurfaceSink(Func aFunc) {
 
   const bool flipVertically = Orientation == Orient::FLIP_VERTICALLY;
 
   WithFilterPipeline(decoder, std::forward<Func>(aFunc),
                      SurfaceConfig{decoder, IntSize(100, 100),
                                    SurfaceFormat::B8G8R8A8, flipVertically});
 }
 
-template <typename Func>
-void WithPalettedSurfaceSink(const IntRect& aFrameRect, Func aFunc) {
-  RefPtr<Decoder> decoder = CreateTrivialDecoder();
-  ASSERT_TRUE(decoder != nullptr);
-
-  WithFilterPipeline(
-      decoder, std::forward<Func>(aFunc),
-      PalettedSurfaceConfig{decoder, IntSize(100, 100), aFrameRect,
-                            SurfaceFormat::B8G8R8A8, 8, false});
-}
-
 void ResetForNextPass(SurfaceFilter* aSink) {
   aSink->ResetToFirstRow();
   EXPECT_FALSE(aSink->IsSurfaceFinished());
   Maybe<SurfaceInvalidRect> invalidRect = aSink->TakeInvalidRect();
   EXPECT_TRUE(invalidRect.isNothing());
 }
 
 template <typename WriteFunc, typename CheckFunc>
@@ -90,28 +79,16 @@ void CheckIterativeWrite(Decoder* aDecod
                          const IntRect& aOutputRect, WriteFunc aWriteFunc) {
   // Ignore the row passed to WriteFunc, since no callers use it.
   auto writeFunc = [&](uint32_t) { return aWriteFunc(); };
 
   DoCheckIterativeWrite(aSink, writeFunc,
                         [&] { CheckGeneratedImage(aDecoder, aOutputRect); });
 }
 
-template <typename WriteFunc>
-void CheckPalettedIterativeWrite(Decoder* aDecoder, PalettedSurfaceSink* aSink,
-                                 const IntRect& aOutputRect,
-                                 WriteFunc aWriteFunc) {
-  // Ignore the row passed to WriteFunc, since no callers use it.
-  auto writeFunc = [&](uint32_t) { return aWriteFunc(); };
-
-  DoCheckIterativeWrite(aSink, writeFunc, [&] {
-    CheckGeneratedPalettedImage(aDecoder, aOutputRect);
-  });
-}
-
 TEST(ImageSurfaceSink, SurfaceSinkInitialization) {
   WithSurfaceSink<Orient::NORMAL>([](Decoder* aDecoder, SurfaceSink* aSink) {
     // Check initial state.
     EXPECT_FALSE(aSink->IsSurfaceFinished());
     Maybe<SurfaceInvalidRect> invalidRect = aSink->TakeInvalidRect();
     EXPECT_TRUE(invalidRect.isNothing());
 
     // Check that the surface is zero-initialized. We verify this by calling
@@ -956,580 +933,8 @@ TEST(ImageSurfaceSink, SurfaceSinkFlipVe
 
       // Check that the generated image is correct.
       RawAccessFrameRef currentFrame = aDecoder->GetCurrentFrameRef();
       RefPtr<SourceSurface> surface = currentFrame->GetSourceSurface();
       EXPECT_TRUE(IsSolidColor(surface, BGRAColor::Green()));
     }
   });
 }
-
-TEST(ImageSurfaceSink, PalettedSurfaceSinkInitialization) {
-  WithPalettedSurfaceSink(
-      IntRect(0, 0, 100, 100),
-      [](Decoder* aDecoder, PalettedSurfaceSink* aSink) {
-        // Check initial state.
-        EXPECT_FALSE(aSink->IsSurfaceFinished());
-        Maybe<SurfaceInvalidRect> invalidRect = aSink->TakeInvalidRect();
-        EXPECT_TRUE(invalidRect.isNothing());
-
-        // Check that the paletted image data is zero-initialized.
-        RawAccessFrameRef currentFrame = aDecoder->GetCurrentFrameRef();
-        uint8_t* imageData = nullptr;
-        uint32_t imageLength = 0;
-        currentFrame->GetImageData(&imageData, &imageLength);
-        ASSERT_TRUE(imageData != nullptr);
-        ASSERT_EQ(100u * 100u, imageLength);
-        for (uint32_t i = 0; i < imageLength; ++i) {
-          ASSERT_EQ(uint8_t(0), imageData[i]);
-        }
-      });
-}
-
-TEST(ImageSurfaceSink, PalettedSurfaceSinkWritePixelsFor0_0_100_100) {
-  WithPalettedSurfaceSink(IntRect(0, 0, 100, 100),
-                          [](Decoder* aDecoder, PalettedSurfaceSink* aSink) {
-                            CheckPalettedWritePixels(aDecoder, aSink);
-                          });
-}
-
-TEST(ImageSurfaceSink, PalettedSurfaceSinkWritePixelsFor25_25_50_50) {
-  WithPalettedSurfaceSink(
-      IntRect(25, 25, 50, 50),
-      [](Decoder* aDecoder, PalettedSurfaceSink* aSink) {
-        CheckPalettedWritePixels(
-            aDecoder, aSink,
-            /* aOutputRect = */ Some(IntRect(0, 0, 50, 50)),
-            /* aInputRect = */ Some(IntRect(0, 0, 50, 50)),
-            /* aInputWriteRect = */ Some(IntRect(25, 25, 50, 50)),
-            /* aOutputWriteRect = */ Some(IntRect(25, 25, 50, 50)));
-      });
-}
-
-TEST(ImageSurfaceSink, PalettedSurfaceSinkWritePixelsForMinus25_Minus25_50_50) {
-  WithPalettedSurfaceSink(
-      IntRect(-25, -25, 50, 50),
-      [](Decoder* aDecoder, PalettedSurfaceSink* aSink) {
-        CheckPalettedWritePixels(
-            aDecoder, aSink,
-            /* aOutputRect = */ Some(IntRect(0, 0, 50, 50)),
-            /* aInputRect = */ Some(IntRect(0, 0, 50, 50)),
-            /* aInputWriteRect = */ Some(IntRect(-25, -25, 50, 50)),
-            /* aOutputWriteRect = */ Some(IntRect(-25, -25, 50, 50)));
-      });
-}
-
-TEST(ImageSurfaceSink, PalettedSurfaceSinkWritePixelsFor75_Minus25_50_50) {
-  WithPalettedSurfaceSink(
-      IntRect(75, -25, 50, 50),
-      [](Decoder* aDecoder, PalettedSurfaceSink* aSink) {
-        CheckPalettedWritePixels(
-            aDecoder, aSink,
-            /* aOutputRect = */ Some(IntRect(0, 0, 50, 50)),
-            /* aInputRect = */ Some(IntRect(0, 0, 50, 50)),
-            /* aInputWriteRect = */ Some(IntRect(75, -25, 50, 50)),
-            /* aOutputWriteRect = */ Some(IntRect(75, -25, 50, 50)));
-      });
-}
-
-TEST(ImageSurfaceSink, PalettedSurfaceSinkWritePixelsForMinus25_75_50_50) {
-  WithPalettedSurfaceSink(
-      IntRect(-25, 75, 50, 50),
-      [](Decoder* aDecoder, PalettedSurfaceSink* aSink) {
-        CheckPalettedWritePixels(
-            aDecoder, aSink,
-            /* aOutputRect = */ Some(IntRect(0, 0, 50, 50)),
-            /* aInputRect = */ Some(IntRect(0, 0, 50, 50)),
-            /* aInputWriteRect = */ Some(IntRect(-25, 75, 50, 50)),
-            /* aOutputWriteRect = */ Some(IntRect(-25, 75, 50, 50)));
-      });
-}
-
-TEST(ImageSurfaceSink, PalettedSurfaceSinkWritePixelsFor75_75_50_50) {
-  WithPalettedSurfaceSink(
-      IntRect(75, 75, 50, 50),
-      [](Decoder* aDecoder, PalettedSurfaceSink* aSink) {
-        CheckPalettedWritePixels(
-            aDecoder, aSink,
-            /* aOutputRect = */ Some(IntRect(0, 0, 50, 50)),
-            /* aInputRect = */ Some(IntRect(0, 0, 50, 50)),
-            /* aInputWriteRect = */ Some(IntRect(75, 75, 50, 50)),
-            /* aOutputWriteRect = */ Some(IntRect(75, 75, 50, 50)));
-      });
-}
-
-TEST(ImageSurfaceSink, PalettedSurfaceSinkWritePixelsFinish) {
-  WithPalettedSurfaceSink(IntRect(0, 0, 100, 100),
-                          [](Decoder* aDecoder, PalettedSurfaceSink* aSink) {
-                            // Write nothing into the surface; just finish
-                            // immediately.
-                            uint32_t count = 0;
-                            auto result = aSink->WritePixels<uint8_t>([&] {
-                              count++;
-                              return AsVariant(WriteState::FINISHED);
-                            });
-                            EXPECT_EQ(WriteState::FINISHED, result);
-                            EXPECT_EQ(1u, count);
-
-                            AssertCorrectPipelineFinalState(
-                                aSink, IntRect(0, 0, 100, 100),
-                                IntRect(0, 0, 100, 100));
-
-                            // Attempt to write more and make sure that nothing
-                            // gets written.
-                            count = 0;
-                            result = aSink->WritePixels<uint8_t>([&]() {
-                              count++;
-                              return AsVariant(uint8_t(128));
-                            });
-                            EXPECT_EQ(WriteState::FINISHED, result);
-                            EXPECT_EQ(0u, count);
-                            EXPECT_TRUE(aSink->IsSurfaceFinished());
-
-                            // Check that the generated image is correct.
-                            EXPECT_TRUE(IsSolidPalettedColor(aDecoder, 0));
-                          });
-}
-
-TEST(ImageSurfaceSink, PalettedSurfaceSinkWritePixelsEarlyExit) {
-  auto checkEarlyExit = [](Decoder* aDecoder, PalettedSurfaceSink* aSink,
-                           WriteState aState) {
-    // Write half a row of green pixels and then exit early with |aState|. If
-    // the lambda keeps getting called, we'll write red pixels, which will cause
-    // the test to fail.
-    uint32_t count = 0;
-    auto result = aSink->WritePixels<uint8_t>([&]() -> NextPixel<uint8_t> {
-      if (count == 50) {
-        return AsVariant(aState);
-      }
-      return count++ < 50 ? AsVariant(uint8_t(255)) : AsVariant(uint8_t(128));
-    });
-
-    EXPECT_EQ(aState, result);
-    EXPECT_EQ(50u, count);
-    CheckGeneratedPalettedImage(aDecoder, IntRect(0, 0, 50, 1));
-
-    if (aState != WriteState::FINISHED) {
-      // We should still be able to write more at this point.
-      EXPECT_FALSE(aSink->IsSurfaceFinished());
-
-      // Verify that we can resume writing. We'll finish up the same row.
-      count = 0;
-      result = aSink->WritePixels<uint8_t>([&]() -> NextPixel<uint8_t> {
-        if (count == 50) {
-          return AsVariant(WriteState::NEED_MORE_DATA);
-        }
-        ++count;
-        return AsVariant(uint8_t(255));
-      });
-
-      EXPECT_EQ(WriteState::NEED_MORE_DATA, result);
-      EXPECT_EQ(50u, count);
-      EXPECT_FALSE(aSink->IsSurfaceFinished());
-      CheckGeneratedPalettedImage(aDecoder, IntRect(0, 0, 100, 1));
-
-      return;
-    }
-
-    // We should've finished the surface at this point.
-    AssertCorrectPipelineFinalState(aSink, IntRect(0, 0, 100, 100),
-                                    IntRect(0, 0, 100, 100));
-
-    // Attempt to write more and make sure that nothing gets written.
-    count = 0;
-    result = aSink->WritePixels<uint8_t>([&] {
-      count++;
-      return AsVariant(uint8_t(128));
-    });
-
-    EXPECT_EQ(WriteState::FINISHED, result);
-    EXPECT_EQ(0u, count);
-    EXPECT_TRUE(aSink->IsSurfaceFinished());
-
-    // Check that the generated image is still correct.
-    CheckGeneratedPalettedImage(aDecoder, IntRect(0, 0, 50, 1));
-  };
-
-  WithPalettedSurfaceSink(IntRect(0, 0, 100, 100),
-                          [&](Decoder* aDecoder, PalettedSurfaceSink* aSink) {
-                            checkEarlyExit(aDecoder, aSink,
-                                           WriteState::NEED_MORE_DATA);
-                          });
-
-  WithPalettedSurfaceSink(IntRect(0, 0, 100, 100),
-                          [&](Decoder* aDecoder, PalettedSurfaceSink* aSink) {
-                            checkEarlyExit(aDecoder, aSink,
-                                           WriteState::FAILURE);
-                          });
-
-  WithPalettedSurfaceSink(IntRect(0, 0, 100, 100),
-                          [&](Decoder* aDecoder, PalettedSurfaceSink* aSink) {
-                            checkEarlyExit(aDecoder, aSink,
-                                           WriteState::FINISHED);
-                          });
-}
-
-TEST(ImageSurfaceSink, PalettedSurfaceSinkWritePixelsToRow) {
-  WithPalettedSurfaceSink(
-      IntRect(0, 0, 100, 100),
-      [](Decoder* aDecoder, PalettedSurfaceSink* aSink) {
-        // Write the first 99 rows of our 100x100 surface and verify that even
-        // though our lambda will yield pixels forever, only one row is written
-        // per call to WritePixelsToRow().
-        for (int row = 0; row < 99; ++row) {
-          uint32_t count = 0;
-          WriteState result = aSink->WritePixelsToRow<uint8_t>([&] {
-            ++count;
-            return AsVariant(uint8_t(255));
-          });
-
-          EXPECT_EQ(WriteState::NEED_MORE_DATA, result);
-          EXPECT_EQ(100u, count);
-          EXPECT_FALSE(aSink->IsSurfaceFinished());
-
-          Maybe<SurfaceInvalidRect> invalidRect = aSink->TakeInvalidRect();
-          EXPECT_TRUE(invalidRect.isSome());
-          EXPECT_EQ(IntRect(0, row, 100, 1), invalidRect->mInputSpaceRect);
-          EXPECT_EQ(IntRect(0, row, 100, 1), invalidRect->mOutputSpaceRect);
-
-          CheckGeneratedPalettedImage(aDecoder, IntRect(0, 0, 100, row + 1));
-        }
-
-        // Write the final line, which should finish the surface.
-        uint32_t count = 0;
-        WriteState result = aSink->WritePixelsToRow<uint8_t>([&] {
-          ++count;
-          return AsVariant(uint8_t(255));
-        });
-
-        EXPECT_EQ(WriteState::FINISHED, result);
-        EXPECT_EQ(100u, count);
-
-        // Note that the final invalid rect we expect here is only the last row;
-        // that's because we called TakeInvalidRect() repeatedly in the loop
-        // above.
-        AssertCorrectPipelineFinalState(aSink, IntRect(0, 99, 100, 1),
-                                        IntRect(0, 99, 100, 1));
-
-        // Check that the generated image is correct.
-        CheckGeneratedPalettedImage(aDecoder, IntRect(0, 0, 100, 100));
-
-        // Attempt to write more and make sure that nothing gets written.
-        count = 0;
-        result = aSink->WritePixelsToRow<uint8_t>([&] {
-          count++;
-          return AsVariant(uint8_t(128));
-        });
-
-        EXPECT_EQ(WriteState::FINISHED, result);
-        EXPECT_EQ(0u, count);
-        EXPECT_TRUE(aSink->IsSurfaceFinished());
-
-        // Check that the generated image is still correct.
-        CheckGeneratedPalettedImage(aDecoder, IntRect(0, 0, 100, 100));
-      });
-}
-
-TEST(ImageSurfaceSink, PalettedSurfaceSinkWritePixelsToRowEarlyExit) {
-  auto checkEarlyExit = [](Decoder* aDecoder, PalettedSurfaceSink* aSink,
-                           WriteState aState) {
-    // Write half a row of 255s and then exit early with |aState|. If the lambda
-    // keeps getting called, we'll write 128s, which will cause the test to
-    // fail.
-    uint32_t count = 0;
-    auto result = aSink->WritePixelsToRow<uint8_t>([&]() -> NextPixel<uint8_t> {
-      if (count == 50) {
-        return AsVariant(aState);
-      }
-      return count++ < 50 ? AsVariant(uint8_t(255)) : AsVariant(uint8_t(128));
-    });
-
-    EXPECT_EQ(aState, result);
-    EXPECT_EQ(50u, count);
-    CheckGeneratedPalettedImage(aDecoder, IntRect(0, 0, 50, 1));
-
-    if (aState != WriteState::FINISHED) {
-      // We should still be able to write more at this point.
-      EXPECT_FALSE(aSink->IsSurfaceFinished());
-
-      // Verify that we can resume the same row and still stop at the end.
-      count = 0;
-      WriteState result = aSink->WritePixelsToRow<uint8_t>([&] {
-        ++count;
-        return AsVariant(uint8_t(255));
-      });
-
-      EXPECT_EQ(WriteState::NEED_MORE_DATA, result);
-      EXPECT_EQ(50u, count);
-      EXPECT_FALSE(aSink->IsSurfaceFinished());
-      CheckGeneratedPalettedImage(aDecoder, IntRect(0, 0, 100, 1));
-
-      return;
-    }
-
-    // We should've finished the surface at this point.
-    AssertCorrectPipelineFinalState(aSink, IntRect(0, 0, 100, 100),
-                                    IntRect(0, 0, 100, 100));
-
-    // Attempt to write more and make sure that nothing gets written.
-    count = 0;
-    result = aSink->WritePixelsToRow<uint8_t>([&] {
-      count++;
-      return AsVariant(uint8_t(128));
-    });
-
-    EXPECT_EQ(WriteState::FINISHED, result);
-    EXPECT_EQ(0u, count);
-    EXPECT_TRUE(aSink->IsSurfaceFinished());
-
-    // Check that the generated image is still correct.
-    CheckGeneratedPalettedImage(aDecoder, IntRect(0, 0, 50, 1));
-  };
-
-  WithPalettedSurfaceSink(IntRect(0, 0, 100, 100),
-                          [&](Decoder* aDecoder, PalettedSurfaceSink* aSink) {
-                            checkEarlyExit(aDecoder, aSink,
-                                           WriteState::NEED_MORE_DATA);
-                          });
-
-  WithPalettedSurfaceSink(IntRect(0, 0, 100, 100),
-                          [&](Decoder* aDecoder, PalettedSurfaceSink* aSink) {
-                            checkEarlyExit(aDecoder, aSink,
-                                           WriteState::FAILURE);
-                          });
-
-  WithPalettedSurfaceSink(IntRect(0, 0, 100, 100),
-                          [&](Decoder* aDecoder, PalettedSurfaceSink* aSink) {
-                            checkEarlyExit(aDecoder, aSink,
-                                           WriteState::FINISHED);
-                          });
-}
-
-TEST(ImageSurfaceSink, PalettedSurfaceSinkWriteBuffer) {
-  WithPalettedSurfaceSink(IntRect(0, 0, 100, 100),
-                          [](Decoder* aDecoder, PalettedSurfaceSink* aSink) {
-                            // Create a buffer the same size as one row of the
-                            // surface (which is 100x100), containing 60 pixels
-                            // of 255 in the middle and 20 transparent pixels of
-                            // 0 on either side.
-                            uint8_t buffer[100];
-                            for (int i = 0; i < 100; ++i) {
-                              buffer[i] = 20 <= i && i < 80 ? 255 : 0;
-                            }
-
-                            // Write the buffer to every row of the surface and
-                            // check that the generated image is correct.
-                            CheckPalettedIterativeWrite(
-                                aDecoder, aSink, IntRect(20, 0, 60, 100),
-                                [&] { return aSink->WriteBuffer(buffer); });
-                          });
-}
-
-TEST(ImageSurfaceSink, PalettedSurfaceSinkWriteBufferPartialRow) {
-  WithPalettedSurfaceSink(IntRect(0, 0, 100, 100),
-                          [](Decoder* aDecoder, PalettedSurfaceSink* aSink) {
-                            // Create a buffer the same size as one row of the
-                            // surface, containing all 255 pixels.
-                            uint8_t buffer[100];
-                            for (int i = 0; i < 100; ++i) {
-                              buffer[i] = 255;
-                            }
-
-                            // Write the buffer to the middle 60 pixels of every
-                            // row of the surface and check that the generated
-                            // image is correct.
-                            CheckPalettedIterativeWrite(
-                                aDecoder, aSink, IntRect(20, 0, 60, 100), [&] {
-                                  return aSink->WriteBuffer(buffer, 20, 60);
-                                });
-                          });
-}
-
-TEST(ImageSurfaceSink,
-     PalettedSurfaceSinkWriteBufferPartialRowStartColOverflow) {
-  WithPalettedSurfaceSink(
-      IntRect(0, 0, 100, 100),
-      [](Decoder* aDecoder, PalettedSurfaceSink* aSink) {
-        // Create a buffer the same size as one row of the surface, containing
-        // all 255 pixels.
-        uint8_t buffer[100];
-        for (int i = 0; i < 100; ++i) {
-          buffer[i] = 255;
-        }
-
-        {
-          // Write the buffer to successive rows until every row of the surface
-          // has been written. We place the start column beyond the end of the
-          // row, which will prevent us from writing anything, so we check that
-          // the generated image is entirely 0.
-          CheckPalettedIterativeWrite(
-              aDecoder, aSink, IntRect(0, 0, 0, 0),
-              [&] { return aSink->WriteBuffer(buffer, 100, 100); });
-        }
-
-        ResetForNextPass(aSink);
-
-        {
-          // Write the buffer to successive rows until every row of the surface
-          // has been written. We use column 50 as the start column, but we
-          // still write the buffer, which means we overflow the right edge of
-          // the surface by 50 pixels. We check that the left half of the
-          // generated image is 0 and the right half is 255.
-          CheckPalettedIterativeWrite(
-              aDecoder, aSink, IntRect(50, 0, 50, 100),
-              [&] { return aSink->WriteBuffer(buffer, 50, 100); });
-        }
-      });
-}
-
-TEST(ImageSurfaceSink, PalettedSurfaceSinkWriteBufferPartialRowBufferOverflow) {
-  WithPalettedSurfaceSink(
-      IntRect(0, 0, 100, 100),
-      [](Decoder* aDecoder, PalettedSurfaceSink* aSink) {
-        // Create a buffer twice as large as a row of the surface. The first
-        // half (which is as large as a row of the image) will contain 255
-        // pixels, while the second half will contain 128 pixels.
-        uint8_t buffer[200];
-        for (int i = 0; i < 200; ++i) {
-          buffer[i] = i < 100 ? 255 : 128;
-        }
-
-        {
-          // Write the buffer to successive rows until every row of the surface
-          // has been written. The buffer extends 100 pixels to the right of a
-          // row of the surface, but bounds checking will prevent us from
-          // overflowing the buffer. We check that the generated image is
-          // entirely 255 since the pixels on the right side of the buffer
-          // shouldn't have been written to the surface.
-          CheckPalettedIterativeWrite(
-              aDecoder, aSink, IntRect(0, 0, 100, 100),
-              [&] { return aSink->WriteBuffer(buffer, 0, 200); });
-        }
-
-        ResetForNextPass(aSink);
-
-        {
-          // Write from the buffer to the middle of each row of the surface.
-          // That means that the left side of each row should be 0, since we
-          // didn't write anything there. A buffer overflow would cause us to
-          // write buffer contents into the left side of each row. We check that
-          // the generated image is 0 on the left side and 255 on the right.
-          CheckPalettedIterativeWrite(
-              aDecoder, aSink, IntRect(50, 0, 50, 100),
-              [&] { return aSink->WriteBuffer(buffer, 50, 200); });
-        }
-      });
-}
-
-TEST(ImageSurfaceSink, PalettedSurfaceSinkWriteBufferFromNullSource) {
-  WithPalettedSurfaceSink(
-      IntRect(0, 0, 100, 100),
-      [](Decoder* aDecoder, PalettedSurfaceSink* aSink) {
-        // Calling WriteBuffer() with a null pointer should fail without making
-        // any changes to the surface.
-        uint8_t* nullBuffer = nullptr;
-        WriteState result = aSink->WriteBuffer(nullBuffer);
-
-        EXPECT_EQ(WriteState::FAILURE, result);
-        EXPECT_FALSE(aSink->IsSurfaceFinished());
-        Maybe<SurfaceInvalidRect> invalidRect = aSink->TakeInvalidRect();
-        EXPECT_TRUE(invalidRect.isNothing());
-
-        // Check that nothing got written to the surface.
-        CheckGeneratedPalettedImage(aDecoder, IntRect(0, 0, 0, 0));
-      });
-}
-
-TEST(ImageSurfaceSink, PalettedSurfaceSinkWriteEmptyRow) {
-  WithPalettedSurfaceSink(
-      IntRect(0, 0, 100, 100),
-      [](Decoder* aDecoder, PalettedSurfaceSink* aSink) {
-        {
-          // Write an empty row to each row of the surface. We check that the
-          // generated image is entirely 0.
-          CheckPalettedIterativeWrite(aDecoder, aSink, IntRect(0, 0, 0, 0),
-                                      [&] { return aSink->WriteEmptyRow(); });
-        }
-
-        ResetForNextPass(aSink);
-
-        {
-          // Write a partial row before we begin calling WriteEmptyRow(). We
-          // check that the generated image is entirely 0, which is to be
-          // expected since WriteEmptyRow() overwrites the current row even if
-          // some data has already been written to it.
-          uint32_t count = 0;
-          auto result =
-              aSink->WritePixels<uint8_t>([&]() -> NextPixel<uint8_t> {
-                if (count == 50) {
-                  return AsVariant(WriteState::NEED_MORE_DATA);
-                }
-                ++count;
-                return AsVariant(uint8_t(255));
-              });
-
-          EXPECT_EQ(WriteState::NEED_MORE_DATA, result);
-          EXPECT_EQ(50u, count);
-          EXPECT_FALSE(aSink->IsSurfaceFinished());
-
-          CheckPalettedIterativeWrite(aDecoder, aSink, IntRect(0, 0, 0, 0),
-                                      [&] { return aSink->WriteEmptyRow(); });
-        }
-
-        ResetForNextPass(aSink);
-
-        {
-          // Create a buffer the same size as one row of the surface, containing
-          // all 255 pixels.
-          uint8_t buffer[100];
-          for (int i = 0; i < 100; ++i) {
-            buffer[i] = 255;
-          }
-
-          // Write an empty row to the middle 60 rows of the surface. The first
-          // 20 and last 20 rows will be 255. (We need to use
-          // DoCheckIterativeWrite() here because we need a custom function to
-          // check the output, since it can't be described by a simple rect.)
-          auto writeFunc = [&](uint32_t aRow) {
-            if (aRow < 20 || aRow >= 80) {
-              return aSink->WriteBuffer(buffer);
-            } else {
-              return aSink->WriteEmptyRow();
-            }
-          };
-
-          auto checkFunc = [&] {
-            EXPECT_TRUE(PalettedRowsAreSolidColor(aDecoder, 0, 20, 255));
-            EXPECT_TRUE(PalettedRowsAreSolidColor(aDecoder, 20, 60, 0));
-            EXPECT_TRUE(PalettedRowsAreSolidColor(aDecoder, 80, 20, 255));
-          };
-
-          DoCheckIterativeWrite(aSink, writeFunc, checkFunc);
-        }
-      });
-}
-
-TEST(ImageSurfaceSink, PalettedSurfaceSinkWriteUnsafeComputedRow) {
-  WithPalettedSurfaceSink(IntRect(0, 0, 100, 100),
-                          [](Decoder* aDecoder, PalettedSurfaceSink* aSink) {
-                            // Create an all-255 buffer the same size as one row
-                            // of the surface.
-                            uint8_t buffer[100];
-                            for (int i = 0; i < 100; ++i) {
-                              buffer[i] = 255;
-                            }
-
-                            // Write the buffer to successive rows until every
-                            // row of the surface has been written. We only
-                            // write to the right half of each row, so we check
-                            // that the left side of the generated image is 0
-                            // and the right side is 255.
-                            CheckPalettedIterativeWrite(
-                                aDecoder, aSink, IntRect(50, 0, 50, 100), [&] {
-                                  return aSink->WriteUnsafeComputedRow<uint8_t>(
-                                      [&](uint8_t* aRow, uint32_t aLength) {
-                                        EXPECT_EQ(100u, aLength);
-                                        memcpy(aRow + 50, buffer,
-                                               50 * sizeof(uint8_t));
-                                      });
-                                });
-                          });
-}