Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
ExifTest.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2016 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
12#include "include/core/SkSize.h"
15#include "tests/Test.h"
16#include "tools/Resources.h"
17
18#include <memory>
19#include <tuple>
20#include <utility>
21
22DEF_TEST(ExifOrientation, r) {
23 std::unique_ptr<SkStream> stream(GetResourceAsStream("images/exif-orientation-2-ur.jpg"));
24 REPORTER_ASSERT(r, nullptr != stream);
25 if (!stream) {
26 return;
27 }
28
29 std::unique_ptr<SkCodec> codec(SkCodec::MakeFromStream(std::move(stream)));
30 REPORTER_ASSERT(r, nullptr != codec);
31 SkEncodedOrigin origin = codec->getOrigin();
33
34 codec = SkCodec::MakeFromStream(GetResourceAsStream("images/mandrill_512_q075.jpg"));
35 REPORTER_ASSERT(r, nullptr != codec);
36 origin = codec->getOrigin();
38}
39
40DEF_TEST(GetImageRespectsExif, r) {
41 std::unique_ptr<SkStream> stream(GetResourceAsStream("images/orientation/6.webp"));
42 REPORTER_ASSERT(r, nullptr != stream);
43 if (!stream) {
44 return;
45 }
46
47 std::unique_ptr<SkCodec> codec(SkWebpDecoder::Decode(std::move(stream), nullptr));
48 REPORTER_ASSERT(r, nullptr != codec);
49 SkEncodedOrigin origin = codec->getOrigin();
51 "Actual origin %d", origin);
52
53 auto result = codec->getImage();
55 "Not success %d", std::get<1>(result));
56 sk_sp<SkImage> frame = std::get<0>(result);
58 SkISize dims = frame->dimensions();
59 REPORTER_ASSERT(r, dims.fWidth == 100, "width %d != 100", dims.fWidth);
60 REPORTER_ASSERT(r, dims.fHeight == 80, "height %d != 80", dims.fHeight);
61}
62
63DEF_TEST(ExifOrientationInExif, r) {
64 std::unique_ptr<SkStream> stream(GetResourceAsStream("images/orientation/exif.jpg"));
65
66 std::unique_ptr<SkCodec> codec = SkCodec::MakeFromStream(std::move(stream));
67 REPORTER_ASSERT(r, nullptr != codec);
68 SkEncodedOrigin origin = codec->getOrigin();
70}
71
72DEF_TEST(ExifOrientationInSubIFD, r) {
73 std::unique_ptr<SkStream> stream(GetResourceAsStream("images/orientation/subifd.jpg"));
74
75 std::unique_ptr<SkCodec> codec = SkCodec::MakeFromStream(std::move(stream));
76 REPORTER_ASSERT(r, nullptr != codec);
77 SkEncodedOrigin origin = codec->getOrigin();
79}
80
81static bool approx_eq(float x, float y, float epsilon) { return std::abs(x - y) < epsilon; }
82
83DEF_TEST(ExifParse, r) {
84 const float kEpsilon = 0.001f;
85
86 {
87 sk_sp<SkData> data = GetResourceAsData("images/test0-hdr.exif");
88 REPORTER_ASSERT(r, nullptr != data);
89 SkExifMetadata exif(data);
90 float hdrHeadroom = 0.f;
91 REPORTER_ASSERT(r, exif.getHdrHeadroom(&hdrHeadroom));
92 REPORTER_ASSERT(r, approx_eq(hdrHeadroom, 3.755296f, kEpsilon));
93
94 uint16_t resolutionUnit = 0;
95 float xResolution = 0.f;
96 float yResolution = 0.f;
97 REPORTER_ASSERT(r, exif.getResolutionUnit(&resolutionUnit));
98 REPORTER_ASSERT(r, 2 == resolutionUnit);
99 REPORTER_ASSERT(r, exif.getXResolution(&xResolution));
100 REPORTER_ASSERT(r, 72.f == xResolution);
101 REPORTER_ASSERT(r, exif.getYResolution(&yResolution));
102 REPORTER_ASSERT(r, 72.f == yResolution);
103
104 uint32_t pixelXDimension = 0;
105 uint32_t pixelYDimension = 0;
106 REPORTER_ASSERT(r, exif.getPixelXDimension(&pixelXDimension));
107 REPORTER_ASSERT(r, 4032 == pixelXDimension);
108 REPORTER_ASSERT(r, exif.getPixelYDimension(&pixelYDimension));
109 REPORTER_ASSERT(r, 3024 == pixelYDimension);
110 }
111
112 {
113 sk_sp<SkData> data = GetResourceAsData("images/test1-pixel32.exif");
114 REPORTER_ASSERT(r, nullptr != data);
115 SkExifMetadata exif(data);
116 float hdrHeadroom = 0.f;
117 REPORTER_ASSERT(r, !exif.getHdrHeadroom(&hdrHeadroom));
118
119 uint16_t resolutionUnit = 0;
120 float xResolution = 0.f;
121 float yResolution = 0.f;
122 REPORTER_ASSERT(r, exif.getResolutionUnit(&resolutionUnit));
123 REPORTER_ASSERT(r, 2 == resolutionUnit);
124 REPORTER_ASSERT(r, exif.getXResolution(&xResolution));
125 REPORTER_ASSERT(r, 72.f == xResolution);
126 REPORTER_ASSERT(r, exif.getYResolution(&yResolution));
127 REPORTER_ASSERT(r, 72.f == yResolution);
128
129 uint32_t pixelXDimension = 0;
130 uint32_t pixelYDimension = 0;
131 REPORTER_ASSERT(r, exif.getPixelXDimension(&pixelXDimension));
132 REPORTER_ASSERT(r, 200 == pixelXDimension);
133 REPORTER_ASSERT(r, exif.getPixelYDimension(&pixelYDimension));
134 REPORTER_ASSERT(r, 100 == pixelYDimension);
135 }
136
137 {
138 sk_sp<SkData> data = GetResourceAsData("images/test2-nonuniform.exif");
139 REPORTER_ASSERT(r, nullptr != data);
140 SkExifMetadata exif(data);
141 float hdrHeadroom = 0.f;
142 REPORTER_ASSERT(r, !exif.getHdrHeadroom(&hdrHeadroom));
143
144 uint16_t resolutionUnit = 0;
145 float xResolution = 0.f;
146 float yResolution = 0.f;
147 REPORTER_ASSERT(r, exif.getResolutionUnit(&resolutionUnit));
148 REPORTER_ASSERT(r, 2 == resolutionUnit);
149 REPORTER_ASSERT(r, exif.getXResolution(&xResolution));
150 REPORTER_ASSERT(r, 144.f == xResolution);
151 REPORTER_ASSERT(r, exif.getYResolution(&yResolution));
152 REPORTER_ASSERT(r, 36.f == yResolution);
153
154 uint32_t pixelXDimension = 0;
155 uint32_t pixelYDimension = 0;
156 REPORTER_ASSERT(r, exif.getPixelXDimension(&pixelXDimension));
157 REPORTER_ASSERT(r, 50 == pixelXDimension);
158 REPORTER_ASSERT(r, exif.getPixelYDimension(&pixelYDimension));
159 REPORTER_ASSERT(r, 100 == pixelYDimension);
160 }
161
162 {
163 sk_sp<SkData> data = GetResourceAsData("images/test3-little-endian.exif");
164 REPORTER_ASSERT(r, nullptr != data);
165 SkExifMetadata exif(data);
166 float hdrHeadroom = 0.f;
167 REPORTER_ASSERT(r, !exif.getHdrHeadroom(&hdrHeadroom));
168
169 uint16_t resolutionUnit = 0;
170 float xResolution = 0.f;
171 float yResolution = 0.f;
172 REPORTER_ASSERT(r, exif.getResolutionUnit(&resolutionUnit));
173 REPORTER_ASSERT(r, 2 == resolutionUnit);
174 REPORTER_ASSERT(r, exif.getXResolution(&xResolution));
175 REPORTER_ASSERT(r, 350.f == xResolution);
176 REPORTER_ASSERT(r, exif.getYResolution(&yResolution));
177 REPORTER_ASSERT(r, 350.f == yResolution);
178
179 uint32_t pixelXDimension = 0;
180 uint32_t pixelYDimension = 0;
181 REPORTER_ASSERT(r, !exif.getPixelXDimension(&pixelXDimension));
182 REPORTER_ASSERT(r, !exif.getPixelYDimension(&pixelYDimension));
183 }
184
185 {
186 sk_sp<SkData> data = GetResourceAsData("images/test0-hdr.exif");
187
188 // Zero out the denominators of signed and unsigned rationals, to verify that we do not
189 // divide by zero.
190 data = SkData::MakeWithCopy(data->bytes(), data->size());
191 memset(static_cast<uint8_t*>(data->writable_data()) + 186, 0, 4);
192 memset(static_cast<uint8_t*>(data->writable_data()) + 2171, 0, 4);
193 memset(static_cast<uint8_t*>(data->writable_data()) + 2240, 0, 4);
194
195 // Parse the corrupted Exif.
196 SkExifMetadata exif(data);
197
198 // HDR headroom signed denominators are destroyed.
199 float hdrHeadroom = 0.f;
200 REPORTER_ASSERT(r, exif.getHdrHeadroom(&hdrHeadroom));
201 REPORTER_ASSERT(r, approx_eq(hdrHeadroom, 3.482202f, kEpsilon));
202
203 // The X resolution should be zero.
204 float xResolution = 0.f;
205 float yResolution = 0.f;
206 REPORTER_ASSERT(r, exif.getXResolution(&xResolution));
207 REPORTER_ASSERT(r, 0.f == xResolution);
208 REPORTER_ASSERT(r, exif.getYResolution(&yResolution));
209 REPORTER_ASSERT(r, 72.f == yResolution);
210 }
211}
static bool approx_eq(float x, float y, float epsilon)
Definition ExifTest.cpp:81
std::unique_ptr< SkStreamAsset > GetResourceAsStream(const char *resource, bool useFileStream)
Definition Resources.cpp:31
sk_sp< SkData > GetResourceAsData(const char *resource)
Definition Resources.cpp:42
SkEncodedOrigin
@ kTopRight_SkEncodedOrigin
@ kTopLeft_SkEncodedOrigin
@ kLeftBottom_SkEncodedOrigin
@ kRightTop_SkEncodedOrigin
static constexpr double kEpsilon
#define DEF_TEST(name, reporter)
Definition Test.h:312
#define REPORTER_ASSERT(r, cond,...)
Definition Test.h:286
static std::unique_ptr< SkCodec > MakeFromStream(std::unique_ptr< SkStream >, SkSpan< const SkCodecs::Decoder > decoders, Result *=nullptr, SkPngChunkReader *=nullptr, SelectionPolicy selectionPolicy=SelectionPolicy::kPreferStillImage)
Definition SkCodec.cpp:163
@ kSuccess
Definition SkCodec.h:80
static sk_sp< SkData > MakeWithCopy(const void *data, size_t length)
Definition SkData.cpp:111
bool getPixelYDimension(uint32_t *out) const
Definition SkExif.h:67
bool getResolutionUnit(uint16_t *out) const
Definition SkExif.h:46
bool getHdrHeadroom(float *out) const
Definition SkExif.h:37
bool getYResolution(float *out) const
Definition SkExif.h:54
bool getXResolution(float *out) const
Definition SkExif.h:50
bool getPixelXDimension(uint32_t *out) const
Definition SkExif.h:63
double frame
Definition examples.cpp:31
GAsyncResult * result
double y
double x
SK_API std::unique_ptr< SkCodec > Decode(std::unique_ptr< SkStream >, SkCodec::Result *, SkCodecs::DecodeContext=nullptr)
int32_t fHeight
Definition SkSize.h:18
int32_t fWidth
Definition SkSize.h:17