void CheckPalettedWritePixels(Decoder* aDecoder, SurfaceFilter* aFilter, Maybe<IntRect> aOutputRect /* = Nothing() */, Maybe<IntRect> aInputRect /* = Nothing() */, Maybe<IntRect> aInputWriteRect /* = Nothing() */, Maybe<IntRect> aOutputWriteRect /* = Nothing() */, uint8_t aFuzz /* = 0 */) { IntRect outputRect = aOutputRect.valueOr(IntRect(0, 0, 100, 100)); IntRect inputRect = aInputRect.valueOr(IntRect(0, 0, 100, 100)); IntRect inputWriteRect = aInputWriteRect.valueOr(inputRect); IntRect outputWriteRect = aOutputWriteRect.valueOr(outputRect); // Fill the image. int32_t count = 0; auto result = aFilter->WritePixels<uint8_t>([&] { ++count; return AsVariant(uint8_t(255)); }); EXPECT_EQ(WriteState::FINISHED, result); EXPECT_EQ(inputWriteRect.width * inputWriteRect.height, count); AssertCorrectPipelineFinalState(aFilter, inputRect, outputRect); // Attempt to write more data and make sure nothing changes. const int32_t oldCount = count; result = aFilter->WritePixels<uint8_t>([&] { ++count; return AsVariant(uint8_t(255)); }); EXPECT_EQ(oldCount, count); EXPECT_EQ(WriteState::FINISHED, result); EXPECT_TRUE(aFilter->IsSurfaceFinished()); Maybe<SurfaceInvalidRect> invalidRect = aFilter->TakeInvalidRect(); EXPECT_TRUE(invalidRect.isNothing()); // Attempt to advance to the next row and make sure nothing changes. aFilter->AdvanceRow(); EXPECT_TRUE(aFilter->IsSurfaceFinished()); invalidRect = aFilter->TakeInvalidRect(); EXPECT_TRUE(invalidRect.isNothing()); // Check that the generated image is correct. RawAccessFrameRef currentFrame = aDecoder->GetCurrentFrameRef(); uint8_t* imageData; uint32_t imageLength; currentFrame->GetImageData(&imageData, &imageLength); ASSERT_TRUE(imageData != nullptr); ASSERT_EQ(outputWriteRect.width * outputWriteRect.height, int32_t(imageLength)); for (uint32_t i = 0; i < imageLength; ++i) { ASSERT_EQ(uint8_t(255), imageData[i]); } }
bool PalettedRectIsSolidColor(Decoder* aDecoder, const IntRect& aRect, uint8_t aColor) { RawAccessFrameRef currentFrame = aDecoder->GetCurrentFrameRef(); uint8_t* imageData; uint32_t imageLength; currentFrame->GetImageData(&imageData, &imageLength); ASSERT_TRUE_OR_RETURN(imageData, false); // Clamp to the frame rect. If any pixels outside the frame rect are included, // we immediately fail, because such pixels don't have any "color" in the // sense this function measures - they're transparent, and that doesn't // necessarily correspond to any color palette index at all. IntRect frameRect = currentFrame->GetRect(); ASSERT_EQ_OR_RETURN(imageLength, uint32_t(frameRect.Area()), false); IntRect rect = aRect.Intersect(frameRect); ASSERT_EQ_OR_RETURN(rect.Area(), aRect.Area(), false); // Translate |rect| by |frameRect.TopLeft()| to reflect the fact that the // frame rect's offset doesn't actually mean anything in terms of the // in-memory representation of the surface. The image data starts at the upper // left corner of the frame rect, in other words. rect -= frameRect.TopLeft(); // Walk through the image data and make sure that the entire rect has the // palette index |aColor|. int32_t rowLength = frameRect.width; for (int32_t row = rect.y; row < rect.YMost(); ++row) { for (int32_t col = rect.x; col < rect.XMost(); ++col) { int32_t i = row * rowLength + col; ASSERT_EQ_OR_RETURN(aColor, imageData[i], false); } } return true; }