48
48
import com .itextpdf .text .Meta ;
49
49
import com .itextpdf .text .Rectangle ;
50
50
import com .itextpdf .text .io .RandomAccessSourceFactory ;
51
- import com .itextpdf .text .pdf .*;
51
+ import com .itextpdf .text .pdf .PRIndirectReference ;
52
+ import com .itextpdf .text .pdf .PRStream ;
53
+ import com .itextpdf .text .pdf .PRTokeniser ;
54
+ import com .itextpdf .text .pdf .PdfAnnotation ;
55
+ import com .itextpdf .text .pdf .PdfArray ;
56
+ import com .itextpdf .text .pdf .PdfBoolean ;
57
+ import com .itextpdf .text .pdf .PdfContentByte ;
58
+ import com .itextpdf .text .pdf .PdfContentParser ;
59
+ import com .itextpdf .text .pdf .PdfDictionary ;
60
+ import com .itextpdf .text .pdf .PdfIndirectReference ;
61
+ import com .itextpdf .text .pdf .PdfLiteral ;
62
+ import com .itextpdf .text .pdf .PdfName ;
63
+ import com .itextpdf .text .pdf .PdfNumber ;
64
+ import com .itextpdf .text .pdf .PdfObject ;
65
+ import com .itextpdf .text .pdf .PdfReader ;
66
+ import com .itextpdf .text .pdf .PdfStamper ;
67
+ import com .itextpdf .text .pdf .PdfString ;
68
+ import com .itextpdf .text .pdf .RandomAccessFileOrArray ;
69
+ import com .itextpdf .text .pdf .RefKey ;
52
70
import com .itextpdf .text .pdf .parser .ContentByteUtils ;
53
71
import com .itextpdf .text .pdf .parser .ImageRenderInfo ;
54
72
import com .itextpdf .text .pdf .parser .InlineImageInfo ;
89
107
import java .util .Map ;
90
108
import java .util .Set ;
91
109
import java .util .Stack ;
92
- import java .util .StringTokenizer ;
93
110
import java .util .TreeSet ;
94
-
111
+ import java . util . regex . Pattern ;
95
112
import javax .xml .XMLConstants ;
96
113
import javax .xml .parsers .DocumentBuilder ;
97
114
import javax .xml .parsers .DocumentBuilderFactory ;
102
119
import javax .xml .transform .TransformerFactory ;
103
120
import javax .xml .transform .dom .DOMSource ;
104
121
import javax .xml .transform .stream .StreamResult ;
105
-
106
122
import org .w3c .dom .Document ;
107
123
import org .w3c .dom .Element ;
108
124
import org .w3c .dom .Node ;
@@ -392,9 +408,17 @@ public void writeReportToXml(OutputStream stream) throws ParserConfigurationExce
392
408
393
409
private String gsExec ;
394
410
private String compareExec ;
395
- private final String gsParams = " -dNOPAUSE -dBATCH -sDEVICE=png16m -r150 -sOutputFile=<outputfile> <inputfile>" ;
411
+ private static final String renderedImageExtension = "png" ;
412
+ private static final String pageNumberPattern = "%03d" ;
413
+ private static final Pattern pageListRegexp = Pattern .compile ("^(\\ d+,)*\\ d+$" );
414
+ private static final String tempFilePrefix = "itext_gs_io_temp" ;
415
+
416
+
417
+ private final String gsParams = " -dNOPAUSE -dBATCH -dSAFER -sDEVICE=" +
418
+ renderedImageExtension + "16m -r150 -sOutputFile=<outputfile> <inputfile>" ;
396
419
private final String compareParams = " \" <image1>\" \" <image2>\" \" <difference>\" " ;
397
420
421
+
398
422
static private final String cannotOpenTargetDirectory = "Cannot open target directory for <filename>." ;
399
423
static private final String gsFailed = "GhostScript failed for <filename>." ;
400
424
static private final String unexpectedNumberOfPages = "Unexpected number of pages for <filename>." ;
@@ -462,7 +486,6 @@ private String compare(String outPath, String differenceImagePrefix, Map<Integer
462
486
file .delete ();
463
487
}
464
488
}
465
-
466
489
File diffFile = new File (outPath + differenceImagePrefix );
467
490
if (diffFile .exists ()) {
468
491
diffFile .delete ();
@@ -499,38 +522,23 @@ private String compare(String outPath, String differenceImagePrefix, Map<Integer
499
522
init (outPath + ignoredAreasPrefix + outPdfName , outPath + ignoredAreasPrefix + cmpPdfName );
500
523
}
501
524
525
+ String cmpPdfTempCopy = null ;
526
+ String replacementImagesDirectory = null ;
527
+ String outPdfTempCopy = null ;
502
528
if (targetDir .exists ()) {
503
- String gsParams = this .gsParams .replace ("<outputfile>" , outPath + cmpImage ).replace ("<inputfile>" , cmpPdf );
504
- Process p = runProcess (gsExec , gsParams );
505
- BufferedReader bri = new BufferedReader (new InputStreamReader (p .getInputStream ()));
506
- BufferedReader bre = new BufferedReader (new InputStreamReader (p .getErrorStream ()));
529
+ replacementImagesDirectory = CompareToolUtil .createTempDirectory (tempFilePrefix );
530
+ cmpPdfTempCopy = CompareToolUtil .createTempCopy (cmpPdf , tempFilePrefix , null );
531
+ outPdfTempCopy = CompareToolUtil .createTempCopy (outPdf , tempFilePrefix , null );
532
+ int exitValue = runGhostscriptAndGetExitCode (cmpPdfTempCopy , CompareToolUtil .buildPath (replacementImagesDirectory ,
533
+ new String []{"cmp_" + tempFilePrefix + pageNumberPattern + "." + renderedImageExtension }));
507
534
String line ;
508
- while ((line = bri .readLine ()) != null ) {
509
- System .out .println (line );
510
- }
511
- bri .close ();
512
- while ((line = bre .readLine ()) != null ) {
513
- System .out .println (line );
514
- }
515
- bre .close ();
516
- if (p .waitFor () == 0 ) {
517
- gsParams = this .gsParams .replace ("<outputfile>" , outPath + outImage ).replace ("<inputfile>" , outPdf );
518
- p = runProcess (gsExec , gsParams );
519
- bri = new BufferedReader (new InputStreamReader (p .getInputStream ()));
520
- bre = new BufferedReader (new InputStreamReader (p .getErrorStream ()));
521
- while ((line = bri .readLine ()) != null ) {
522
- System .out .println (line );
523
- }
524
- bri .close ();
525
- while ((line = bre .readLine ()) != null ) {
526
- System .out .println (line );
527
- }
528
- bre .close ();
529
- int exitValue = p .waitFor ();
530
-
535
+ if (exitValue == 0 ) {
536
+ exitValue = runGhostscriptAndGetExitCode (outPdfTempCopy , CompareToolUtil .buildPath (replacementImagesDirectory ,
537
+ new String []{tempFilePrefix + pageNumberPattern + "." + renderedImageExtension }));
531
538
if (exitValue == 0 ) {
532
- imageFiles = targetDir .listFiles (new PngFileFilter ());
533
- cmpImageFiles = targetDir .listFiles (new CmpPngFileFilter ());
539
+ File tempTargetDir = new File (replacementImagesDirectory );
540
+ imageFiles = tempTargetDir .listFiles (new PngFileFilter ());
541
+ cmpImageFiles = tempTargetDir .listFiles (new CmpPngFileFilter ());
534
542
boolean bUnexpectedNumberOfPages = false ;
535
543
if (imageFiles .length != cmpImageFiles .length ) {
536
544
bUnexpectedNumberOfPages = true ;
@@ -543,6 +551,10 @@ private String compare(String outPath, String differenceImagePrefix, Map<Integer
543
551
Arrays .sort (cmpImageFiles , new ImageNameComparator ());
544
552
String differentPagesFail = null ;
545
553
for (int i = 0 ; i < cnt ; i ++) {
554
+ CompareToolUtil .copy (imageFiles [i ].getAbsolutePath (), CompareToolUtil .buildPath (targetDir .getAbsolutePath (),
555
+ new String []{outPdfName + "-" + (i + 1 ) + "." + renderedImageExtension }));
556
+ CompareToolUtil .copy (cmpImageFiles [i ].getAbsolutePath (), CompareToolUtil .buildPath (targetDir .getAbsolutePath (),
557
+ new String []{"cmp_" + outPdfName + "-" + (i + 1 ) + "." + renderedImageExtension }));
546
558
if (equalPages != null && equalPages .contains (i ))
547
559
continue ;
548
560
System .out .print ("Comparing page " + Integer .toString (i + 1 ) + " (" + imageFiles [i ].getAbsolutePath () + ")..." );
@@ -552,15 +564,20 @@ private String compare(String outPath, String differenceImagePrefix, Map<Integer
552
564
is1 .close ();
553
565
is2 .close ();
554
566
if (!cmpResult ) {
555
- if (compareExec != null && new File (compareExec ).exists ()) {
556
- String compareParams = this .compareParams .replace ("<image1>" , imageFiles [i ].getAbsolutePath ()).replace ("<image2>" , cmpImageFiles [i ].getAbsolutePath ()).replace ("<difference>" , outPath + differenceImagePrefix + Integer .toString (i + 1 ) + ".png" );
557
- p = runProcess (compareExec , compareParams );
558
- bre = new BufferedReader (new InputStreamReader (p .getErrorStream ()));
567
+ if (compareExec != null ) {
568
+ String compareParams = this .compareParams .replace ("<image1>" , imageFiles [i ].getAbsolutePath ()).replace ("<image2>" ,
569
+ cmpImageFiles [i ].getAbsolutePath ()).replace ("<difference>" ,
570
+ CompareToolUtil .buildPath (replacementImagesDirectory , new String []{ "diff" +
571
+ (i + 1 ) + "." + renderedImageExtension }));
572
+
573
+ Process p = CompareToolUtil .runProcess (compareExec , compareParams );
574
+ BufferedReader bre = new BufferedReader (new InputStreamReader (p .getErrorStream ()));
559
575
while ((line = bre .readLine ()) != null ) {
560
576
System .out .println (line );
561
577
}
562
578
bre .close ();
563
579
int cmpExitValue = p .waitFor ();
580
+
564
581
if (cmpExitValue == 0 ) {
565
582
if (differentPagesFail == null ) {
566
583
differentPagesFail = differentPages .replace ("<filename>" , outPdf ).replace ("<pagenumber>" , Integer .toString (i + 1 ));
@@ -581,8 +598,17 @@ private String compare(String outPath, String differenceImagePrefix, Map<Integer
581
598
} else {
582
599
System .out .println ("done." );
583
600
}
601
+ CompareToolUtil .removeFiles (new String [] {imageFiles [i ].getAbsolutePath (), cmpImageFiles [i ].getAbsolutePath ()});
602
+ }
603
+ File [] diffFiles = tempTargetDir .listFiles ();
604
+ for (int i = 0 ; i < diffFiles .length ; i ++) {
605
+ System .out .println (targetDir .getAbsolutePath ());
606
+ CompareToolUtil .copy (diffFiles [i ].getAbsolutePath (), CompareToolUtil .buildPath (targetDir .getAbsolutePath (),
607
+ new String []{differenceImagePrefix + "-" + (i + 1 ) + "." + renderedImageExtension }));
608
+ diffFiles [i ].delete ();
584
609
}
585
- if (differentPagesFail != null ) {
610
+ tempTargetDir .delete ();
611
+ if (differentPagesFail != null ) {
586
612
return differentPagesFail ;
587
613
} else {
588
614
if (bUnexpectedNumberOfPages )
@@ -597,20 +623,27 @@ private String compare(String outPath, String differenceImagePrefix, Map<Integer
597
623
} else {
598
624
return cannotOpenTargetDirectory .replace ("<filename>" , outPdf );
599
625
}
600
-
601
626
return null ;
602
627
}
603
628
604
- private Process runProcess (String execPath , String params ) throws IOException , InterruptedException {
605
- StringTokenizer st = new StringTokenizer (params );
606
- String [] cmdArray = new String [st .countTokens () + 1 ];
607
- cmdArray [0 ] = execPath ;
608
- for (int i = 1 ; st .hasMoreTokens (); ++i )
609
- cmdArray [i ] = st .nextToken ();
610
-
611
- Process p = Runtime .getRuntime ().exec (cmdArray );
612
-
613
- return p ;
629
+ private int runGhostscriptAndGetExitCode (String replacementPdf , String replacementImagesDirectory )
630
+ throws IOException , InterruptedException {
631
+ String gsParams = this .gsParams .replace ("<outputfile>" , replacementImagesDirectory ).
632
+ replace ("<inputfile>" , replacementPdf );
633
+ Process p = CompareToolUtil .runProcess (gsExec , gsParams );
634
+ BufferedReader bri = new BufferedReader (new InputStreamReader (p .getInputStream ()));
635
+ BufferedReader bre = new BufferedReader (new InputStreamReader (p .getErrorStream ()));
636
+ String line ;
637
+ while ((line = bri .readLine ()) != null ) {
638
+ System .out .println (line );
639
+ }
640
+ bri .close ();
641
+ while ((line = bre .readLine ()) != null ) {
642
+ System .out .println (line );
643
+ }
644
+ bre .close ();
645
+ int exitValue = p .waitFor ();
646
+ return exitValue ;
614
647
}
615
648
616
649
public String compare (String outPdf , String cmpPdf , String outPath , String differenceImagePrefix , Map <Integer , List <Rectangle >> ignoredAreas ) throws IOException , InterruptedException , DocumentException {
@@ -1367,9 +1400,12 @@ private void init(String outPdf, String cmpPdf) {
1367
1400
this .cmpPdf = cmpPdf ;
1368
1401
outPdfName = new File (outPdf ).getName ();
1369
1402
cmpPdfName = new File (cmpPdf ).getName ();
1370
- outImage = outPdfName + "-%03d.png" ;
1371
- if (cmpPdfName .startsWith ("cmp_" )) cmpImage = cmpPdfName + "-%03d.png" ;
1372
- else cmpImage = "cmp_" + cmpPdfName + "-%03d.png" ;
1403
+ outImage = outPdfName + pageNumberPattern + "." + renderedImageExtension ;
1404
+ if (cmpPdfName .startsWith ("cmp_" )) {
1405
+ cmpImage = cmpPdfName + pageNumberPattern + "." + renderedImageExtension ;
1406
+ } else {
1407
+ cmpImage = "cmp_" + cmpPdfName + pageNumberPattern + "." + renderedImageExtension ;
1408
+ }
1373
1409
}
1374
1410
1375
1411
private boolean compareStreams (InputStream is1 , InputStream is2 ) throws IOException {
@@ -1396,7 +1432,7 @@ public boolean accept(File pathname) {
1396
1432
String ap = pathname .getAbsolutePath ();
1397
1433
boolean b1 = ap .endsWith (".png" );
1398
1434
boolean b2 = ap .contains ("cmp_" );
1399
- return b1 && !b2 && ap . contains ( outPdfName ) ;
1435
+ return b1 && !b2 ;
1400
1436
}
1401
1437
}
1402
1438
@@ -1405,7 +1441,7 @@ public boolean accept(File pathname) {
1405
1441
String ap = pathname .getAbsolutePath ();
1406
1442
boolean b1 = ap .endsWith (".png" );
1407
1443
boolean b2 = ap .contains ("cmp_" );
1408
- return b1 && b2 && ap . contains ( cmpPdfName ) ;
1444
+ return b1 && b2 ;
1409
1445
}
1410
1446
}
1411
1447
@@ -1500,6 +1536,4 @@ public InputSource resolveEntity(String publicId, String systemId) throws SAXExc
1500
1536
return new InputSource (new StringReader ("" ));
1501
1537
}
1502
1538
}
1503
-
1504
-
1505
1539
}
0 commit comments