static void CheckDecoderResults(const ImageTestCase& aTestCase, Decoder* aDecoder) { EXPECT_TRUE(aDecoder->GetDecodeDone()); EXPECT_EQ(bool(aTestCase.mFlags & TEST_CASE_HAS_ERROR), aDecoder->HasError()); EXPECT_TRUE(!aDecoder->WasAborted()); // Verify that the decoder made the expected progress. Progress progress = aDecoder->TakeProgress(); EXPECT_EQ(bool(aTestCase.mFlags & TEST_CASE_HAS_ERROR), bool(progress & FLAG_HAS_ERROR)); if (aTestCase.mFlags & TEST_CASE_HAS_ERROR) { return; // That's all we can check for bad images. } EXPECT_TRUE(bool(progress & FLAG_SIZE_AVAILABLE)); EXPECT_TRUE(bool(progress & FLAG_DECODE_COMPLETE)); EXPECT_TRUE(bool(progress & FLAG_FRAME_COMPLETE)); EXPECT_EQ(bool(aTestCase.mFlags & TEST_CASE_IS_TRANSPARENT), bool(progress & FLAG_HAS_TRANSPARENCY)); EXPECT_EQ(bool(aTestCase.mFlags & TEST_CASE_IS_ANIMATED), bool(progress & FLAG_IS_ANIMATED)); // The decoder should get the correct size. IntSize size = aDecoder->GetSize(); EXPECT_EQ(aTestCase.mSize.width, size.width); EXPECT_EQ(aTestCase.mSize.height, size.height); // Get the current frame, which is always the first frame of the image // because CreateAnonymousDecoder() forces a first-frame-only decode. RawAccessFrameRef currentFrame = aDecoder->GetCurrentFrameRef(); RefPtr<SourceSurface> surface = currentFrame->GetSurface(); // Verify that the resulting surfaces matches our expectations. EXPECT_EQ(SurfaceType::DATA, surface->GetType()); EXPECT_TRUE(surface->GetFormat() == SurfaceFormat::B8G8R8X8 || surface->GetFormat() == SurfaceFormat::B8G8R8A8); EXPECT_EQ(aTestCase.mSize, surface->GetSize()); EXPECT_TRUE(IsSolidColor(surface, BGRAColor::Green(), aTestCase.mFlags & TEST_CASE_IS_FUZZY)); }
/* static */ already_AddRefed<gfx::SourceSurface> ImageOps::DecodeToSurface(nsIInputStream* aInputStream, const nsACString& aMimeType, uint32_t aFlags) { MOZ_ASSERT(aInputStream); nsresult rv; // Prepare the input stream. nsCOMPtr<nsIInputStream> inputStream = aInputStream; if (!NS_InputStreamIsBuffered(aInputStream)) { nsCOMPtr<nsIInputStream> bufStream; rv = NS_NewBufferedInputStream(getter_AddRefs(bufStream), aInputStream, 1024); if (NS_SUCCEEDED(rv)) { inputStream = bufStream; } } // Figure out how much data we've been passed. uint64_t length; rv = inputStream->Available(&length); if (NS_FAILED(rv) || length > UINT32_MAX) { return nullptr; } // Write the data into a SourceBuffer. RefPtr<SourceBuffer> sourceBuffer = new SourceBuffer(); sourceBuffer->ExpectLength(length); rv = sourceBuffer->AppendFromInputStream(inputStream, length); if (NS_FAILED(rv)) { return nullptr; } sourceBuffer->Complete(NS_OK); // Create a decoder. DecoderType decoderType = DecoderFactory::GetDecoderType(PromiseFlatCString(aMimeType).get()); RefPtr<Decoder> decoder = DecoderFactory::CreateAnonymousDecoder(decoderType, sourceBuffer, ToSurfaceFlags(aFlags)); if (!decoder) { return nullptr; } // Run the decoder synchronously. decoder->Decode(); if (!decoder->GetDecodeDone() || decoder->HasError()) { return nullptr; } // Pull out the surface. RawAccessFrameRef frame = decoder->GetCurrentFrameRef(); if (!frame) { return nullptr; } RefPtr<SourceSurface> surface = frame->GetSurface(); if (!surface) { return nullptr; } return surface.forget(); }