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 "BasicLayers.h"
8 #include "Common.h"
9 #include "imgIContainer.h"
10 #include "ImageFactory.h"
11 #include "ImageContainer.h"
12 #include "mozilla/gfx/2D.h"
13 #include "mozilla/RefPtr.h"
14 #include "nsIInputStream.h"
15 #include "nsString.h"
16 #include "ProgressTracker.h"
17 
18 using namespace mozilla;
19 using namespace mozilla::gfx;
20 using namespace mozilla::image;
21 
22 class ImageContainers : public ::testing::Test {
23  protected:
24   AutoInitializeImageLib mInit;
25 };
26 
TEST_F(ImageContainers,RasterImageContainer)27 TEST_F(ImageContainers, RasterImageContainer) {
28   ImageTestCase testCase = GreenPNGTestCase();
29 
30   // Create an image.
31   RefPtr<Image> image = ImageFactory::CreateAnonymousImage(
32       nsDependentCString(testCase.mMimeType));
33   ASSERT_TRUE(!image->HasError());
34 
35   nsCOMPtr<nsIInputStream> inputStream = LoadFile(testCase.mPath);
36   ASSERT_TRUE(inputStream);
37 
38   // Figure out how much data we have.
39   uint64_t length;
40   nsresult rv = inputStream->Available(&length);
41   ASSERT_TRUE(NS_SUCCEEDED(rv));
42 
43   // Write the data into the image.
44   rv = image->OnImageDataAvailable(nullptr, nullptr, inputStream, 0,
45                                    static_cast<uint32_t>(length));
46   ASSERT_TRUE(NS_SUCCEEDED(rv));
47 
48   // Let the image know we've sent all the data.
49   rv = image->OnImageDataComplete(nullptr, nullptr, NS_OK, true);
50   ASSERT_TRUE(NS_SUCCEEDED(rv));
51 
52   RefPtr<ProgressTracker> tracker = image->GetProgressTracker();
53   tracker->SyncNotifyProgress(FLAG_LOAD_COMPLETE);
54 
55   RefPtr<layers::LayerManager> layerManager =
56       new layers::BasicLayerManager(layers::BasicLayerManager::BLM_OFFSCREEN);
57 
58   // Get at native size.
59   RefPtr<layers::ImageContainer> nativeContainer =
60       image->GetImageContainer(layerManager, imgIContainer::FLAG_SYNC_DECODE);
61   ASSERT_TRUE(nativeContainer != nullptr);
62   IntSize containerSize = nativeContainer->GetCurrentSize();
63   EXPECT_EQ(testCase.mSize.width, containerSize.width);
64   EXPECT_EQ(testCase.mSize.height, containerSize.height);
65 
66   // Upscaling should give the native size.
67   ImgDrawResult drawResult;
68   IntSize requestedSize = testCase.mSize;
69   requestedSize.Scale(2, 2);
70   RefPtr<layers::ImageContainer> upscaleContainer;
71   drawResult = image->GetImageContainerAtSize(
72       layerManager, requestedSize, Nothing(), Nothing(),
73       imgIContainer::FLAG_SYNC_DECODE |
74           imgIContainer::FLAG_HIGH_QUALITY_SCALING,
75       getter_AddRefs(upscaleContainer));
76   EXPECT_EQ(drawResult, ImgDrawResult::SUCCESS);
77   ASSERT_TRUE(upscaleContainer != nullptr);
78   containerSize = upscaleContainer->GetCurrentSize();
79   EXPECT_EQ(testCase.mSize.width, containerSize.width);
80   EXPECT_EQ(testCase.mSize.height, containerSize.height);
81 
82   // Downscaling should give the downscaled size.
83   requestedSize = testCase.mSize;
84   requestedSize.width /= 2;
85   requestedSize.height /= 2;
86   RefPtr<layers::ImageContainer> downscaleContainer;
87   drawResult = image->GetImageContainerAtSize(
88       layerManager, requestedSize, Nothing(), Nothing(),
89       imgIContainer::FLAG_SYNC_DECODE |
90           imgIContainer::FLAG_HIGH_QUALITY_SCALING,
91       getter_AddRefs(downscaleContainer));
92   EXPECT_EQ(drawResult, ImgDrawResult::SUCCESS);
93   ASSERT_TRUE(downscaleContainer != nullptr);
94   containerSize = downscaleContainer->GetCurrentSize();
95   EXPECT_EQ(requestedSize.width, containerSize.width);
96   EXPECT_EQ(requestedSize.height, containerSize.height);
97 
98   // Get at native size again. Should give same container.
99   RefPtr<layers::ImageContainer> againContainer;
100   drawResult = image->GetImageContainerAtSize(
101       layerManager, testCase.mSize, Nothing(), Nothing(),
102       imgIContainer::FLAG_SYNC_DECODE, getter_AddRefs(againContainer));
103   EXPECT_EQ(drawResult, ImgDrawResult::SUCCESS);
104   ASSERT_EQ(nativeContainer.get(), againContainer.get());
105 }
106