Skip to content

Commit 46a3beb

Browse files
feat: Add an option noFailOnFsErrors to avoid exceptions on fs errors (#61)
* chore: Format C files * feat: Add an option to avoid failing on missing file path * chore(docs): Update README * Try to add specific esy version * Use nightly esy on CI * Try using macos 10.13 * Try with macos-latest
1 parent 5bbbc13 commit 46a3beb

File tree

10 files changed

+144
-83
lines changed

10 files changed

+144
-83
lines changed

.ci/utils/use-esy.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# steps to install esy globally
22

33
steps:
4-
- script: "npm install -g esy"
4+
- script: "npm install -g @esy-nightly/esy"
55
displayName: "install esy"

README.md

+12-4
Original file line numberDiff line numberDiff line change
@@ -88,16 +88,18 @@ export type ODiffOptions = Partial<{
8888
outputDiffMask: boolean;
8989
/** Do not compare images and produce output if images layout is different. */
9090
failOnLayoutDiff: boolean;
91+
/** Return { match: false, reason: '...' } instead of throwing error if file is missing. */
92+
noFailOnFsErrors: boolean;
9193
/** Color difference threshold (from 0 to 1). Less more precise. */
9294
threshold: number;
9395
/** If this is true, antialiased pixels are not counted to the diff of an image */
9496
antialiasing: boolean;
9597
/** An array of regions to ignore in the diff. */
9698
ignoreRegions: Array<{
97-
x1: number,
98-
y1: number,
99-
x2: number,
100-
y2: number,
99+
x1: number;
100+
y1: number;
101+
x2: number;
102+
y2: number;
101103
}>;
102104
}>;
103105

@@ -117,6 +119,12 @@ declare function compare(
117119
/** Percentage of different pixels in the whole image */
118120
diffPercentage: number;
119121
}
122+
| {
123+
match: false;
124+
reason: "file-not-exists";
125+
/** Errored file path */
126+
file: string;
127+
}
120128
>;
121129

122130
export { compare };

azure-pipelines.yml

+2-2
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ jobs:
1919
- template: .ci/build-platform.yml
2020
parameters:
2121
platform: MacOS
22-
vmImage: macOS-10.14
22+
vmImage: macOS-latest
2323

2424
# Need windows-2019 to do esy import/export-dependencies
2525
# which assumes you have bsdtar (tar.exe) in your system
@@ -38,7 +38,7 @@ jobs:
3838
- MacOS
3939
- Windows_x64
4040
pool:
41-
vmImage: macOS-10.14
41+
vmImage: macOS-latest
4242
demands: node.js
4343
steps:
4444
- template: .ci/cross-release.yml

bin/node-bindings/odiff.d.ts

+12-4
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,18 @@ export type ODiffOptions = Partial<{
55
outputDiffMask: boolean;
66
/** Do not compare images and produce output if images layout is different. */
77
failOnLayoutDiff: boolean;
8+
/** Return { match: false, reason: '...' } instead of throwing error if file is missing. */
9+
noFailOnFsErrors: boolean;
810
/** Color difference threshold (from 0 to 1). Less more precise. */
911
threshold: number;
1012
/** If this is true, antialiased pixels are not counted to the diff of an image */
1113
antialiasing: boolean;
1214
/** An array of regions to ignore in the diff. */
1315
ignoreRegions: Array<{
14-
x1: number,
15-
y1: number,
16-
x2: number,
17-
y2: number,
16+
x1: number;
17+
y1: number;
18+
x2: number;
19+
y2: number;
1820
}>;
1921
}>;
2022

@@ -34,6 +36,12 @@ declare function compare(
3436
/** Percentage of different pixels in the whole image */
3537
diffPercentage: number;
3638
}
39+
| {
40+
match: false;
41+
reason: "file-not-exists";
42+
/** Errored file path */
43+
file: string;
44+
}
3745
>;
3846

3947
export { compare };

bin/node-bindings/odiff.js

+25-12
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,10 @@ function optionsToArgs(options) {
4848

4949
case "ignoreRegions": {
5050
const regions = value
51-
.map((region) => `${region.x1}:${region.y1}-${region.x2}:${region.y2}`)
52-
.join(',');
51+
.map(
52+
(region) => `${region.x1}:${region.y1}-${region.x2}:${region.y2}`
53+
)
54+
.join(",");
5355

5456
setArgWithValue("ignore", regions);
5557
break;
@@ -92,9 +94,10 @@ async function compare(basePath, comparePath, diffOutput, options = {}) {
9294
return new Promise((resolve, reject) => {
9395
let producedStdout, producedStdError;
9496

95-
const binaryPath = options && options.__binaryPath
96-
? options.__binaryPath
97-
: path.join(__dirname, "bin", "odiff");
97+
const binaryPath =
98+
options && options.__binaryPath
99+
? options.__binaryPath
100+
: path.join(__dirname, "bin", "odiff");
98101

99102
execFile(
100103
binaryPath,
@@ -119,14 +122,24 @@ async function compare(basePath, comparePath, diffOutput, options = {}) {
119122
});
120123
break;
121124
case 124:
122-
reject(
123-
new TypeError(
124-
(producedStdError || "Invalid Argument Exception").replace(
125-
CMD_BIN_HELPER_MSG,
126-
""
127-
)
128-
)
125+
/** @type string */
126+
const originalErrorMessage = (
127+
producedStdError || "Invalid Argument Exception"
128+
).replace(CMD_BIN_HELPER_MSG, "");
129+
130+
const noFileOrDirectoryMatches = originalErrorMessage.match(
131+
/no\n\s*`(.*)'\sfile or\n\s*directory/
129132
);
133+
134+
if (options.noFailOnFsErrors && noFileOrDirectoryMatches[1]) {
135+
resolve({
136+
match: false,
137+
reason: "file-not-exists",
138+
file: noFileOrDirectoryMatches[1],
139+
});
140+
} else {
141+
reject(new TypeError(originalErrorMessage));
142+
}
130143
break;
131144

132145
default:

io/png/ReadPng.c

+12-7
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,15 @@ read_png_file(value file)
2121
const char *filename = String_val(file);
2222

2323
png = fopen(filename, "rb");
24-
if(png == NULL) {
24+
if (png == NULL)
25+
{
2526
caml_failwith("error opening input file");
2627
}
2728

2829
ctx = spng_ctx_new(0);
2930

30-
if(ctx == NULL) {
31+
if (ctx == NULL)
32+
{
3133
caml_failwith("spng_ctx_new() failed");
3234
spng_ctx_free(ctx);
3335
free(out);
@@ -47,27 +49,30 @@ read_png_file(value file)
4749
struct spng_ihdr ihdr;
4850
result = spng_get_ihdr(ctx, &ihdr);
4951

50-
if(result) {
52+
if (result)
53+
{
5154
caml_failwith("spng_get_ihdr() error!");
5255
spng_ctx_free(ctx);
5356
free(out);
5457
}
5558

5659
size_t out_size;
5760
result = spng_decoded_image_size(ctx, SPNG_FMT_RGBA8, &out_size);
58-
if(result) {
61+
if (result)
62+
{
5963
spng_ctx_free(ctx);
6064
};
6165

62-
6366
out = malloc(out_size);
64-
if(out == NULL) {
67+
if (out == NULL)
68+
{
6569
spng_ctx_free(ctx);
6670
free(out);
6771
};
6872

6973
result = spng_decode_image(ctx, out, out_size, SPNG_FMT_RGBA8, 0);
70-
if(result) {
74+
if (result)
75+
{
7176
spng_ctx_free(ctx);
7277
free(out);
7378
caml_failwith(spng_strerror(result));

io/png_write/WritePng.c

+23-15
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ value write_png_bigarray(value filename_val, value bigarray, value width_val, va
1818

1919
FILE *fp;
2020

21-
if (( fp = fopen(filename, "wb")) == NULL ){
21+
if ((fp = fopen(filename, "wb")) == NULL)
22+
{
2223
caml_failwith("Can not save the output :(");
2324
}
2425

@@ -35,51 +36,58 @@ value write_png_bigarray(value filename_val, value bigarray, value width_val, va
3536

3637
spng_ctx *ctx = spng_ctx_new(SPNG_CTX_ENCODER);
3738
struct spng_ihdr ihdr = {
38-
width,
39-
height,
40-
bit_depth,
41-
color_type,
42-
compression_method,
43-
filter_method,
44-
interlace_method,
39+
width,
40+
height,
41+
bit_depth,
42+
color_type,
43+
compression_method,
44+
filter_method,
45+
interlace_method,
4546
};
4647

4748
result = spng_set_ihdr(ctx, &ihdr);
48-
if(result) {
49+
if (result)
50+
{
4951
spng_ctx_free(ctx);
5052
fclose(fp);
5153
caml_failwith(spng_strerror(result));
5254
}
5355

5456
result = spng_set_option(ctx, SPNG_FILTER_CHOICE, SPNG_DISABLE_FILTERING);
55-
if(result) {
57+
if (result)
58+
{
5659
spng_ctx_free(ctx);
5760
fclose(fp);
5861
caml_failwith(spng_strerror(result));
5962
}
6063

6164
result = spng_set_png_file(ctx, fp);
62-
if(result) {
65+
if (result)
66+
{
6367
fclose(fp);
6468
spng_ctx_free(ctx);
6569
caml_failwith(spng_strerror(result));
6670
}
6771

6872
result = spng_encode_image(ctx, 0, 0, SPNG_FMT_PNG, SPNG_ENCODE_PROGRESSIVE);
6973

70-
if(result) {
74+
if (result)
75+
{
7176
fclose(fp);
7277
spng_ctx_free(ctx);
7378
caml_failwith(spng_strerror(result));
7479
}
7580

76-
for(int i = 0; i < ihdr.height; i++) {
81+
for (int i = 0; i < ihdr.height; i++)
82+
{
7783
const char *row = data + out_width * i;
7884
result = spng_encode_scanline(ctx, row, out_width);
79-
if(result) break;
85+
if (result)
86+
break;
8087
}
8188

82-
if(result != SPNG_EOI) {
89+
if (result != SPNG_EOI)
90+
{
8391
spng_ctx_free(ctx);
8492
fclose(fp);
8593
caml_failwith(spng_strerror(result));

io/tiff/ReadTiff.c

+7-8
Original file line numberDiff line numberDiff line change
@@ -23,26 +23,25 @@ read_tiff_file_to_tuple(value file)
2323

2424
TIFF *image;
2525

26-
27-
28-
if (!(image = TIFFOpen(filename, "r"))) {
26+
if (!(image = TIFFOpen(filename, "r")))
27+
{
2928
caml_failwith("opening input file failed!");
3029
}
3130

3231
TIFFGetField(image, TIFFTAG_IMAGEWIDTH, &width);
3332
TIFFGetField(image, TIFFTAG_IMAGELENGTH, &height);
3433

35-
3634
int buffer_size = width * height;
37-
buffer = (uint32_t*)malloc(buffer_size * 4);
35+
buffer = (uint32_t *)malloc(buffer_size * 4);
3836

39-
if (!buffer) {
37+
if (!buffer)
38+
{
4039
TIFFClose(image);
4140
caml_failwith("allocating TIFF buffer failed");
4241
}
4342

44-
45-
if (!(TIFFReadRGBAImageOriented(image, width, height, buffer, ORIENTATION_TOPLEFT, 0))) {
43+
if (!(TIFFReadRGBAImageOriented(image, width, height, buffer, ORIENTATION_TOPLEFT, 0)))
44+
{
4645
TIFFClose(image);
4746
caml_failwith("reading input file failed");
4847
}

src/Antialiasing.re

+13-13
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,11 @@ module MakeAntialiasing = (IO1: ImageIO.ImageIO, IO2: ImageIO.ImageIO) => {
3939
let x1 = min(x + 1, baseImg.width - 1);
4040
let y1 = min(y + 1, baseImg.height - 1);
4141

42-
let minAdjacientDelta = ref(0.0);
43-
let maxAdjacientDelta = ref(0.0);
42+
let minSiblingDelta = ref(0.0);
43+
let maxSiblingDelta = ref(0.0);
4444

45-
let minAdjacientDeltaCoord = ref((0, 0));
46-
let maxAdjacientDeltaCoord = ref((0, 0));
45+
let minSiblingDeltaCoord = ref((0, 0));
46+
let maxSiblingDeltaCoord = ref((0, 0));
4747

4848
let zeroes = ref(x == x0 || x == x1 || y == y0 || y == y1 ? 1 : 0);
4949

@@ -65,12 +65,12 @@ module MakeAntialiasing = (IO1: ImageIO.ImageIO, IO2: ImageIO.ImageIO) => {
6565
adjacentColor,
6666
);
6767

68-
if (delta < minAdjacientDelta^) {
69-
minAdjacientDelta := delta;
70-
minAdjacientDeltaCoord := (adj_x, adj_y);
71-
} else if (delta > maxAdjacientDelta^) {
72-
maxAdjacientDelta := delta;
73-
maxAdjacientDeltaCoord := (adj_x, adj_y);
68+
if (delta < minSiblingDelta^) {
69+
minSiblingDelta := delta;
70+
minSiblingDeltaCoord := (adj_x, adj_y);
71+
} else if (delta > maxSiblingDelta^) {
72+
maxSiblingDelta := delta;
73+
maxSiblingDeltaCoord := (adj_x, adj_y);
7474
};
7575
};
7676
};
@@ -80,13 +80,13 @@ module MakeAntialiasing = (IO1: ImageIO.ImageIO, IO2: ImageIO.ImageIO) => {
8080
// if we found more than 2 equal siblings or
8181
// there are no darker pixels among the siblings or
8282
// there are no brighter pixels among the siblings it's not anti-aliasing
83-
if (zeroes^ >= 3 || minAdjacientDelta^ == 0.0 || maxAdjacientDelta^ == 0.0) {
83+
if (zeroes^ >= 3 || minSiblingDelta^ == 0.0 || maxSiblingDelta^ == 0.0) {
8484
false;
8585
} else {
8686
// if either the darkest or the brightest pixel has 3+ equal siblings in both images
8787
// (definitely not anti-aliased), this pixel is anti-aliased
88-
let (minX, minY) = minAdjacientDeltaCoord^;
89-
let (maxX, maxY) = maxAdjacientDeltaCoord^;
88+
let (minX, minY) = minSiblingDeltaCoord^;
89+
let (maxX, maxY) = maxSiblingDeltaCoord^;
9090
(
9191
hasManySiblingsWithSameColor(
9292
~x=minX,

0 commit comments

Comments
 (0)