Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/image/test/gtest/TestDecodeToSurface.cpp
Line
Count
Source (jump to first uncovered line)
1
/* This Source Code Form is subject to the terms of the Mozilla Public
2
 * License, v. 2.0. If a copy of the MPL was not distributed with this
3
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
5
#include "gtest/gtest.h"
6
7
#include "Common.h"
8
#include "imgIContainer.h"
9
#include "imgITools.h"
10
#include "ImageOps.h"
11
#include "mozilla/gfx/2D.h"
12
#include "nsComponentManagerUtils.h"
13
#include "nsCOMPtr.h"
14
#include "nsIInputStream.h"
15
#include "nsIRunnable.h"
16
#include "nsIThread.h"
17
#include "mozilla/RefPtr.h"
18
#include "nsString.h"
19
#include "nsThreadUtils.h"
20
21
using namespace mozilla;
22
using namespace mozilla::gfx;
23
using namespace mozilla::image;
24
25
class DecodeToSurfaceRunnable : public Runnable
26
{
27
public:
28
  DecodeToSurfaceRunnable(RefPtr<SourceSurface>& aSurface,
29
                          nsIInputStream* aInputStream,
30
                          ImageOps::ImageBuffer* aImageBuffer,
31
                          const ImageTestCase& aTestCase)
32
    : mozilla::Runnable("DecodeToSurfaceRunnable")
33
    , mSurface(aSurface)
34
    , mInputStream(aInputStream)
35
    , mImageBuffer(aImageBuffer)
36
    , mTestCase(aTestCase)
37
0
  { }
38
39
  NS_IMETHOD Run() override
40
0
  {
41
0
    Go();
42
0
    return NS_OK;
43
0
  }
44
45
  void Go()
46
0
  {
47
0
    Maybe<IntSize> outputSize;
48
0
    if (mTestCase.mOutputSize != mTestCase.mSize) {
49
0
      outputSize.emplace(mTestCase.mOutputSize);
50
0
    }
51
0
52
0
    if (mImageBuffer) {
53
0
      mSurface =
54
0
        ImageOps::DecodeToSurface(mImageBuffer,
55
0
                                  nsDependentCString(mTestCase.mMimeType),
56
0
                                  imgIContainer::DECODE_FLAGS_DEFAULT,
57
0
                                  outputSize);
58
0
    } else {
59
0
      mSurface =
60
0
        ImageOps::DecodeToSurface(mInputStream.forget(),
61
0
                                  nsDependentCString(mTestCase.mMimeType),
62
0
                                  imgIContainer::DECODE_FLAGS_DEFAULT,
63
0
                                  outputSize);
64
0
    }
65
0
    ASSERT_TRUE(mSurface != nullptr);
66
0
67
0
    EXPECT_TRUE(mSurface->IsDataSourceSurface());
68
0
    EXPECT_TRUE(mSurface->GetFormat() == SurfaceFormat::B8G8R8X8 ||
69
0
                mSurface->GetFormat() == SurfaceFormat::B8G8R8A8);
70
0
71
0
    if (outputSize) {
72
0
      EXPECT_EQ(*outputSize, mSurface->GetSize());
73
0
    } else {
74
0
      EXPECT_EQ(mTestCase.mSize, mSurface->GetSize());
75
0
    }
76
0
77
0
    EXPECT_TRUE(IsSolidColor(mSurface, BGRAColor::Green(),
78
0
                             mTestCase.mFlags & TEST_CASE_IS_FUZZY ? 1 : 0));
79
0
  }
80
81
private:
82
  RefPtr<SourceSurface>& mSurface;
83
  nsCOMPtr<nsIInputStream> mInputStream;
84
  RefPtr<ImageOps::ImageBuffer> mImageBuffer;
85
  ImageTestCase mTestCase;
86
};
87
88
static void
89
RunDecodeToSurface(const ImageTestCase& aTestCase,
90
                   ImageOps::ImageBuffer* aImageBuffer = nullptr)
91
0
{
92
0
  nsCOMPtr<nsIInputStream> inputStream;
93
0
  if (!aImageBuffer) {
94
0
    inputStream = LoadFile(aTestCase.mPath);
95
0
    ASSERT_TRUE(inputStream != nullptr);
96
0
  }
97
0
98
0
  nsCOMPtr<nsIThread> thread;
99
0
  nsresult rv =
100
0
    NS_NewNamedThread("DecodeToSurface", getter_AddRefs(thread), nullptr);
101
0
  ASSERT_TRUE(NS_SUCCEEDED(rv));
102
0
103
0
  // We run the DecodeToSurface tests off-main-thread to ensure that
104
0
  // DecodeToSurface doesn't require any main-thread-only code.
105
0
  RefPtr<SourceSurface> surface;
106
0
  nsCOMPtr<nsIRunnable> runnable =
107
0
    new DecodeToSurfaceRunnable(surface, inputStream, aImageBuffer, aTestCase);
108
0
  thread->Dispatch(runnable, nsIThread::DISPATCH_SYNC);
109
0
110
0
  thread->Shutdown();
111
0
112
0
  // Explicitly release the SourceSurface on the main thread.
113
0
  surface = nullptr;
114
0
}
115
116
class ImageDecodeToSurface : public ::testing::Test
117
{
118
protected:
119
  AutoInitializeImageLib mInit;
120
};
121
122
0
TEST_F(ImageDecodeToSurface, PNG) { RunDecodeToSurface(GreenPNGTestCase()); }
123
0
TEST_F(ImageDecodeToSurface, GIF) { RunDecodeToSurface(GreenGIFTestCase()); }
124
0
TEST_F(ImageDecodeToSurface, JPG) { RunDecodeToSurface(GreenJPGTestCase()); }
125
0
TEST_F(ImageDecodeToSurface, BMP) { RunDecodeToSurface(GreenBMPTestCase()); }
126
0
TEST_F(ImageDecodeToSurface, ICO) { RunDecodeToSurface(GreenICOTestCase()); }
127
0
TEST_F(ImageDecodeToSurface, Icon) { RunDecodeToSurface(GreenIconTestCase()); }
128
129
TEST_F(ImageDecodeToSurface, AnimatedGIF)
130
0
{
131
0
  RunDecodeToSurface(GreenFirstFrameAnimatedGIFTestCase());
132
0
}
133
134
TEST_F(ImageDecodeToSurface, AnimatedPNG)
135
0
{
136
0
  RunDecodeToSurface(GreenFirstFrameAnimatedPNGTestCase());
137
0
}
138
139
TEST_F(ImageDecodeToSurface, Corrupt)
140
0
{
141
0
  ImageTestCase testCase = CorruptTestCase();
142
0
143
0
  nsCOMPtr<nsIInputStream> inputStream = LoadFile(testCase.mPath);
144
0
  ASSERT_TRUE(inputStream != nullptr);
145
0
146
0
  RefPtr<SourceSurface> surface =
147
0
    ImageOps::DecodeToSurface(inputStream.forget(),
148
0
                              nsDependentCString(testCase.mMimeType),
149
0
                              imgIContainer::DECODE_FLAGS_DEFAULT);
150
0
  EXPECT_TRUE(surface == nullptr);
151
0
}
152
153
TEST_F(ImageDecodeToSurface, ICOMultipleSizes)
154
0
{
155
0
  ImageTestCase testCase = GreenMultipleSizesICOTestCase();
156
0
157
0
  nsCOMPtr<nsIInputStream> inputStream = LoadFile(testCase.mPath);
158
0
  ASSERT_TRUE(inputStream != nullptr);
159
0
160
0
  RefPtr<ImageOps::ImageBuffer> buffer =
161
0
    ImageOps::CreateImageBuffer(inputStream.forget());
162
0
  ASSERT_TRUE(buffer != nullptr);
163
0
164
0
  ImageMetadata metadata;
165
0
  nsresult rv = ImageOps::DecodeMetadata(buffer,
166
0
                                         nsDependentCString(testCase.mMimeType),
167
0
                                         metadata);
168
0
  EXPECT_TRUE(NS_SUCCEEDED(rv));
169
0
  ASSERT_TRUE(metadata.HasSize());
170
0
  EXPECT_EQ(testCase.mSize, metadata.GetSize());
171
0
172
0
  const nsTArray<IntSize>& nativeSizes = metadata.GetNativeSizes();
173
0
  ASSERT_EQ(6u, nativeSizes.Length());
174
0
175
0
  IntSize expectedSizes[] = {
176
0
    IntSize(16, 16),
177
0
    IntSize(32, 32),
178
0
    IntSize(64, 64),
179
0
    IntSize(128, 128),
180
0
    IntSize(256, 256),
181
0
    IntSize(256, 128),
182
0
  };
183
0
184
0
  for (int i = 0; i < 6; ++i) {
185
0
    EXPECT_EQ(expectedSizes[i], nativeSizes[i]);
186
0
187
0
    // Request decoding at native size
188
0
    testCase.mOutputSize = nativeSizes[i];
189
0
    RunDecodeToSurface(testCase, buffer);
190
0
  }
191
0
}