Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Rewrite in OCaml #91

Merged
merged 1 commit into from
Mar 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file removed .DS_Store
Binary file not shown.
2 changes: 1 addition & 1 deletion .ci/utils/use-esy.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# steps to install esy globally

steps:
- script: "npm install -g esy@beta"
- script: "npm install -g esy"
displayName: "install esy"
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
- uses: actions/[email protected]

- name: Install esy
run: npm install -g esy@beta
run: npm install -g esy

- name: Try to restore install cache
uses: actions/[email protected]
Expand Down
File renamed without changes.
23 changes: 23 additions & 0 deletions bin/Color.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
let ofHexString s =
match String.length s with
| (4 | 7) as len -> (
let short = len = 4 in
let r' =
match short with true -> String.sub s 1 1 | false -> String.sub s 1 2
in
let g' =
match short with true -> String.sub s 2 1 | false -> String.sub s 3 2
in
let b' =
match short with true -> String.sub s 3 1 | false -> String.sub s 5 2
in
let r = int_of_string_opt ("0x" ^ r') in
let g = int_of_string_opt ("0x" ^ g') in
let b = int_of_string_opt ("0x" ^ b') in

match (r, g, b) with
| Some r, Some g, Some b when short ->
Some ((16 * r) + r, (16 * g) + g, (16 * b) + b)
| Some r, Some g, Some b -> Some (r, g, b)
| _ -> None)
| _ -> None
19 changes: 0 additions & 19 deletions bin/Color.re

This file was deleted.

44 changes: 44 additions & 0 deletions bin/Main.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
open Odiff.ImageIO
open Odiff.Diff

let getIOModule filename =
match Filename.extension filename with
| ".png" -> (module ODiffIO.Png.IO : ImageIO)
| ".jpg" | ".jpeg" -> (module ODiffIO.Jpg.IO : ImageIO)
| ".bmp" -> (module ODiffIO.Bmp.IO : ImageIO)
| ".tiff" -> (module ODiffIO.Tiff.IO : ImageIO)
| f -> failwith ("This format is not supported: " ^ f)

type 'output diffResult = { exitCode : int; diff : 'output option }

let main img1Path img2Path diffPath threshold outputDiffMask failOnLayoutChange
diffColorHex stdoutParsableString antialiasing ignoreRegions diffLines =
let module IO1 = (val getIOModule img1Path) in
let module IO2 = (val getIOModule img2Path) in
let module Diff = MakeDiff (IO1) (IO2) in
let img1 = IO1.loadImage img1Path in
let img2 = IO2.loadImage img2Path in
let { diff; exitCode } =
Diff.diff img1 img2 ~outputDiffMask ~threshold ~failOnLayoutChange
~antialiasing ~ignoreRegions ~diffLines
~diffPixel:
(Color.ofHexString diffColorHex |> function
| Some col -> col
| None -> (255, 0, 0))
()
|> Print.printDiffResult stdoutParsableString
|> function
| Layout -> { diff = None; exitCode = 21 }
| Pixel (diffOutput, diffCount, stdoutParsableString, _) when diffCount = 0
->
{ exitCode = 0; diff = Some diffOutput }
| Pixel (diffOutput, diffCount, diffPercentage, _) ->
IO1.saveImage diffOutput diffPath;
{ exitCode = 22; diff = Some diffOutput }
in
IO1.freeImage img1;
IO2.freeImage img2;
(match diff with
| Some output when outputDiffMask -> IO1.freeImage output
| _ -> ());
exit exitCode
86 changes: 0 additions & 86 deletions bin/Main.re

This file was deleted.

88 changes: 88 additions & 0 deletions bin/ODiffBin.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
open Cmdliner
open Term
open Arg

let diffPath =
value & pos 2 string ""
& info [] ~docv:"DIFF" ~doc:"Diff output path (.png only)"

let base =
value & pos 0 file "" & info [] ~docv:"BASE" ~doc:"Path to base image"

let comp =
value & pos 1 file ""
& info [] ~docv:"COMPARING" ~doc:"Path to comparing image"

let threshold =
value & opt float 0.1
& info [ "t"; "threshold" ] ~docv:"THRESHOLD"
~doc:"Color difference threshold (from 0 to 1). Less more precise."

let diffMask =
value & flag
& info [ "dm"; "diff-mask" ] ~docv:"DIFF_IMAGE"
~doc:"Output only changed pixel over transparent background."

let failOnLayout =
value & flag
& info [ "fail-on-layout" ] ~docv:"FAIL_ON_LAYOUT"
~doc:
"Do not compare images and produce output if images layout is \
different."

let parsableOutput =
value & flag
& info [ "parsable-stdout" ] ~docv:"PARSABLE_OUTPUT"
~doc:"Stdout parsable output"

let diffColor =
value & opt string ""
& info [ "diff-color" ]
~doc:
"Color used to highlight different pixels in the output (in hex format \
e.g. #cd2cc9)."

let antialiasing =
value & flag
& info [ "aa"; "antialiasing" ]
~doc:
"With this flag enabled, antialiased pixels are not counted to the \
diff of an image"

let diffLines =
value & flag
& info [ "output-diff-lines" ]
~doc:
"With this flag enabled, output result in case of different images \
will output lines for all the different pixels"

let ignoreRegions =
value
& opt
(list ~sep:',' (t2 ~sep:'-' (t2 ~sep:':' int int) (t2 ~sep:':' int int)))
[]
& info [ "i"; "ignore" ]
~doc:
"An array of regions to ignore in the diff. One region looks like \
\"x1:y1-x2:y2\". Multiple regions are separated with a ','."

let cmd =
let man =
[
`S Manpage.s_description;
`P "$(tname) is the fastest pixel-by-pixel image comparison tool.";
`P "Supported image types: .png, .jpg, .jpeg, .bitmap";
]
in
( const Main.main $ base $ comp $ diffPath $ threshold $ diffMask
$ failOnLayout $ diffColor $ parsableOutput $ antialiasing $ ignoreRegions
$ diffLines,
Term.info "odiff" ~version:"3.0.0" ~doc:"Find difference between 2 images."
~exits:
(Term.exit_info 0 ~doc:"on image match"
:: Term.exit_info 21 ~doc:"on layout diff when --fail-on-layout"
:: Term.exit_info 22 ~doc:"on image pixel difference"
:: Term.default_error_exits)
~man )

let () = Term.eval cmd |> Term.exit
Loading
Loading