xref: /aosp_15_r20/external/skia/tests/ImageGeneratorOrientationTest.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1*c8dee2aaSAndroid Build Coastguard Worker /*
2*c8dee2aaSAndroid Build Coastguard Worker  * Copyright 2024 Google LLC.
3*c8dee2aaSAndroid Build Coastguard Worker  *
4*c8dee2aaSAndroid Build Coastguard Worker  * Use of this source code is governed by a BSD-style license that can be
5*c8dee2aaSAndroid Build Coastguard Worker  * found in the LICENSE file.
6*c8dee2aaSAndroid Build Coastguard Worker  */
7*c8dee2aaSAndroid Build Coastguard Worker 
8*c8dee2aaSAndroid Build Coastguard Worker #include "include/codec/SkCodec.h"
9*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkBitmap.h"
10*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkColor.h"
11*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkData.h"
12*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkImage.h"
13*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkImageGenerator.h"
14*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkImageInfo.h"
15*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkM44.h"
16*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkRefCnt.h"
17*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkStream.h"
18*c8dee2aaSAndroid Build Coastguard Worker #include "src/base/SkAutoMalloc.h"
19*c8dee2aaSAndroid Build Coastguard Worker #include "src/codec/SkCodecImageGenerator.h"
20*c8dee2aaSAndroid Build Coastguard Worker #include "src/codec/SkPixmapUtilsPriv.h"
21*c8dee2aaSAndroid Build Coastguard Worker #include "src/image/SkImageGeneratorPriv.h"
22*c8dee2aaSAndroid Build Coastguard Worker #include "tests/Test.h"
23*c8dee2aaSAndroid Build Coastguard Worker #include "tools/Resources.h"
24*c8dee2aaSAndroid Build Coastguard Worker 
25*c8dee2aaSAndroid Build Coastguard Worker #if defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_IOS)
26*c8dee2aaSAndroid Build Coastguard Worker     #include "include/ports/SkImageGeneratorCG.h"
27*c8dee2aaSAndroid Build Coastguard Worker #elif defined(SK_BUILD_FOR_WIN)
28*c8dee2aaSAndroid Build Coastguard Worker     #include "include/ports/SkImageGeneratorWIC.h"
29*c8dee2aaSAndroid Build Coastguard Worker     #include "src/utils/win/SkAutoCoInitialize.h"
30*c8dee2aaSAndroid Build Coastguard Worker #elif defined(SK_ENABLE_NDK_IMAGES)
31*c8dee2aaSAndroid Build Coastguard Worker     #include "include/ports/SkImageGeneratorNDK.h"
32*c8dee2aaSAndroid Build Coastguard Worker #endif
33*c8dee2aaSAndroid Build Coastguard Worker 
nearly_equal(SkColor4f a,SkColor4f b)34*c8dee2aaSAndroid Build Coastguard Worker static bool nearly_equal(SkColor4f a, SkColor4f b) {
35*c8dee2aaSAndroid Build Coastguard Worker     float d = SkV3{a.fR - b.fR, a.fG - b.fG, a.fB - b.fB}.length();
36*c8dee2aaSAndroid Build Coastguard Worker     static constexpr float kTol = 0.02f;
37*c8dee2aaSAndroid Build Coastguard Worker     return d <= kTol;
38*c8dee2aaSAndroid Build Coastguard Worker }
39*c8dee2aaSAndroid Build Coastguard Worker 
DEF_TEST(ImageGeneratorOrientationTest,reporter)40*c8dee2aaSAndroid Build Coastguard Worker DEF_TEST(ImageGeneratorOrientationTest, reporter) {
41*c8dee2aaSAndroid Build Coastguard Worker   #if defined(SK_BUILD_FOR_WIN)
42*c8dee2aaSAndroid Build Coastguard Worker     SkAutoCoInitialize com;
43*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, com.succeeded());
44*c8dee2aaSAndroid Build Coastguard Worker   #endif
45*c8dee2aaSAndroid Build Coastguard Worker 
46*c8dee2aaSAndroid Build Coastguard Worker   for (char i = '1'; i <= '8'; i++) {
47*c8dee2aaSAndroid Build Coastguard Worker     SkString path =  SkStringPrintf("images/orientation/%c_444.jpg", i);
48*c8dee2aaSAndroid Build Coastguard Worker     // Get the image as data
49*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<SkData> data(GetResourceAsData(path.c_str()));
50*c8dee2aaSAndroid Build Coastguard Worker 
51*c8dee2aaSAndroid Build Coastguard Worker     std::unique_ptr<SkImageGenerator> gen;
52*c8dee2aaSAndroid Build Coastguard Worker     #if defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_IOS)
53*c8dee2aaSAndroid Build Coastguard Worker       gen = SkImageGeneratorCG::MakeFromEncodedCG(data);
54*c8dee2aaSAndroid Build Coastguard Worker     #elif defined(SK_BUILD_FOR_WIN)
55*c8dee2aaSAndroid Build Coastguard Worker       gen = SkImageGeneratorWIC::MakeFromEncodedWIC(data);
56*c8dee2aaSAndroid Build Coastguard Worker     #elif defined(SK_ENABLE_NDK_IMAGES)
57*c8dee2aaSAndroid Build Coastguard Worker       gen = SkImageGeneratorNDK::MakeFromEncodedNDK(data);
58*c8dee2aaSAndroid Build Coastguard Worker     #else
59*c8dee2aaSAndroid Build Coastguard Worker       gen = SkCodecImageGenerator::MakeFromEncodedCodec(data);
60*c8dee2aaSAndroid Build Coastguard Worker     #endif
61*c8dee2aaSAndroid Build Coastguard Worker 
62*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, gen);
63*c8dee2aaSAndroid Build Coastguard Worker 
64*c8dee2aaSAndroid Build Coastguard Worker     bool success;
65*c8dee2aaSAndroid Build Coastguard Worker     // Get bitmap from image generator.
66*c8dee2aaSAndroid Build Coastguard Worker     SkImageInfo genInfo = gen->getInfo();
67*c8dee2aaSAndroid Build Coastguard Worker     SkBitmap genBitmap;
68*c8dee2aaSAndroid Build Coastguard Worker     success = genBitmap.tryAllocPixels(genInfo);
69*c8dee2aaSAndroid Build Coastguard Worker     SkPixmap genPM = genBitmap.pixmap();
70*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, genPM.addr());
71*c8dee2aaSAndroid Build Coastguard Worker     success = gen->getPixels(genPM);
72*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, success);
73*c8dee2aaSAndroid Build Coastguard Worker 
74*c8dee2aaSAndroid Build Coastguard Worker     // Get bitmap from codec. SkCodec::getPixels does not automatically apply
75*c8dee2aaSAndroid Build Coastguard Worker     // the origin so we rotate it manually.
76*c8dee2aaSAndroid Build Coastguard Worker     SkBitmap codecBitmap;
77*c8dee2aaSAndroid Build Coastguard Worker     std::unique_ptr<SkStream> stream(GetResourceAsStream(path.c_str()));
78*c8dee2aaSAndroid Build Coastguard Worker     std::unique_ptr<SkCodec> codec(SkCodec::MakeFromStream(std::move(stream)));
79*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, codec);
80*c8dee2aaSAndroid Build Coastguard Worker 
81*c8dee2aaSAndroid Build Coastguard Worker     SkImageInfo codecInfo = codec->getInfo();
82*c8dee2aaSAndroid Build Coastguard Worker     SkEncodedOrigin origin = codec->getOrigin();
83*c8dee2aaSAndroid Build Coastguard Worker 
84*c8dee2aaSAndroid Build Coastguard Worker     success = codecBitmap.tryAllocPixels(codecInfo);
85*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, success);
86*c8dee2aaSAndroid Build Coastguard Worker     SkCodec::Result result = codec->getPixels(codecInfo, codecBitmap.getPixels(),
87*c8dee2aaSAndroid Build Coastguard Worker                                               codecBitmap.rowBytes());
88*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, result == SkCodec::kSuccess);
89*c8dee2aaSAndroid Build Coastguard Worker 
90*c8dee2aaSAndroid Build Coastguard Worker 
91*c8dee2aaSAndroid Build Coastguard Worker     SkBitmap tmpBitmap;
92*c8dee2aaSAndroid Build Coastguard Worker     if (SkEncodedOriginSwapsWidthHeight(origin)) {
93*c8dee2aaSAndroid Build Coastguard Worker       codecInfo = SkPixmapUtils::SwapWidthHeight(codecInfo);
94*c8dee2aaSAndroid Build Coastguard Worker     }
95*c8dee2aaSAndroid Build Coastguard Worker     success = tmpBitmap.tryAllocPixels(codecInfo);
96*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, success);
97*c8dee2aaSAndroid Build Coastguard Worker 
98*c8dee2aaSAndroid Build Coastguard Worker     success = SkPixmapUtils::Orient(tmpBitmap.pixmap(), codecBitmap.pixmap(), origin);
99*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, success);
100*c8dee2aaSAndroid Build Coastguard Worker 
101*c8dee2aaSAndroid Build Coastguard Worker     codecBitmap.swap(tmpBitmap);
102*c8dee2aaSAndroid Build Coastguard Worker 
103*c8dee2aaSAndroid Build Coastguard Worker     // Compare the decoded SkCodec and the bits from the SkImageGenerator.
104*c8dee2aaSAndroid Build Coastguard Worker     // They should be the same because both should respect orientation.
105*c8dee2aaSAndroid Build Coastguard Worker     if (codecBitmap.dimensions() != genInfo.dimensions()) {
106*c8dee2aaSAndroid Build Coastguard Worker       ERRORF(reporter, "Bitmaps do not have the same dimentions.\n"
107*c8dee2aaSAndroid Build Coastguard Worker                         "\tgenBitmap: (%i, %i)\tcodecBitmap: (%i, %i)",
108*c8dee2aaSAndroid Build Coastguard Worker                         codecBitmap.dimensions().fWidth, codecBitmap.dimensions().fHeight,
109*c8dee2aaSAndroid Build Coastguard Worker                         genBitmap.dimensions().fWidth, genBitmap.dimensions().fHeight);
110*c8dee2aaSAndroid Build Coastguard Worker     }
111*c8dee2aaSAndroid Build Coastguard Worker       for (int k = 0; k < codecBitmap.width();  ++k) {
112*c8dee2aaSAndroid Build Coastguard Worker         for (int j = 0; j < codecBitmap.height(); ++j) {
113*c8dee2aaSAndroid Build Coastguard Worker             SkColor4f c1 = genBitmap.getColor4f(k, j);
114*c8dee2aaSAndroid Build Coastguard Worker             SkColor4f c2 = codecBitmap.getColor4f(k, j);
115*c8dee2aaSAndroid Build Coastguard Worker             if (!nearly_equal(c1, c2)) {
116*c8dee2aaSAndroid Build Coastguard Worker                 ERRORF(reporter, "Bitmaps for %s do not match starting at position %i, %i\n"
117*c8dee2aaSAndroid Build Coastguard Worker                           "\tgenBitmap: %x\tcodecBitmap: %x", path.c_str(), i, j,
118*c8dee2aaSAndroid Build Coastguard Worker                           c1.toSkColor(), c2.toSkColor());
119*c8dee2aaSAndroid Build Coastguard Worker                 return;
120*c8dee2aaSAndroid Build Coastguard Worker             }
121*c8dee2aaSAndroid Build Coastguard Worker         }
122*c8dee2aaSAndroid Build Coastguard Worker       }
123*c8dee2aaSAndroid Build Coastguard Worker   }
124*c8dee2aaSAndroid Build Coastguard Worker }
125