@@ -3,6 +3,7 @@ package main
33import (
44 "crypto/sha256"
55 "errors"
6+ "flag"
67 "fmt"
78 "image"
89 "image/color"
@@ -13,15 +14,17 @@ import (
1314 "strconv"
1415)
1516
16- // Structure for Pixel. Used as float to make operations more easily.
17+ // Structure for Pixel.
1718type Pixel struct {
18- r ,g ,b ,a float64
19+ r , g , b , a uint8
20+ modified bool
1921}
2022
21- func rgbaToPixel (r uint32 , g uint32 , b uint32 , a uint32 ) Pixel {
22- return Pixel {float64 (r ), float64 (g ), float64 (b ), float64 (a )}
23- }
23+ var rmaster , gmaster , bmaster float64
2424
25+ func rgbaToPixel (r uint32 , g uint32 , b uint32 , a uint32 ) Pixel {
26+ return Pixel {uint8 (r >> 8 ), uint8 (g >> 8 ), uint8 (b >> 8 ), uint8 (a >> 8 ), false }
27+ }
2528
2629func CreatePNG (PDFPath string ) {
2730
@@ -60,21 +63,30 @@ func RetrievePixel(fileName string) ([][]Pixel, int, int) {
6063
6164 bounds := img .Bounds ()
6265 width , height := bounds .Max .X , bounds .Max .Y
63- var pixels [][]Pixel
66+ pixels := make ( [][]Pixel , bounds . Max . Y )
6467 for y := bounds .Min .Y ; y < height ; y ++ {
65- var row []Pixel
68+ row := make ( []Pixel , bounds . Max . X )
6669 for x := bounds .Min .X ; x < width ; x ++ {
67- row = append ( row , rgbaToPixel (img .At (x , y ).RGBA () ))
70+ row [ x ] = rgbaToPixel (img .At (x , y ).RGBA ())
6871 }
69- pixels = append ( pixels , row )
72+ pixels [ y ] = row
7073 }
7174 return pixels , width , height
7275}
7376
7477func drawSection (row []Pixel ) {
78+ alpha := 0.6
79+ notalpha := float64 (1 - alpha )
80+
7581 for i := 0 ; i < len (row ); i ++ {
76- row [i ].g = row [i ].g * 0.7
77- row [i ].b = row [i ].b * 0.9
82+
83+ if ! row [i ].modified {
84+ row [i ].r = uint8 (float64 (row [i ].r )* alpha + notalpha * rmaster )
85+ row [i ].g = uint8 (float64 (row [i ].g )* alpha + notalpha * gmaster )
86+ row [i ].b = uint8 (float64 (row [i ].b )* alpha + notalpha * bmaster )
87+ row [i ].modified = true
88+ }
89+
7890 }
7991}
8092
@@ -84,7 +96,7 @@ func CompareSingleImage(path1 string, path2 string, i int) {
8496 sha2 := ComputeSha256 (path2 )
8597
8698 // If the two images have the same hash, the two pages are the same.
87- if sha1 == sha2 {
99+ if sha1 == sha2 {
88100 fmt .Printf ("The pages number %d are the same.\n " , i )
89101 return
90102 }
@@ -102,21 +114,23 @@ func CompareSingleImage(path1 string, path2 string, i int) {
102114
103115 for y := 0 ; y < len (pixel_1 ); y ++ {
104116 for x := 0 ; x < len (pixel_1 [y ]); x ++ {
105- result := compareSinglePixel (pixel_1 [y ][x ], pixel_2 [y ][x ])
106- if ! result {
107- drawSection (pixel_3 [y ])
117+ if ! pixel_3 [y ][x ].modified {
118+ result := compareSinglePixel (pixel_1 [y ][x ], pixel_2 [y ][x ])
119+ if ! result {
120+ drawSection (pixel_3 [y ])
121+ }
108122 }
109123 }
110124 }
111125
112- img := image .NewNRGBA (image .Rect (0 , 0 , x_1 , y_1 ))
126+ img := image .NewRGBA (image .Rect (0 , 0 , x_1 , y_1 ))
113127 for y := 0 ; y < y_1 ; y ++ {
114128 for x := 0 ; x < x_1 ; x ++ {
115129 img .Set (x , y , color.RGBA {
116- R : uint8 ( pixel_3 [y ][x ].r ) ,
117- G : uint8 ( pixel_3 [y ][x ].g ) ,
118- B : uint8 ( pixel_3 [y ][x ].b ) ,
119- A : uint8 ( pixel_3 [y ][x ].a ) ,
130+ R : pixel_3 [y ][x ].r ,
131+ G : pixel_3 [y ][x ].g ,
132+ B : pixel_3 [y ][x ].b ,
133+ A : pixel_3 [y ][x ].a ,
120134 })
121135 }
122136 }
@@ -164,14 +178,16 @@ func ComputeSha256(filePath string) string {
164178}
165179
166180func Compare (PDF1 string , PDF2 string ) {
167- // Compares the two files
181+ // Compares the two files
168182
169183 shaPDF1 := ComputeSha256 (PDF1 )
170184 shaPDF2 := ComputeSha256 (PDF2 )
171185
172- err := os .Mkdir ("generated" , os .ModePerm )
173- if err != nil {
174- panic (err )
186+ if _ , err := os .Stat ("generated" ); errors .Is (err , os .ErrNotExist ) {
187+ err := os .Mkdir ("generated" , os .ModePerm )
188+ if err != nil {
189+ panic (err )
190+ }
175191 }
176192
177193 i := 1
@@ -182,37 +198,55 @@ func Compare(PDF1 string, PDF2 string) {
182198 // pdf contains <= 999 pages => 001.. 002.. 003
183199
184200 o := fmt .Sprintf ("%d" , k )
185- s := fmt .Sprintf ("%0" + o + "d" , i )
201+ s := fmt .Sprintf ("%0" + o + "d" , i )
186202
187203 s_pdf1 := shaPDF1 + "/png_gen-" + s + ".png"
188204 s_pdf2 := shaPDF2 + "/png_gen-" + s + ".png"
189205
190206 if _ , err := os .Stat (s_pdf1 ); errors .Is (err , os .ErrNotExist ) {
191- // TODO: remove this println
192- fmt .Println ("File " + s_pdf1 + " does not exist." )
193207 k ++
194- if k == 12 {
208+ if k == 12 {
195209 break
196210 }
197211 } else {
198212 CompareSingleImage (s_pdf1 , s_pdf2 , i )
199213 i ++
200214 }
201-
215+
202216 }
217+ }
218+
219+ func hexToRGB (hexcolor string ) {
220+ // converts a string to rgb values
221+ values , _ := strconv .ParseUint (hexcolor , 16 , 32 )
222+ rmaster = float64 (values >> 16 )
223+ gmaster = float64 ((values >> 8 ) & 0xff )
224+ bmaster = float64 ((values ) & 0xff )
225+
226+ fmt .Printf ("Color chosen: %f %f %f \n " , rmaster , gmaster , bmaster )
203227
204228}
205229
206- func main (){
207- fmt .Println ("pdf-diff: highlights the differences between two pdf files." )
208- if len (os .Args ) < 2 {
209- fmt .Println ("You need to specify two parameters!" )
230+ func main () {
231+
232+ // flags
233+
234+ color := flag .String ("color" , "ff2010" , "hex value for the background color for highlighting" )
235+ flag .Parse ()
236+
237+ arguments := flag .Args ()
238+
239+ if len (arguments ) < 2 {
240+ fmt .Println ("pdf-diff: highlights the differences between two pdf files." )
241+ fmt .Println ("Usage: pdf-diff pdf-file-1 pdf-file-2 [-color] hex-color" )
242+ fmt .Println ()
243+ flag .PrintDefaults ()
210244 os .Exit (1 )
211245 }
212246
213- CreatePNG ( os . Args [ 1 ] )
214- CreatePNG (os . Args [ 2 ])
215-
216- Compare (os . Args [ 1 ], os . Args [ 2 ])
247+ hexToRGB ( * color )
248+ CreatePNG (arguments [ 0 ])
249+ CreatePNG ( arguments [ 1 ])
250+ Compare (arguments [ 0 ], arguments [ 1 ])
217251
218252}
0 commit comments