tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

TestDownscalingFilter.cpp (9493B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
      3 /* This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this
      5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 #include "gtest/gtest.h"
      8 
      9 #include "mozilla/gfx/2D.h"
     10 #include "Common.h"
     11 #include "Decoder.h"
     12 #include "DecoderFactory.h"
     13 #include "SourceBuffer.h"
     14 #include "SurfaceFilters.h"
     15 #include "SurfacePipe.h"
     16 
     17 using namespace mozilla;
     18 using namespace mozilla::gfx;
     19 using namespace mozilla::image;
     20 
     21 template <typename Func>
     22 void WithDownscalingFilter(const IntSize& aInputSize,
     23                           const IntSize& aOutputSize, Func aFunc) {
     24  RefPtr<image::Decoder> decoder = CreateTrivialDecoder();
     25  ASSERT_TRUE(decoder != nullptr);
     26 
     27  WithFilterPipeline(
     28      decoder, std::forward<Func>(aFunc),
     29      DownscalingConfig{aInputSize, SurfaceFormat::OS_RGBA},
     30      SurfaceConfig{decoder, aOutputSize, SurfaceFormat::OS_RGBA, false});
     31 }
     32 
     33 void AssertConfiguringDownscalingFilterFails(const IntSize& aInputSize,
     34                                             const IntSize& aOutputSize) {
     35  RefPtr<image::Decoder> decoder = CreateTrivialDecoder();
     36  ASSERT_TRUE(decoder != nullptr);
     37 
     38  AssertConfiguringPipelineFails(
     39      decoder, DownscalingConfig{aInputSize, SurfaceFormat::OS_RGBA},
     40      SurfaceConfig{decoder, aOutputSize, SurfaceFormat::OS_RGBA, false});
     41 }
     42 
     43 TEST(ImageDownscalingFilter, WritePixels100_100to99_99)
     44 {
     45  WithDownscalingFilter(IntSize(100, 100), IntSize(99, 99),
     46                        [](image::Decoder* aDecoder, SurfaceFilter* aFilter) {
     47                          CheckWritePixels(
     48                              aDecoder, aFilter,
     49                              /* aOutputRect = */ Some(IntRect(0, 0, 99, 99)));
     50                        });
     51 }
     52 
     53 TEST(ImageDownscalingFilter, WritePixels100_100to33_33)
     54 {
     55  WithDownscalingFilter(IntSize(100, 100), IntSize(33, 33),
     56                        [](image::Decoder* aDecoder, SurfaceFilter* aFilter) {
     57                          CheckWritePixels(
     58                              aDecoder, aFilter,
     59                              /* aOutputRect = */ Some(IntRect(0, 0, 33, 33)));
     60                        });
     61 }
     62 
     63 TEST(ImageDownscalingFilter, WritePixels100_100to1_1)
     64 {
     65  WithDownscalingFilter(IntSize(100, 100), IntSize(1, 1),
     66                        [](image::Decoder* aDecoder, SurfaceFilter* aFilter) {
     67                          CheckWritePixels(
     68                              aDecoder, aFilter,
     69                              /* aOutputRect = */ Some(IntRect(0, 0, 1, 1)));
     70                        });
     71 }
     72 
     73 TEST(ImageDownscalingFilter, WritePixels100_100to33_99)
     74 {
     75  WithDownscalingFilter(IntSize(100, 100), IntSize(33, 99),
     76                        [](image::Decoder* aDecoder, SurfaceFilter* aFilter) {
     77                          CheckWritePixels(
     78                              aDecoder, aFilter,
     79                              /* aOutputRect = */ Some(IntRect(0, 0, 33, 99)));
     80                        });
     81 }
     82 
     83 TEST(ImageDownscalingFilter, WritePixels100_100to99_33)
     84 {
     85  WithDownscalingFilter(IntSize(100, 100), IntSize(99, 33),
     86                        [](image::Decoder* aDecoder, SurfaceFilter* aFilter) {
     87                          CheckWritePixels(
     88                              aDecoder, aFilter,
     89                              /* aOutputRect = */ Some(IntRect(0, 0, 99, 33)));
     90                        });
     91 }
     92 
     93 TEST(ImageDownscalingFilter, WritePixels100_100to99_1)
     94 {
     95  WithDownscalingFilter(IntSize(100, 100), IntSize(99, 1),
     96                        [](image::Decoder* aDecoder, SurfaceFilter* aFilter) {
     97                          CheckWritePixels(
     98                              aDecoder, aFilter,
     99                              /* aOutputRect = */ Some(IntRect(0, 0, 99, 1)));
    100                        });
    101 }
    102 
    103 TEST(ImageDownscalingFilter, WritePixels100_100to1_99)
    104 {
    105  WithDownscalingFilter(IntSize(100, 100), IntSize(1, 99),
    106                        [](image::Decoder* aDecoder, SurfaceFilter* aFilter) {
    107                          CheckWritePixels(
    108                              aDecoder, aFilter,
    109                              /* aOutputRect = */ Some(IntRect(0, 0, 1, 99)));
    110                        });
    111 }
    112 
    113 TEST(ImageDownscalingFilter, DownscalingFailsFor100_100to101_101)
    114 {
    115  // Upscaling is disallowed.
    116  AssertConfiguringDownscalingFilterFails(IntSize(100, 100), IntSize(101, 101));
    117 }
    118 
    119 TEST(ImageDownscalingFilter, DownscalingFailsFor100_100to100_100)
    120 {
    121  // "Scaling" to the same size is disallowed.
    122  AssertConfiguringDownscalingFilterFails(IntSize(100, 100), IntSize(100, 100));
    123 }
    124 
    125 TEST(ImageDownscalingFilter, DownscalingFailsFor0_0toMinus1_Minus1)
    126 {
    127  // A 0x0 input size is disallowed.
    128  AssertConfiguringDownscalingFilterFails(IntSize(0, 0), IntSize(-1, -1));
    129 }
    130 
    131 TEST(ImageDownscalingFilter, DownscalingFailsForMinus1_Minus1toMinus2_Minus2)
    132 {
    133  // A negative input size is disallowed.
    134  AssertConfiguringDownscalingFilterFails(IntSize(-1, -1), IntSize(-2, -2));
    135 }
    136 
    137 TEST(ImageDownscalingFilter, DownscalingFailsFor100_100to0_0)
    138 {
    139  // A 0x0 output size is disallowed.
    140  AssertConfiguringDownscalingFilterFails(IntSize(100, 100), IntSize(0, 0));
    141 }
    142 
    143 TEST(ImageDownscalingFilter, DownscalingFailsFor100_100toMinus1_Minus1)
    144 {
    145  // A negative output size is disallowed.
    146  AssertConfiguringDownscalingFilterFails(IntSize(100, 100), IntSize(-1, -1));
    147 }
    148 
    149 TEST(ImageDownscalingFilter, WritePixelsOutput100_100to20_20)
    150 {
    151  WithDownscalingFilter(
    152      IntSize(100, 100), IntSize(20, 20),
    153      [](image::Decoder* aDecoder, SurfaceFilter* aFilter) {
    154        // Fill the image. It consists of 25 lines of green, followed by 25
    155        // lines of red, followed by 25 lines of green, followed by 25 more
    156        // lines of red.
    157        uint32_t count = 0;
    158        auto result =
    159            aFilter->WritePixels<uint32_t>([&]() -> NextPixel<uint32_t> {
    160              uint32_t color =
    161                  (count <= 25 * 100) || (count > 50 * 100 && count <= 75 * 100)
    162                      ? BGRAColor::Green().AsPixel()
    163                      : BGRAColor::Red().AsPixel();
    164              ++count;
    165              return AsVariant(color);
    166            });
    167        EXPECT_EQ(WriteState::FINISHED, result);
    168        EXPECT_EQ(100u * 100u, count);
    169 
    170        AssertCorrectPipelineFinalState(aFilter, IntRect(0, 0, 100, 100),
    171                                        IntRect(0, 0, 20, 20));
    172 
    173        // Check that the generated image is correct. Note that we skip rows
    174        // near the transitions between colors, since the downscaler does not
    175        // produce a sharp boundary at these points. Even some of the rows we
    176        // test need a small amount of fuzz; this is just the nature of Lanczos
    177        // downscaling.
    178        RawAccessFrameRef currentFrame = aDecoder->GetCurrentFrameRef();
    179        RefPtr<SourceSurface> surface = currentFrame->GetSourceSurface();
    180        EXPECT_TRUE(RowsAreSolidColor(surface, 0, 4, BGRAColor::Green(),
    181                                      /* aFuzz = */ 2));
    182        EXPECT_TRUE(RowsAreSolidColor(surface, 6, 3, BGRAColor::Red(),
    183                                      /* aFuzz = */ 3));
    184        EXPECT_TRUE(RowsAreSolidColor(surface, 11, 3, BGRAColor::Green(),
    185                                      /* aFuzz = */ 3));
    186        EXPECT_TRUE(RowsAreSolidColor(surface, 16, 4, BGRAColor::Red(),
    187                                      /* aFuzz = */ 3));
    188      });
    189 }
    190 
    191 TEST(ImageDownscalingFilter, WritePixelsOutput100_100to10_20)
    192 {
    193  WithDownscalingFilter(
    194      IntSize(100, 100), IntSize(10, 20),
    195      [](image::Decoder* aDecoder, SurfaceFilter* aFilter) {
    196        // Fill the image. It consists of 25 lines of green, followed by 25
    197        // lines of red, followed by 25 lines of green, followed by 25 more
    198        // lines of red.
    199        uint32_t count = 0;
    200        auto result =
    201            aFilter->WritePixels<uint32_t>([&]() -> NextPixel<uint32_t> {
    202              uint32_t color =
    203                  (count <= 25 * 100) || (count > 50 * 100 && count <= 75 * 100)
    204                      ? BGRAColor::Green().AsPixel()
    205                      : BGRAColor::Red().AsPixel();
    206              ++count;
    207              return AsVariant(color);
    208            });
    209        EXPECT_EQ(WriteState::FINISHED, result);
    210        EXPECT_EQ(100u * 100u, count);
    211 
    212        AssertCorrectPipelineFinalState(aFilter, IntRect(0, 0, 100, 100),
    213                                        IntRect(0, 0, 10, 20));
    214 
    215        // Check that the generated image is correct. Note that we skip rows
    216        // near the transitions between colors, since the downscaler does not
    217        // produce a sharp boundary at these points. Even some of the rows we
    218        // test need a small amount of fuzz; this is just the nature of Lanczos
    219        // downscaling.
    220        RawAccessFrameRef currentFrame = aDecoder->GetCurrentFrameRef();
    221        RefPtr<SourceSurface> surface = currentFrame->GetSourceSurface();
    222        EXPECT_TRUE(RowsAreSolidColor(surface, 0, 4, BGRAColor::Green(),
    223                                      /* aFuzz = */ 2));
    224        EXPECT_TRUE(RowsAreSolidColor(surface, 6, 3, BGRAColor::Red(),
    225                                      /* aFuzz = */ 3));
    226        EXPECT_TRUE(RowsAreSolidColor(surface, 11, 3, BGRAColor::Green(),
    227                                      /* aFuzz = */ 3));
    228        EXPECT_TRUE(RowsAreSolidColor(surface, 16, 4, BGRAColor::Red(),
    229                                      /* aFuzz = */ 3));
    230      });
    231 }