@@ -3,25 +3,29 @@ package main
33import (
44 "crypto/sha256"
55 "errors"
6+ "flag"
67 "fmt"
78 "image"
89 "image/color"
910 "image/png"
1011 "io"
1112 "os"
1213 "os/exec"
14+ //"runtime/pprof"
1315 "strconv"
1416)
1517
16- // Structure for Pixel. Used as float to make operations more easily.
18+ // Structure for Pixel.
1719type Pixel struct {
18- r ,g ,b ,a float64
20+ r , g , b , a uint8
21+ modified bool
1922}
2023
21- func rgbaToPixel (r uint32 , g uint32 , b uint32 , a uint32 ) Pixel {
22- return Pixel {float64 (r ), float64 (g ), float64 (b ), float64 (a )}
23- }
24+ var rmaster , gmaster , bmaster float64
2425
26+ func rgbaToPixel (r uint32 , g uint32 , b uint32 , a uint32 ) Pixel {
27+ return Pixel {uint8 (r >> 8 ), uint8 (g >> 8 ), uint8 (b >> 8 ), uint8 (a >> 8 ), false }
28+ }
2529
2630func CreatePNG (PDFPath string ) {
2731
@@ -60,21 +64,30 @@ func RetrievePixel(fileName string) ([][]Pixel, int, int) {
6064
6165 bounds := img .Bounds ()
6266 width , height := bounds .Max .X , bounds .Max .Y
63- var pixels [][]Pixel
67+ pixels := make ( [][]Pixel , bounds . Max . Y )
6468 for y := bounds .Min .Y ; y < height ; y ++ {
65- var row []Pixel
69+ row := make ( []Pixel , bounds . Max . X )
6670 for x := bounds .Min .X ; x < width ; x ++ {
67- row = append ( row , rgbaToPixel (img .At (x , y ).RGBA () ))
71+ row [ x ] = rgbaToPixel (img .At (x , y ).RGBA ())
6872 }
69- pixels = append ( pixels , row )
73+ pixels [ y ] = row
7074 }
7175 return pixels , width , height
7276}
7377
7478func drawSection (row []Pixel ) {
79+ alpha := 0.6
80+ notalpha := float64 (1 - alpha )
81+
7582 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
83+
84+ if ! row [i ].modified {
85+ row [i ].r = uint8 (float64 (row [i ].r )* alpha + notalpha * rmaster )
86+ row [i ].g = uint8 (float64 (row [i ].g )* alpha + notalpha * gmaster )
87+ row [i ].b = uint8 (float64 (row [i ].b )* alpha + notalpha * bmaster )
88+ row [i ].modified = true
89+ }
90+
7891 }
7992}
8093
@@ -84,7 +97,7 @@ func CompareSingleImage(path1 string, path2 string, i int) {
8497 sha2 := ComputeSha256 (path2 )
8598
8699 // If the two images have the same hash, the two pages are the same.
87- if sha1 == sha2 {
100+ if sha1 == sha2 {
88101 fmt .Printf ("The pages number %d are the same.\n " , i )
89102 return
90103 }
@@ -102,21 +115,23 @@ func CompareSingleImage(path1 string, path2 string, i int) {
102115
103116 for y := 0 ; y < len (pixel_1 ); y ++ {
104117 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 ])
118+ if ! pixel_3 [y ][x ].modified {
119+ result := compareSinglePixel (pixel_1 [y ][x ], pixel_2 [y ][x ])
120+ if ! result {
121+ drawSection (pixel_3 [y ])
122+ }
108123 }
109124 }
110125 }
111126
112- img := image .NewNRGBA (image .Rect (0 , 0 , x_1 , y_1 ))
127+ img := image .NewRGBA (image .Rect (0 , 0 , x_1 , y_1 ))
113128 for y := 0 ; y < y_1 ; y ++ {
114129 for x := 0 ; x < x_1 ; x ++ {
115130 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 ) ,
131+ R : pixel_3 [y ][x ].r ,
132+ G : pixel_3 [y ][x ].g ,
133+ B : pixel_3 [y ][x ].b ,
134+ A : pixel_3 [y ][x ].a ,
120135 })
121136 }
122137 }
@@ -164,14 +179,16 @@ func ComputeSha256(filePath string) string {
164179}
165180
166181func Compare (PDF1 string , PDF2 string ) {
167- // Compares the two files
182+ // Compares the two files
168183
169184 shaPDF1 := ComputeSha256 (PDF1 )
170185 shaPDF2 := ComputeSha256 (PDF2 )
171186
172- err := os .Mkdir ("generated" , os .ModePerm )
173- if err != nil {
174- panic (err )
187+ if _ , err := os .Stat ("generated" ); errors .Is (err , os .ErrNotExist ) {
188+ err := os .Mkdir ("generated" , os .ModePerm )
189+ if err != nil {
190+ panic (err )
191+ }
175192 }
176193
177194 i := 1
@@ -182,37 +199,55 @@ func Compare(PDF1 string, PDF2 string) {
182199 // pdf contains <= 999 pages => 001.. 002.. 003
183200
184201 o := fmt .Sprintf ("%d" , k )
185- s := fmt .Sprintf ("%0" + o + "d" , i )
202+ s := fmt .Sprintf ("%0" + o + "d" , i )
186203
187204 s_pdf1 := shaPDF1 + "/png_gen-" + s + ".png"
188205 s_pdf2 := shaPDF2 + "/png_gen-" + s + ".png"
189206
190207 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." )
193208 k ++
194- if k == 12 {
209+ if k == 12 {
195210 break
196211 }
197212 } else {
198213 CompareSingleImage (s_pdf1 , s_pdf2 , i )
199214 i ++
200215 }
201-
216+
202217 }
218+ }
219+
220+ func hexToRGB (hexcolor string ) {
221+ // converts a string to rgb values
222+ values , _ := strconv .ParseUint (hexcolor , 16 , 32 )
223+ rmaster = float64 (values >> 16 )
224+ gmaster = float64 ((values >> 8 ) & 0xff )
225+ bmaster = float64 ((values ) & 0xff )
226+
227+ fmt .Printf ("Color chosen: %f %f %f \n " , rmaster , gmaster , bmaster )
203228
204229}
205230
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!" )
231+ func main () {
232+
233+ // flags
234+
235+ color := flag .String ("color" , "ff2010" , "hex value for the background color for highlighting" )
236+ flag .Parse ()
237+
238+ arguments := flag .Args ()
239+
240+ if len (arguments ) < 2 {
241+ fmt .Println ("pdf-diff: highlights the differences between two pdf files." )
242+ fmt .Println ("Usage: pdf-diff pdf-file-1 pdf-file-2 [-color] hex-color" )
243+ fmt .Println ()
244+ flag .PrintDefaults ()
210245 os .Exit (1 )
211246 }
212247
213- CreatePNG ( os . Args [ 1 ] )
214- CreatePNG (os . Args [ 2 ])
215-
216- Compare (os . Args [ 1 ], os . Args [ 2 ])
248+ hexToRGB ( * color )
249+ CreatePNG (arguments [ 0 ])
250+ CreatePNG ( arguments [ 1 ])
251+ Compare (arguments [ 0 ], arguments [ 1 ])
217252
218253}
0 commit comments