Beispiel #1
0
static void
CheckDecoderSingleChunk(const ImageTestCase& aTestCase)
{
  nsCOMPtr<nsIInputStream> inputStream = LoadFile(aTestCase.mPath);
  ASSERT_TRUE(inputStream != nullptr);

  // Figure out how much data we have.
  uint64_t length;
  nsresult rv = inputStream->Available(&length);
  ASSERT_TRUE(NS_SUCCEEDED(rv));

  // Write the data into a SourceBuffer.
  RefPtr<SourceBuffer> sourceBuffer = new SourceBuffer();
  sourceBuffer->ExpectLength(length);
  rv = sourceBuffer->AppendFromInputStream(inputStream, length);
  ASSERT_TRUE(NS_SUCCEEDED(rv));
  sourceBuffer->Complete(NS_OK);

  // Create a decoder.
  DecoderType decoderType =
    DecoderFactory::GetDecoderType(aTestCase.mMimeType);
  RefPtr<Decoder> decoder =
    DecoderFactory::CreateAnonymousDecoder(decoderType, sourceBuffer,
                                           DefaultSurfaceFlags());
  ASSERT_TRUE(decoder != nullptr);

  // Run the full decoder synchronously.
  decoder->Decode();
  
  CheckDecoderResults(aTestCase, decoder);
}
Beispiel #2
0
/* 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();
}
static void
CheckMetadata(const ImageTestCase& aTestCase,
              BMPAlpha aBMPAlpha = BMPAlpha::DISABLED)
{
  nsCOMPtr<nsIInputStream> inputStream = LoadFile(aTestCase.mPath);
  ASSERT_TRUE(inputStream != nullptr);

  // Figure out how much data we have.
  uint64_t length;
  nsresult rv = inputStream->Available(&length);
  ASSERT_TRUE(NS_SUCCEEDED(rv));

  // Write the data into a SourceBuffer.
  RefPtr<SourceBuffer> sourceBuffer = new SourceBuffer();
  sourceBuffer->ExpectLength(length);
  rv = sourceBuffer->AppendFromInputStream(inputStream, length);
  ASSERT_TRUE(NS_SUCCEEDED(rv));
  sourceBuffer->Complete(NS_OK);

  // Create a metadata decoder.
  DecoderType decoderType =
    DecoderFactory::GetDecoderType(aTestCase.mMimeType);
  RefPtr<Decoder> decoder =
    DecoderFactory::CreateAnonymousMetadataDecoder(decoderType, sourceBuffer);
  ASSERT_TRUE(decoder != nullptr);

  if (aBMPAlpha == BMPAlpha::ENABLED) {
    static_cast<nsBMPDecoder*>(decoder.get())->SetUseAlphaData(true);
  }

  // Run the metadata decoder synchronously.
  decoder->Decode();
  
  // Ensure that the metadata decoder didn't make progress it shouldn't have
  // (which would indicate that it decoded past the header of the image).
  Progress metadataProgress = decoder->TakeProgress();
  EXPECT_TRUE(0 == (metadataProgress & ~(FLAG_SIZE_AVAILABLE |
                                         FLAG_HAS_TRANSPARENCY |
                                         FLAG_IS_ANIMATED)));

  // If the test case is corrupt, assert what we can and return early.
  if (aTestCase.mFlags & TEST_CASE_HAS_ERROR) {
    EXPECT_TRUE(decoder->GetDecodeDone());
    EXPECT_TRUE(decoder->HasError());
    return;
  }

  EXPECT_TRUE(decoder->GetDecodeDone() && !decoder->HasError());

  // Check that we got the expected metadata.
  EXPECT_TRUE(metadataProgress & FLAG_SIZE_AVAILABLE);

  IntSize metadataSize = decoder->GetSize();
  EXPECT_EQ(aTestCase.mSize.width, metadataSize.width);
  EXPECT_EQ(aTestCase.mSize.height, metadataSize.height);

  bool expectTransparency = aBMPAlpha == BMPAlpha::ENABLED
                          ? true
                          : bool(aTestCase.mFlags & TEST_CASE_IS_TRANSPARENT);
  EXPECT_EQ(expectTransparency, bool(metadataProgress & FLAG_HAS_TRANSPARENCY));

  EXPECT_EQ(bool(aTestCase.mFlags & TEST_CASE_IS_ANIMATED),
            bool(metadataProgress & FLAG_IS_ANIMATED));

  // Create a full decoder, so we can compare the result.
  decoder =
    DecoderFactory::CreateAnonymousDecoder(decoderType, sourceBuffer,
                                           DefaultSurfaceFlags());
  ASSERT_TRUE(decoder != nullptr);

  if (aBMPAlpha == BMPAlpha::ENABLED) {
    static_cast<nsBMPDecoder*>(decoder.get())->SetUseAlphaData(true);
  }

  // Run the full decoder synchronously.
  decoder->Decode();
  
  EXPECT_TRUE(decoder->GetDecodeDone() && !decoder->HasError());
  Progress fullProgress = decoder->TakeProgress();

  // If the metadata decoder set a progress bit, the full decoder should also
  // have set the same bit.
  EXPECT_EQ(fullProgress, metadataProgress | fullProgress);

  // The full decoder and the metadata decoder should agree on the image's size.
  IntSize fullSize = decoder->GetSize();
  EXPECT_EQ(metadataSize.width, fullSize.width);
  EXPECT_EQ(metadataSize.height, fullSize.height);

  // We should not discover transparency during the full decode that we didn't
  // discover during the metadata decode, unless the image is animated.
  EXPECT_TRUE(!(fullProgress & FLAG_HAS_TRANSPARENCY) ||
              (metadataProgress & FLAG_HAS_TRANSPARENCY) ||
              (fullProgress & FLAG_IS_ANIMATED));
}