Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
Functions
skdiff_utils.cpp File Reference
#include "include/codec/SkPngDecoder.h"
#include "include/core/SkBitmap.h"
#include "include/core/SkData.h"
#include "include/core/SkPixelRef.h"
#include "include/core/SkStream.h"
#include "include/core/SkTypes.h"
#include "include/encode/SkPngEncoder.h"
#include "tools/skdiff/skdiff.h"
#include "tools/skdiff/skdiff_utils.h"
#include <memory>

Go to the source code of this file.

Functions

bool are_buffers_equal (SkData *skdata1, SkData *skdata2)
 
sk_sp< SkDataread_file (const char *file_path)
 
bool get_bitmap (sk_sp< SkData > fileBits, DiffResource &resource, bool sizeOnly, bool ignoreColorSpace)
 
static void force_all_opaque (const SkBitmap &bitmap)
 
bool write_bitmap (const SkString &path, const SkBitmap &bitmap)
 
static SkString replace_all (const SkString &input, const char oldSubstring[], const char newSubstring[])
 
static SkString filename_to_derived_filename (const SkString &filename, const char *suffix)
 
SkString filename_to_diff_filename (const SkString &filename)
 
SkString filename_to_white_filename (const SkString &filename)
 
void create_and_write_diff_image (DiffRecord *drp, DiffMetricProc dmp, const int colorThreshold, const SkString &outputDir, const SkString &filename)
 

Function Documentation

◆ are_buffers_equal()

bool are_buffers_equal ( SkData skdata1,
SkData skdata2 
)

Returns true if the two buffers passed in are both non-nullptr, have the same length, and contain exactly the same byte values.

Definition at line 19 of file skdiff_utils.cpp.

19 {
20 if ((nullptr == skdata1) || (nullptr == skdata2)) {
21 return false;
22 }
23 if (skdata1->size() != skdata2->size()) {
24 return false;
25 }
26 return (0 == memcmp(skdata1->data(), skdata2->data(), skdata1->size()));
27}
const void * data() const
Definition SkData.h:37
size_t size() const
Definition SkData.h:30

◆ create_and_write_diff_image()

void create_and_write_diff_image ( DiffRecord drp,
DiffMetricProc  dmp,
const int  colorThreshold,
const SkString outputDir,
const SkString filename 
)

Calls compute_diff and handles the difference and white diff resources. If !outputDir.isEmpty(), writes out difference and white images.

Definition at line 157 of file skdiff_utils.cpp.

161 {
162 const int w = drp->fBase.fBitmap.width();
163 const int h = drp->fBase.fBitmap.height();
164
165 if (w != drp->fComparison.fBitmap.width() || h != drp->fComparison.fBitmap.height()) {
167 } else {
169
171
173 compute_diff(drp, dmp, colorThreshold);
175 }
176
177 if (outputDir.isEmpty()) {
180
181 } else {
183 drp->fDifference.fFullPath = outputDir;
186
188 drp->fWhite.fFullPath = outputDir;
191
195 } else {
197 }
198 if (write_bitmap(drp->fWhite.fFullPath, drp->fWhite.fBitmap)) {
200 } else {
202 }
203 }
204 }
205}
#define SkASSERT(cond)
Definition SkAssert.h:116
int width() const
Definition SkBitmap.h:149
void allocN32Pixels(int width, int height, bool isOpaque=false)
Definition SkBitmap.cpp:232
int height() const
Definition SkBitmap.h:158
bool isEmpty() const
Definition SkString.h:130
void append(const char text[])
Definition SkString.h:203
SkScalar w
SkScalar h
void compute_diff(DiffRecord *dr, DiffMetricProc diffFunction, const int colorThreshold)
Definition skdiff.cpp:158
SkString filename_to_white_filename(const SkString &filename)
SkString filename_to_diff_filename(const SkString &filename)
bool write_bitmap(const SkString &path, const SkBitmap &bitmap)
DiffResource fDifference
Definition skdiff.h:132
DiffResource fComparison
Definition skdiff.h:131
Result fResult
Which category of diff result.
Definition skdiff.h:154
@ kUnknown_Result
Definition skdiff.h:97
@ kDifferentSizes_Result
Definition skdiff.h:95
@ kDifferentPixels_Result
Definition skdiff.h:94
DiffResource fBase
Definition skdiff.h:130
DiffResource fWhite
Definition skdiff.h:133
SkString fFullPath
Definition skdiff.h:81
SkBitmap fBitmap
Definition skdiff.h:83
@ kExists_Status
Definition skdiff.h:42
@ kDoesNotExist_Status
Definition skdiff.h:44
@ kSpecified_Status
Definition skdiff.h:47
@ kUnspecified_Status
Definition skdiff.h:49
Status fStatus
Definition skdiff.h:84
SkString fFilename
Definition skdiff.h:79

◆ filename_to_derived_filename()

static SkString filename_to_derived_filename ( const SkString filename,
const char *  suffix 
)
static

Definition at line 136 of file skdiff_utils.cpp.

136 {
137 SkString diffName (filename);
138 const char* cstring = diffName.c_str();
139 size_t dotOffset = strrchr(cstring, '.') - cstring;
140 diffName.remove(dotOffset, diffName.size() - dotOffset);
141 diffName.append(suffix);
142
143 // In case we recursed into subdirectories, replace slashes with something else
144 // so the diffs will all be written into a single flat directory.
145 diffName = replace_all(diffName, PATH_DIV_STR, "_");
146 return diffName;
147}
#define PATH_DIV_STR
Definition skdiff.h:21
static SkString replace_all(const SkString &input, const char oldSubstring[], const char newSubstring[])

◆ filename_to_diff_filename()

SkString filename_to_diff_filename ( const SkString filename)

Given an image filename, returns the name of the file containing the associated difference image.

Definition at line 149 of file skdiff_utils.cpp.

149 {
150 return filename_to_derived_filename(filename, "-diff.png");
151}
static SkString filename_to_derived_filename(const SkString &filename, const char *suffix)

◆ filename_to_white_filename()

SkString filename_to_white_filename ( const SkString filename)

Given an image filename, returns the name of the file containing the "white" difference image.

Definition at line 153 of file skdiff_utils.cpp.

153 {
154 return filename_to_derived_filename(filename, "-white.png");
155}

◆ force_all_opaque()

static void force_all_opaque ( const SkBitmap bitmap)
static

Thanks to PNG, we need to force all pixels 100% opaque.

Definition at line 89 of file skdiff_utils.cpp.

89 {
90 for (int y = 0; y < bitmap.height(); y++) {
91 for (int x = 0; x < bitmap.width(); x++) {
92 *bitmap.getAddr32(x, y) |= (SK_A32_MASK << SK_A32_SHIFT);
93 }
94 }
95}
#define SK_A32_MASK
Definition SkColorPriv.h:45
#define SK_A32_SHIFT
Definition SkTypes.h:54
double y
double x

◆ get_bitmap()

bool get_bitmap ( sk_sp< SkData fileBits,
DiffResource resource,
bool  sizeOnly,
bool  ignoreColorSpace 
)

Decodes the fileBits into the resource.fBitmap. Returns false on failure.

Definition at line 37 of file skdiff_utils.cpp.

38 {
39 static constexpr const SkCodecs::Decoder decoders[] = {
41 };
42
43 auto codec = SkCodec::MakeFromData(std::move(fileBits), decoders);
44 if (!codec) {
45 SkDebugf("ERROR: could not create codec for <%s>\n", resource.fFullPath.c_str());
47 return false;
48 }
49
50 // If we're "ignoring" color space, then we want the raw pixel values from each image, so we
51 // decode to the original color space. If we want to account for color spaces, then we want to
52 // decode each image to the same color space, so that colors that are the "same" (but encoded
53 // differently) are transformed to some canonical representation prior to comparison.
54 //
55 // TODO: Use something wider than sRGB to avoid clipping with out-of-gamut colors.
56 SkImageInfo info = codec->getInfo().makeColorType(kN32_SkColorType);
57 if (!ignoreColorSpace) {
59 }
60
61 if (!resource.fBitmap.setInfo(info.makeColorType(kN32_SkColorType))) {
62 SkDebugf("ERROR: could not set bitmap info for <%s>\n", resource.fFullPath.c_str());
64 return false;
65 }
66
67 if (sizeOnly) {
68 return true;
69 }
70
71 if (!resource.fBitmap.tryAllocPixels()) {
72 SkDebugf("ERROR: could not allocate pixels for <%s>\n", resource.fFullPath.c_str());
74 return false;
75 }
76
77 if (SkCodec::kSuccess != codec->getPixels(resource.fBitmap.info(),
78 resource.fBitmap.getPixels(), resource.fBitmap.rowBytes())) {
79 SkDebugf("ERROR: codec failed for basePath <%s>\n", resource.fFullPath.c_str());
81 return false;
82 }
83
85 return true;
86}
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
Definition DM.cpp:213
void SK_SPI SkDebugf(const char format[],...) SK_PRINTF_LIKE(1
size_t rowBytes() const
Definition SkBitmap.h:238
void * getPixels() const
Definition SkBitmap.h:283
const SkImageInfo & info() const
Definition SkBitmap.h:139
bool setInfo(const SkImageInfo &imageInfo, size_t rowBytes=0)
Definition SkBitmap.cpp:114
bool tryAllocPixels(const SkImageInfo &info, size_t rowBytes)
Definition SkBitmap.cpp:271
static std::unique_ptr< SkCodec > MakeFromData(sk_sp< SkData >, SkSpan< const SkCodecs::Decoder > decoders, SkPngChunkReader *=nullptr)
Definition SkCodec.cpp:241
@ kSuccess
Definition SkCodec.h:80
static sk_sp< SkColorSpace > MakeSRGB()
const char * c_str() const
Definition SkString.h:133
constexpr SkCodecs::Decoder Decoder()
@ kCouldNotDecode_Status
Definition skdiff.h:34
@ kDecoded_Status
Definition skdiff.h:32
SkImageInfo makeColorSpace(sk_sp< SkColorSpace > cs) const
SkImageInfo makeColorType(SkColorType newColorType) const

◆ read_file()

sk_sp< SkData > read_file ( const char *  file_path)

Reads the file at the given path and returns its complete contents as an SkData object (or returns nullptr on error).

Definition at line 29 of file skdiff_utils.cpp.

29 {
31 if (!data) {
32 SkDebugf("WARNING: could not open file <%s> for reading\n", file_path);
33 }
34 return data;
35}
static sk_sp< SkData > MakeFromFileName(const char path[])
Definition SkData.cpp:148
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot data
Definition switches.h:41

◆ replace_all()

static SkString replace_all ( const SkString input,
const char  oldSubstring[],
const char  newSubstring[] 
)
static

Return a copy of the "input" string, within which we have replaced all instances of oldSubstring with newSubstring.

TODO: If we like this, we should move it into the core SkString implementation, adding more checks and ample test cases, and paying more attention to efficiency.

Definition at line 120 of file skdiff_utils.cpp.

121 {
123 const char *input_cstr = input.c_str();
124 const char *first_char = input_cstr;
125 const char *match_char;
126 size_t oldSubstringLen = strlen(oldSubstring);
127 while ((match_char = strstr(first_char, oldSubstring))) {
128 output.append(first_char, (match_char - first_char));
129 output.append(newSubstring);
130 first_char = match_char + oldSubstringLen;
131 }
132 output.append(first_char);
133 return output;
134}

◆ write_bitmap()

bool write_bitmap ( const SkString path,
const SkBitmap bitmap 
)

Writes the bitmap as a PNG to the path specified.

Definition at line 97 of file skdiff_utils.cpp.

97 {
99 if (!copy.tryAllocPixels(bitmap.info().makeColorType(kN32_SkColorType))) {
100 return false;
101 }
102 if (!bitmap.readPixels(copy.pixmap())) {
103 return false;
104 }
106
107 SkFILEWStream file(path.c_str());
108 if (!file.isValid()) {
109 return false;
110 }
111
112 return SkPngEncoder::Encode(&file, copy.pixmap(), {});
113}
SK_API bool Encode(SkWStream *dst, const SkPixmap &src, const Options &options)
Definition copy.py:1
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir path
Definition switches.h:57
static void force_all_opaque(const SkBitmap &bitmap)