Skip to content

Commit 57f8799

Browse files
Merge pull request #690 from IENT/merge/mse-alpha-compare
Merge/mse alpha compare
2 parents e4cfd0a + 63e907c commit 57f8799

4 files changed

Lines changed: 59 additions & 24 deletions

File tree

YUViewLib/src/video/rgb/ConversionDifferenceRGB.cpp

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -124,27 +124,39 @@ calculateDifferencePredefinedPixelFormat(const InputFrameParameters &frame1,
124124
dst += 4;
125125
}
126126

127-
return {outputImage, sse.getMSE()};
127+
return {outputImage, sse.getMSE(false)};
128128
}
129129

130130
template <typename T>
131-
rgba_t getRGBAndConvertEndianness(const DataPointers<T> dataPointers, const Endianness endianness)
131+
rgba_t getRGBAndConvertEndianness(const DataPointers<T> dataPointers,
132+
const PixelFormatRGB &pixelFormat)
132133
{
133134
constexpr auto bitDepth =
134135
(std::is_same_v<T, uint8_t> ? 8 : (std::is_same_v<T, uint16_t> ? 16 : 32));
135136

136137
auto r = *dataPointers.r;
137138
auto g = *dataPointers.g;
138139
auto b = *dataPointers.b;
140+
T a = 0;
139141

140-
if (endianness == Endianness::Big)
142+
if (pixelFormat.getEndianness() == Endianness::Big)
141143
{
142144
r = swapBytesEndianness<bitDepth>(r);
143145
g = swapBytesEndianness<bitDepth>(g);
144146
b = swapBytesEndianness<bitDepth>(b);
145147
}
146148

147-
return rgba_t({.r = static_cast<int>(r), .g = static_cast<int>(g), .b = static_cast<int>(b)});
149+
if (pixelFormat.hasAlpha())
150+
{
151+
a = *dataPointers.a;
152+
if (pixelFormat.getEndianness() == Endianness::Big)
153+
a = swapBytesEndianness<bitDepth>(a);
154+
}
155+
156+
return rgba_t({.r = static_cast<int>(r),
157+
.g = static_cast<int>(g),
158+
.b = static_cast<int>(b),
159+
.a = static_cast<int>(a)});
148160
}
149161

150162
template <typename T>
@@ -163,9 +175,9 @@ std::pair<QImage, MSE> calculateDifferenceAndMSE(const InputFrameParameters &fra
163175
calculatePointersToStartOfComponents<T>(frame2.rawDataItem, frame2.frameSize, pixelFormat);
164176

165177
const auto frameSize = Size(std::min(frame1.frameSize.width, frame2.frameSize.width),
166-
std::min(frame1.frameSize.height, frame2.frameSize.height));
178+
std::min(frame1.frameSize.height, frame2.frameSize.height));
167179
auto outputImage = QImage(QSize(frameSize.width, frameSize.height),
168-
functionsGui::platformImageFormat(pixelFormat.hasAlpha()));
180+
functionsGui::platformImageFormat(pixelFormat.hasAlpha()));
169181
SSE sse;
170182

171183
unsigned char *restrict dst = outputImage.bits();
@@ -174,8 +186,8 @@ std::pair<QImage, MSE> calculateDifferenceAndMSE(const InputFrameParameters &fra
174186

175187
for (unsigned i = 0; i < frameSize.width * frameSize.height; ++i)
176188
{
177-
const auto rgb1 = getRGBAndConvertEndianness(dataPointers1, pixelFormat.getEndianness());
178-
const auto rgb2 = getRGBAndConvertEndianness(dataPointers2, pixelFormat.getEndianness());
189+
const auto rgb1 = getRGBAndConvertEndianness(dataPointers1, pixelFormat);
190+
const auto rgb2 = getRGBAndConvertEndianness(dataPointers2, pixelFormat);
179191

180192
const auto delta = rgb1 - rgb2;
181193

@@ -190,11 +202,16 @@ std::pair<QImage, MSE> calculateDifferenceAndMSE(const InputFrameParameters &fra
190202
dst += 4;
191203
}
192204

193-
return {outputImage, sse.getMSE()};
205+
return {outputImage, sse.getMSE(pixelFormat.hasAlpha())};
194206
}
195207

196208
} // namespace
197209

210+
void PrintTo(const MSE &mse, std::ostream *os)
211+
{
212+
*os << "MSE(r=" << mse.r << ", g=" << mse.g << ", b=" << mse.b << ", a=" << mse.a << ")";
213+
}
214+
198215
std::pair<QImage, MSE> calculateDifferenceAndMSE(const InputFrameParameters &frame1,
199216
const InputFrameParameters &frame2,
200217
const PixelFormatRGB &pixelFormat,

YUViewLib/src/video/rgb/ConversionDifferenceRGB.h

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@
3737
#include <QByteArray>
3838
#include <QImage>
3939

40+
#include <ostream>
41+
4042
namespace video::rgb
4143
{
4244

@@ -55,10 +57,12 @@ struct MSE
5557

5658
bool operator==(const MSE &other) const
5759
{
58-
return std::tie(r, g, b, a) == std::tie(other.r, other.g, other.b, a);
60+
return std::tie(r, g, b, a) == std::tie(other.r, other.g, other.b, other.a);
5961
}
6062
};
6163

64+
void PrintTo(const MSE &mse, std::ostream *os);
65+
6266
// Sum of Squared Errors
6367
class SSE
6468
{
@@ -72,13 +76,13 @@ class SSE
7276
++this->nrSamples;
7377
}
7478

75-
MSE getMSE() const
79+
MSE getMSE(const bool hasAlpha) const
7680
{
7781
MSE mse;
7882
mse.r = static_cast<double>(this->r) / this->nrSamples;
7983
mse.g = static_cast<double>(this->g) / this->nrSamples;
8084
mse.b = static_cast<double>(this->b) / this->nrSamples;
81-
mse.a = static_cast<double>(this->a) / this->nrSamples;
85+
mse.a = hasAlpha ? static_cast<double>(this->a) / this->nrSamples : 0.0;
8286
return mse;
8387
}
8488

YUViewLib/src/video/rgb/ConversionFunctions.h

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -41,15 +41,17 @@ namespace video::rgb
4141

4242
template <typename T> struct DataPointers
4343
{
44-
const T *r;
45-
const T *g;
46-
const T *b;
44+
const T *r{};
45+
const T *g{};
46+
const T *b{};
47+
const T *a{};
4748

4849
DataPointers operator+=(const int offset)
4950
{
5051
this->r += offset;
5152
this->g += offset;
5253
this->b += offset;
54+
this->a += offset;
5355
return *this;
5456
}
5557
};
@@ -69,19 +71,30 @@ DataPointers<T> calculatePointersToStartOfComponents(const QByteArray &rawFr
6971
const auto posR = pixelFormat.getChannelPosition(Channel::Red);
7072
const auto posG = pixelFormat.getChannelPosition(Channel::Green);
7173
const auto posB = pixelFormat.getChannelPosition(Channel::Blue);
74+
const auto posA = pixelFormat.getChannelPosition(Channel::Alpha);
7275

7376
const auto castDataPointer = reinterpret_cast<T const *>(rawFrameData.data());
7477

78+
DataPointers<T> dataPointers;
7579
if (pixelFormat.getDataLayout() == DataLayout::Planar)
7680
{
7781
const auto offsetToNextPlane = frameSize.width * frameSize.height;
7882

79-
return {.r = castDataPointer + (posR * offsetToNextPlane),
80-
.g = castDataPointer + (posG * offsetToNextPlane),
81-
.b = castDataPointer + (posB * offsetToNextPlane)};
83+
dataPointers.r = castDataPointer + (posR * offsetToNextPlane);
84+
dataPointers.g = castDataPointer + (posG * offsetToNextPlane);
85+
dataPointers.b = castDataPointer + (posB * offsetToNextPlane);
86+
dataPointers.a =
87+
pixelFormat.hasAlpha() ? castDataPointer + (posA * offsetToNextPlane) : nullptr;
88+
}
89+
else
90+
{
91+
dataPointers.r = castDataPointer + posR;
92+
dataPointers.g = castDataPointer + posG;
93+
dataPointers.b = castDataPointer + posB;
94+
dataPointers.a = pixelFormat.hasAlpha() ? castDataPointer + posA : nullptr;
8295
}
8396

84-
return {.r = castDataPointer + posR, .g = castDataPointer + posG, .b = castDataPointer + posB};
97+
return dataPointers;
8598
}
8699

87100
inline rgba_t extractRGB565Value(const unsigned char *data, const Endianness endianness)

YUViewUnitTest/video/rgb/ConversionDifferenceRGBTest.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,8 @@ FrameAandB createTestFrameDataRGB565()
147147
using ExpectedImageAndMse = std::pair<QImage, MSE>;
148148
ExpectedImageAndMse generateExpectedImageAndMse(const FrameAandB &testFrames,
149149
const int amplificationFactor,
150-
bool markDifference)
150+
bool markDifference,
151+
bool hasAlpha)
151152
{
152153
QImage image(QSize(TEST_FRAME_SIZE.width, TEST_FRAME_SIZE.height),
153154
functionsGui::platformImageFormat(false));
@@ -159,7 +160,7 @@ ExpectedImageAndMse generateExpectedImageAndMse(const FrameAandB &testFrames,
159160
const auto &pixelA = testFrames.first.at(i);
160161
const auto &pixelB = testFrames.second.at(i);
161162

162-
const auto diff = pixelA - pixelB;
163+
auto diff = pixelA - pixelB;
163164

164165
sse.addSample(diff);
165166

@@ -177,7 +178,7 @@ ExpectedImageAndMse generateExpectedImageAndMse(const FrameAandB &testFrames,
177178
image.setPixel(x, y, qRgb(outputPixel.r, outputPixel.g, outputPixel.b));
178179
}
179180

180-
return {image, sse.getMSE()};
181+
return {image, sse.getMSE(hasAlpha)};
181182
}
182183

183184
using GenerationResult = std::tuple<QByteArray, QByteArray, QImage, MSE>;
@@ -207,8 +208,8 @@ GenerationResult generateRawDataFramesExpectedResultAndMse(const PixelFormatRGB
207208
std::get<1>(result) = createRawRGBData(pixelFormat, testFrames.second, bitDepth);
208209
}
209210

210-
std::tie(std::get<2>(result), std::get<3>(result)) =
211-
generateExpectedImageAndMse(testFrames, amplificationFactor, markDifference);
211+
std::tie(std::get<2>(result), std::get<3>(result)) = generateExpectedImageAndMse(
212+
testFrames, amplificationFactor, markDifference, pixelFormat.hasAlpha());
212213

213214
return result;
214215
}

0 commit comments

Comments
 (0)