Skip to content

Commit 79648dd

Browse files
Image tools: combined GetImageDifference and ComputeDifferenceImage into one function
1 parent bc41c1d commit 79648dd

File tree

3 files changed

+94
-222
lines changed

3 files changed

+94
-222
lines changed

Common/interface/ImageTools.h

Lines changed: 19 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,8 @@ struct ImageDiffInfo
5757
typedef struct ImageDiffInfo ImageDiffInfo;
5858

5959

60-
/// Attributes for GetImageDifference function
61-
struct GetImageDifferenceAttribs
60+
/// Attributes for ComputeImageDifference function
61+
struct ComputeImageDifferenceAttribs
6262
{
6363
/// Image width
6464
Uint32 Width DEFAULT_INITIALIZER(0);
@@ -86,52 +86,9 @@ struct GetImageDifferenceAttribs
8686

8787
/// Difference threshold
8888
Uint32 Threshold DEFAULT_INITIALIZER(0);
89-
};
90-
typedef struct GetImageDifferenceAttribs GetImageDifferenceAttribs;
91-
92-
/// Computes the difference between two images
93-
///
94-
/// \param [in] Attribs Image difference attributes, see Diligent::GetImageDifferenceAttribs.
95-
///
96-
/// \return The image difference information, see Diligent::ImageDiffInfo.
97-
///
98-
/// \remarks The difference between two pixels is calculated as the maximum of the
99-
/// absolute differences of all channels. The average difference is the
100-
/// average of all differences, not counting pixels that are equal.
101-
/// The root mean square difference is calculated as the square root of
102-
/// the average of the squares of all differences, not counting pixels that
103-
/// are equal.
104-
void DILIGENT_GLOBAL_FUNCTION(GetImageDifference)(const GetImageDifferenceAttribs REF Attribs, ImageDiffInfo REF ImageDiff);
10589

106-
107-
/// Attributes for ComputeDifferenceImage function
108-
struct ComputeDifferenceImageAttribs
109-
{
110-
/// Image width
111-
Uint32 Width DEFAULT_INITIALIZER(0);
112-
113-
/// Image height
114-
Uint32 Height DEFAULT_INITIALIZER(0);
115-
116-
/// A pointer to the first image data
117-
const void* pImage1 DEFAULT_INITIALIZER(nullptr);
118-
119-
/// Number of channels in the first image
120-
Uint32 NumChannels1 DEFAULT_INITIALIZER(0);
121-
122-
/// Row stride of the first image data, in bytes
123-
Uint32 Stride1 DEFAULT_INITIALIZER(0);
124-
125-
/// A pointer to the second image data
126-
const void* pImage2 DEFAULT_INITIALIZER(nullptr);
127-
128-
/// Number of channels in the second image
129-
Uint32 NumChannels2 DEFAULT_INITIALIZER(0);
130-
131-
/// Row stride of the second image data, in bytes
132-
Uint32 Stride2 DEFAULT_INITIALIZER(0);
133-
134-
/// A pointer to the difference image data
90+
/// A pointer to the difference image data.
91+
/// If null, the difference image will not be computed.
13592
void* pDiffImage DEFAULT_INITIALIZER(nullptr);
13693

13794
/// Row stride of the difference image data, in bytes
@@ -144,12 +101,23 @@ struct ComputeDifferenceImageAttribs
144101
/// Scale factor for the difference image
145102
float Scale DEFAULT_INITIALIZER(1.f);
146103
};
147-
typedef struct ComputeDifferenceImageAttribs ComputeDifferenceImageAttribs;
104+
typedef struct ComputeImageDifferenceAttribs ComputeImageDifferenceAttribs;
148105

149-
/// Computes the difference image
106+
/// Computes the difference between two images
107+
///
108+
/// \param [in] Attribs Image difference attributes, see Diligent::ComputeImageDifferenceAttribs.
109+
///
110+
/// \return The image difference information, see Diligent::ImageDiffInfo.
150111
///
151-
/// \param [in] Attribs Compute difference image attributes, see Diligent::ComputeDifferenceImageAttribs.
152-
void DILIGENT_GLOBAL_FUNCTION(ComputeDifferenceImage)(const ComputeDifferenceImageAttribs REF Attribs);
112+
/// \remarks The difference between two pixels is calculated as the maximum of the
113+
/// absolute differences of all channels. The average difference is the
114+
/// average of all differences, not counting pixels that are equal.
115+
/// The root mean square difference is calculated as the square root of
116+
/// the average of the squares of all differences, not counting pixels that
117+
/// are equal.
118+
void DILIGENT_GLOBAL_FUNCTION(ComputeImageDifference)(const ComputeImageDifferenceAttribs REF Attribs, ImageDiffInfo REF ImageDiff);
119+
120+
153121
// clang-format on
154122

155123
#include "../../Primitives/interface/UndefRefMacro.h"

Common/src/ImageTools.cpp

Lines changed: 33 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@
3434
namespace Diligent
3535
{
3636

37-
void GetImageDifference(const GetImageDifferenceAttribs& Attribs,
38-
ImageDiffInfo& Diff)
37+
void ComputeImageDifference(const ComputeImageDifferenceAttribs& Attribs,
38+
ImageDiffInfo& Diff)
3939
{
4040
Diff = {};
4141

@@ -68,21 +68,45 @@ void GetImageDifference(const GetImageDifferenceAttribs& Attribs,
6868
return;
6969
}
7070

71-
const Uint32 NumChannels = std::min(Attribs.NumChannels1, Attribs.NumChannels2);
71+
const Uint32 NumSrcChannels = std::min(Attribs.NumChannels1, Attribs.NumChannels2);
72+
const Uint32 NumDiffChannels = Attribs.NumDiffChannels != 0 ? Attribs.NumDiffChannels : NumSrcChannels;
73+
if (Attribs.pDiffImage != nullptr)
74+
{
75+
if (Attribs.DiffStride < Attribs.Width * NumDiffChannels)
76+
{
77+
UNEXPECTED("DiffStride is too small. It must be at least ", Attribs.Width * NumDiffChannels, " bytes long.");
78+
return;
79+
}
80+
}
81+
7282
for (Uint32 row = 0; row < Attribs.Height; ++row)
7383
{
74-
const Uint8* pRow1 = reinterpret_cast<const Uint8*>(Attribs.pImage1) + row * Attribs.Stride1;
75-
const Uint8* pRow2 = reinterpret_cast<const Uint8*>(Attribs.pImage2) + row * Attribs.Stride2;
84+
const Uint8* pRow1 = reinterpret_cast<const Uint8*>(Attribs.pImage1) + row * Attribs.Stride1;
85+
const Uint8* pRow2 = reinterpret_cast<const Uint8*>(Attribs.pImage2) + row * Attribs.Stride2;
86+
Uint8* pDiffRow = Attribs.pDiffImage != nullptr ? reinterpret_cast<Uint8*>(Attribs.pDiffImage) + row * Attribs.DiffStride : nullptr;
7687

7788
for (Uint32 col = 0; col < Attribs.Width; ++col)
7889
{
7990
Uint32 PixelDiff = 0;
80-
for (Uint32 ch = 0; ch < NumChannels; ++ch)
91+
for (Uint32 ch = 0; ch < NumSrcChannels; ++ch)
8192
{
8293
const Uint32 ChannelDiff = static_cast<Uint32>(
8394
std::abs(static_cast<int>(pRow1[col * Attribs.NumChannels1 + ch]) -
8495
static_cast<int>(pRow2[col * Attribs.NumChannels2 + ch])));
8596
PixelDiff = std::max(PixelDiff, ChannelDiff);
97+
98+
if (pDiffRow != nullptr && ch < NumDiffChannels)
99+
{
100+
pDiffRow[col * NumDiffChannels + ch] = static_cast<Uint8>(std::min(ChannelDiff * Attribs.Scale, 255.f));
101+
}
102+
}
103+
104+
if (pDiffRow != nullptr)
105+
{
106+
for (Uint32 ch = NumSrcChannels; ch < NumDiffChannels; ++ch)
107+
{
108+
pDiffRow[col * NumDiffChannels + ch] = ch == 3 ? 255 : 0;
109+
}
86110
}
87111

88112
if (PixelDiff != 0)
@@ -107,79 +131,13 @@ void GetImageDifference(const GetImageDifferenceAttribs& Attribs,
107131
}
108132
}
109133

110-
void ComputeDifferenceImage(const ComputeDifferenceImageAttribs& Attribs)
111-
{
112-
if (Attribs.pImage1 == nullptr || Attribs.pImage2 == nullptr || Attribs.pDiffImage == nullptr)
113-
{
114-
UNEXPECTED("Image pointers cannot be null");
115-
return;
116-
}
117-
118-
if (Attribs.NumChannels1 == 0)
119-
{
120-
UNEXPECTED("NumChannels1 cannot be zero");
121-
return;
122-
}
123-
if (Attribs.Stride1 < Attribs.Width * Attribs.NumChannels1)
124-
{
125-
UNEXPECTED("Stride1 is too small. It must be at least ", Attribs.Width * Attribs.NumChannels1, " bytes long.");
126-
return;
127-
}
128-
129-
if (Attribs.NumChannels2 == 0)
130-
{
131-
UNEXPECTED("NumChannels2 cannot be zero");
132-
return;
133-
}
134-
if (Attribs.Stride2 < Attribs.Width * Attribs.NumChannels2)
135-
{
136-
UNEXPECTED("Stride2 is too small. It must be at least ", Attribs.Width * Attribs.NumChannels2, " bytes long.");
137-
return;
138-
}
139-
140-
const Uint32 NumSrcChannels = std::min(Attribs.NumChannels1, Attribs.NumChannels2);
141-
const Uint32 NumDiffChannels = Attribs.NumDiffChannels != 0 ? Attribs.NumDiffChannels : NumSrcChannels;
142-
if (Attribs.DiffStride < Attribs.Width * NumDiffChannels)
143-
{
144-
UNEXPECTED("DiffStride is too small. It must be at least ", Attribs.Width * NumDiffChannels, " bytes long.");
145-
return;
146-
}
147-
148-
for (Uint32 row = 0; row < Attribs.Height; ++row)
149-
{
150-
const Uint8* pRow1 = reinterpret_cast<const Uint8*>(Attribs.pImage1) + row * Attribs.Stride1;
151-
const Uint8* pRow2 = reinterpret_cast<const Uint8*>(Attribs.pImage2) + row * Attribs.Stride2;
152-
Uint8* pDiffRow = reinterpret_cast<Uint8*>(Attribs.pDiffImage) + row * Attribs.DiffStride;
153-
154-
for (Uint32 col = 0; col < Attribs.Width; ++col)
155-
{
156-
for (Uint32 ch = 0; ch < NumDiffChannels; ++ch)
157-
{
158-
int ChannelDiff = ch == 3 ? 255 : 0;
159-
if (ch < NumSrcChannels)
160-
{
161-
ChannelDiff = std::abs(static_cast<int>(pRow1[col * Attribs.NumChannels1 + ch]) -
162-
static_cast<int>(pRow2[col * Attribs.NumChannels2 + ch]));
163-
ChannelDiff = std::min(255, static_cast<int>(ChannelDiff * Attribs.Scale));
164-
}
165-
pDiffRow[col * NumDiffChannels + ch] = static_cast<Uint8>(ChannelDiff);
166-
}
167-
}
168-
}
169-
}
170-
171134
} // namespace Diligent
172135

173136
extern "C"
174137
{
175-
void Diligent_GetImageDifference(const Diligent::GetImageDifferenceAttribs& Attribs,
176-
Diligent::ImageDiffInfo& ImageDiff)
177-
{
178-
Diligent::GetImageDifference(Attribs, ImageDiff);
179-
}
180-
181-
void Diligent_ComputeDifferenceImage(const Diligent::ComputeDifferenceImageAttribs& Attribs)
138+
void Diligent_ComputeImageDifference(const Diligent::ComputeImageDifferenceAttribs& Attribs,
139+
Diligent::ImageDiffInfo& ImageDiff)
182140
{
183-
Diligent::ComputeDifferenceImage(Attribs);
141+
Diligent::ComputeImageDifference(Attribs, ImageDiff);
184142
}
185143
}

0 commit comments

Comments
 (0)