1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 package convwatch;
29 
30 
31 import helper.ProcessHandler;
32 import java.io.File;
33 import convwatch.PixelCounter;
34 import convwatch.StatusHelper;
35 import helper.OSHelper;
36 import helper.StringHelper;
37 import java.util.ArrayList;
38 import util.utils;
39 
40 // -----------------------------------------------------------------------------
41 // --------------------------------- PRNCompare ---------------------------------
42 
43 // class DifferenceType
44 // {
45 //     final static int NO_DIFFERENCE = 1;
46 //     final static int DIFFERENCE = 2;
47 //
48 //     public int nValue = NO_DIFFERENCE;
49 //     public boolean equals(int _n)
50 //         {
51 //             if ( _n == nValue ) return true;
52 //             return false;
53 //         }
54 // }
55 
56 // -----------------------------------------------------------------------------
57 public class PRNCompare
58 {
59     // OSHelper m_aHelper;
60     String fs;
61 
62     public PRNCompare()
63         {
64             // m_aHelper = new OSHelper();
65             fs = System.getProperty("file.separator");
66         }
67 
68     String executeSynchronously(String _sCommand)
69         {
70             // System.out.println(_sCommand);
71 
72             ProcessHandler aHandler = new ProcessHandler(_sCommand);
73             boolean bBackValue = aHandler.executeSynchronously();
74 
75             String sText = aHandler.getOutputText();
76 
77             GlobalLogWriter.get().println("Exitcode: " + String.valueOf(aHandler.getExitCode()));
78             return sText;
79         }
80 
81 
82     int getMaxNumOfFileEntry(String _sDirectory, String _sBasename)
83         {
84 //  TODO: check if directory exist should be done earlier
85             File aDirectory = new File(_sDirectory);
86             File[] aDirList = aDirectory.listFiles(
87                 /*
88                   new FileFilter() {
89                   boolean accept(File filename)
90                   {
91                   if (filename.getName().endsWith("jpg"))
92                   return true;
93                   return false;
94                   }
95                   } */
96                 );
97 
98             int nMaxNumber = 0;
99             for(int n = 0; n<aDirList.length ; n++)
100             {
101                 String sDirEntry = aDirList[n].getName();
102                 if (sDirEntry.endsWith(".jpg"))
103                 {
104                     int nNum = nMaxNumber;
105 
106                     if (sDirEntry.startsWith(_sBasename))
107                     {
108                         // System.out.println(sDirEntry);
109                         int nJpgIdx = sDirEntry.lastIndexOf(".jpg");
110                         String sValue = sDirEntry.substring(_sBasename.length(), nJpgIdx);
111                         int nValue = 0;
112                         try
113                         {
114                             nValue = Integer.valueOf(sValue).intValue();
115                         }
116                         catch(java.lang.NumberFormatException e)
117                         {
118                         }
119 
120                         // System.out.println(nValue);
121                         nNum = nValue;
122                     }
123 
124                     if (nNum > nMaxNumber)
125                     {
126                         nMaxNumber = nNum;
127                     }
128                 }
129             }
130             return nMaxNumber;
131         }
132 
133     String m_sInputPath;
134     String m_sReferencePath;
135     String m_sOutputPath;
136     String m_sDocFile;
137     String m_sReferenceFile;
138     String m_sPostScriptFile;
139     // String m_sOldDiff;
140     int m_nMaxPages = 0;
141     int m_nResolutionInDPI = 0;
142     TriState m_tUseBorderMove;
143     String m_sDocumentType;
144 
145     public void setInputPath(String _sInputPath) { m_sInputPath = _sInputPath; }
146 
147     public void setReferencePath(String _sReferencePath) { m_sReferencePath = _sReferencePath; }
148 
149     public void setOutputPath(String _sOutPath) { m_sOutputPath = _sOutPath; }
150 
151     public void setDocFile(String _sDocFile) { m_sDocFile = _sDocFile;}
152 
153     public void setReferenceFile(String _sPRNFile){ m_sReferenceFile = _sPRNFile;}
154 
155     public void setPostScriptFile(String _sPSFile){ m_sPostScriptFile = _sPSFile;}
156 
157     public void setBorderMove(TriState _b) {m_tUseBorderMove = _b;}
158     public TriState getBorderMove() {return m_tUseBorderMove;}
159     // public void setOldDiffPath(String _sOldDiff)
160     //     {
161     //         m_sOldDiff = _sOldDiff;
162     //     }
163     public void setMaxPages(int _n) {m_nMaxPages = _n;}
164     int getMaxPages() {return m_nMaxPages;}
165 
166     public void setResolutionInDPI(int _n) {m_nResolutionInDPI = _n;}
167     int getResolutionInDPI() {return m_nResolutionInDPI;}
168 
169     public void setDocumentType(String _sTypeName)
170         {
171             m_sDocumentType = _sTypeName;
172         }
173 
174     // -----------------------------------------------------------------------------
175 
176     public StatusHelper[] compare()
177         {
178             createJPEGFromPostscript(m_sOutputPath, m_sReferencePath, m_sReferenceFile, getResolutionInDPI());
179 //  TODO: Assume, that Postscript is already in the OutputPath, this may change.
180             createJPEGFromPostscript(m_sOutputPath, m_sOutputPath, m_sPostScriptFile, getResolutionInDPI());
181             StatusHelper[] aList = createDiffs(m_sOutputPath,
182                                                m_sOutputPath, m_sReferenceFile,
183                                                m_sOutputPath, m_sPostScriptFile,
184                                                getMaxPages(), m_tUseBorderMove);
185 
186 //  TODO: Rename?
187 
188             return aList;
189         }
190 
191     public StatusHelper[] compare_new()
192         {
193             String[] aRefList = createJPEGFromPostscript(m_sOutputPath, m_sReferencePath, m_sReferenceFile, getResolutionInDPI());
194 //  TODO: Assume, that Postscript is already in the OutputPath, this may change.
195             String[] aPSList = createJPEGFromPostscript(m_sOutputPath, m_sOutputPath, m_sPostScriptFile, getResolutionInDPI());
196             StatusHelper[] aList = createDiffs(m_sOutputPath,
197                                                aRefList,
198                                                aPSList,
199                                                getMaxPages(), m_tUseBorderMove);
200 
201             return aList;
202         }
203 
204     static String getJPEGName(String _sOutputPath, String _sBasename, String _sGS_PageOutput)
205         {
206             String fs = System.getProperty("file.separator");
207 
208             String sJPEGName = _sOutputPath + fs + _sBasename + _sGS_PageOutput + ".jpg";
209             return sJPEGName;
210         }
211 
212     /**
213      * Create via ghostscript (gs) from the reference file for every page a JPEG file
214      *
215      * MUST set:
216      * m_sOutputPath, m_sReferenceFile, m_sReferencePath
217      *
218      * return exit code from gs command
219      */
220     public static String[] createJPEGFromPostscript(String _sOutputPath, String _sSourcePath, String _sSourceFile, int _nResolutionInDPI)
221         {
222             String sGS_PageOutput = "%04d";
223             // if ( OSHelper.isWindows() )
224             // {
225             //     sGS_PageOutput = "%%d";
226             // }
227 
228             FileHelper.makeDirectories("", _sOutputPath);
229 
230             // create a jpeg from original prn
231             String fs = System.getProperty("file.separator");
232 
233             String sJPGFilename = getJPEGName(_sOutputPath, _sSourceFile, sGS_PageOutput);
234             String sOriginalFile = _sSourcePath + fs + _sSourceFile;
235             String sCommand;
236             String sGS = "gs";
237             if (OSHelper.isWindows())
238             {
239                 sGS = "gswin32c.exe";
240             }
241 
242             sCommand = sGS + " -dNOPROMPT -dBATCH -sDEVICE=jpeg -r" + String.valueOf(_nResolutionInDPI) + " -dNOPAUSE -sOutputFile=" + StringHelper.doubleQuoteIfNeed(sJPGFilename) + " " + StringHelper.doubleQuoteIfNeed(sOriginalFile);
243             String[] sCommandArray =
244                 {
245                     sGS,
246                     "-dNOPROMPT",
247                     "-dBATCH",
248                     "-sDEVICE=jpeg",
249                     "-r" + String.valueOf(_nResolutionInDPI),
250                     "-dNOPAUSE",
251                     "-sOutputFile=" + sJPGFilename,
252                     sOriginalFile
253                 };
254             // System.out.println("Start Command array");
255             // try
256             // {
257             //     Runtime.getRuntime().exec(sCommandArray);
258             // } catch (Exception e) {
259             //     System.out.println("FAILED");
260             // }
261             // System.out.println("done");
262 
263             ProcessHandler aHandler = new ProcessHandler(sCommandArray);
264             boolean bBackValue = aHandler.executeSynchronously();
265 
266             // TODO: return a real filename, due to the fact we don't know how much files are created, maybe better to return a list
267 
268             ArrayList m_aFileList = new ArrayList();
269             for (int i=1;i<9999;i++)
270             {
271                 String sNewJPEGFilename = utils.replaceAll13(sJPGFilename, sGS_PageOutput, StringHelper.createValueString(i, 4));
272                 if (FileHelper.exists(sNewJPEGFilename))
273                 {
274                     m_aFileList.add(sNewJPEGFilename); // as long as the files exist, fill the array
275                 }
276                 else
277                 {
278                     break;                             // stop file check
279                 }
280             }
281             String[] aList = new String[m_aFileList.size()];
282             aList = (String[])m_aFileList.toArray(aList);
283             return aList; // sNewJPEGFilename;
284         }
285 
286     /**
287      * Create Difference Files from the JPEGs
288      * parameter, how much difference files should create
289      *
290      * m_sPostScriptFile
291      * m_sReferenceFile
292      * m_sOutputPath
293      */
294     public StatusHelper[] createDiffs(String _sOutputPath, String _sSourcePath1, String _sSourceFile1, String _sSourcePath2, String _sSourceFile2, int _nMaxDiffs, TriState _tUseBorderMove)
295         {
296             if (_nMaxDiffs < 1)
297             {
298                 _nMaxDiffs = 1;
299             }
300 
301             String sS1Basename = FileHelper.getBasename(_sSourceFile1);
302             String sS2Basename = FileHelper.getBasename(_sSourceFile2);
303 
304             // count, from which file (jpegs) exist more, take the less one
305             // more are not compareable
306             int nS1_Files = getMaxNumOfFileEntry(_sSourcePath1, sS1Basename);
307             int nS2_Files = getMaxNumOfFileEntry(_sSourcePath2, sS2Basename);
308 
309             // System.out.println("count of s1 files " + String.valueOf(nS1_Files));
310             // System.out.println("count of s2 files " + String.valueOf(nS2_Files));
311 
312             // take the min of both
313             int nMin = Math.min(nS1_Files, nS2_Files);
314             nMin = Math.min(nMin, _nMaxDiffs);
315 
316             StatusHelper[] aList = new StatusHelper[nMin];
317 
318 //  TODO: if both document do not have same page count, produce an error
319             // System.out.println("min of both: " + String.valueOf(nMin));
320 
321             int nStatusIndex = 0;
322             for (int i=1;i<=nMin;i++)
323             {
324                 String sOldGfx =  getJPEGName(_sSourcePath1, sS1Basename, StringHelper.createValueString(i, 4));
325                 String sNewGfx =  getJPEGName(_sSourcePath2, sS2Basename, StringHelper.createValueString(i, 4));
326                 String sDiffGfx_ = getJPEGName(_sOutputPath, sS1Basename + ".diff", StringHelper.createValueString(i, 4));
327 
328 
329                 String sDiffGfx = compareJPEGs(sOldGfx, sNewGfx, sDiffGfx_);
330                 StatusHelper aStatus = new StatusHelper(sOldGfx, sNewGfx, sDiffGfx);
331 
332                 // if (FileHelper.exists(sDiffGfx))
333                 if (sDiffGfx.length() > 0)
334                 {
335                     int nResult = identify(sDiffGfx);
336                     if (nResult == 1)
337                     {
338                         aStatus.nDiffStatus = StatusHelper.DIFF_NO_DIFFERENCES;
339                     }
340                     else
341                     {
342                         try
343                         {
344                             int nPercent = estimateGfx(sOldGfx, sNewGfx, sDiffGfx);
345                             aStatus.nDiffStatus = StatusHelper.DIFF_DIFFERENCES_FOUND;
346                             aStatus.nPercent = nPercent;
347 
348                             // GlobalLogWriter.get().println("Hello World:  Percent:= " + nPercent);
349                             // GlobalLogWriter.get().println("Hello World: TriState:= " + _tUseBorderMove.intValue());
350                             // GlobalLogWriter.get().println("Hello World:  DocType:= " + m_sDocumentType);
351 
352 // TODO: insert here the new BorderRemover if the percentage value is creater than 75%
353                             if (nPercent > 75 &&
354                                 ((_tUseBorderMove == TriState.TRUE ) ||
355                                  ((_tUseBorderMove == TriState.UNSET) &&
356                                   m_sDocumentType.indexOf("MS PowerPoint") > 0)))
357                             {
358                                 setBorderMove(TriState.TRUE);
359 
360                                 String sOld_BM_Gfx =  getJPEGName(_sSourcePath1, sS1Basename + ".BM", StringHelper.createValueString(i, 4));
361                                 String sNew_BM_Gfx =  getJPEGName(_sSourcePath2, sS2Basename + ".BM", StringHelper.createValueString(i, 4));
362                                 String sDiff_BM_Gfx_ = getJPEGName(_sOutputPath, sS1Basename + ".diff.BM", StringHelper.createValueString(i, 4));
363                                 aStatus.setFilesForBorderMove(sOld_BM_Gfx, sNew_BM_Gfx, sDiff_BM_Gfx_);
364                                 try
365                                 {
366                                     BorderRemover a = new BorderRemover();
367                                     a.createNewImageWithoutBorder(sOldGfx, sOld_BM_Gfx);
368                                     a.createNewImageWithoutBorder(sNewGfx, sNew_BM_Gfx);
369 
370                                     String sDiff_BM_Gfx = compareJPEGs( sOld_BM_Gfx, sNew_BM_Gfx, sDiff_BM_Gfx_);
371 
372                                     // if (FileHelper.exists(sDiff_BM_Gfx))
373                                     if (sDiff_BM_Gfx.length() > 0)
374                                     {
375                                         nResult = identify(sDiff_BM_Gfx);
376                                         if (nResult == 1)
377                                         {
378                                             aStatus.nDiffStatus = StatusHelper.DIFF_AFTER_MOVE_DONE_NO_PROBLEMS;
379                                             aStatus.nPercent2 = 0;
380                                         }
381                                         else
382                                         {
383                                             nPercent = estimateGfx(sOld_BM_Gfx, sNew_BM_Gfx, sDiff_BM_Gfx);
384                                             aStatus.nDiffStatus = StatusHelper.DIFF_AFTER_MOVE_DONE_DIFFERENCES_FOUND;
385                                             aStatus.nPercent2 = nPercent;
386                                         }
387                                     }
388                                     else
389                                     {
390                                     }
391                                 }
392                                 catch(java.io.IOException e)
393                                 {
394                                     GlobalLogWriter.get().println("Exception caught. At border remove: " + e.getMessage());
395                                 }
396                             }
397 
398 
399                         }
400                         catch (java.io.IOException e)
401                         {
402                             GlobalLogWriter.get().println(e.getMessage());
403                         }
404                     }
405 
406                     // checkDiff(sOldGfx, sNewGfx, sDiffGfx);
407                     // if (i >= _nMaxDiffs)
408                     // {
409                     //     break;
410                     // }
411                 }
412                 aList[nStatusIndex ++] = aStatus;
413             }
414             return aList;
415         }
416 
417 
418     public StatusHelper[] createDiffs(String _sOutputPath, String[] _aRefList, String[] _aPSList, int _nMaxDiffs, TriState _tUseBorderMove)
419         {
420             if (_nMaxDiffs < 1)
421             {
422                 _nMaxDiffs = 1;
423             }
424 
425             // count, from which file (jpegs) exist more, take the less one
426             // more are not compareable
427 
428             // take the min of both
429             int nMin = Math.min(_aRefList.length, _aPSList.length);
430             nMin = Math.min(nMin, _nMaxDiffs);
431 
432             StatusHelper[] aList = new StatusHelper[nMin];
433 
434 //  TODO: if both document do not have same page count, produce an error
435             // System.out.println("min of both: " + String.valueOf(nMin));
436 
437             int nStatusIndex = 0;
438             for (int i=1;i<=nMin;i++)
439             {
440                 String sOldGfx =  _aRefList[i];
441                 String sNewGfx =  _aPSList[i];
442                 // String sDiffGfx_ = getJPEGName(_sOutputPath, sS1Basename + ".diff", StringHelper.createValueString(i, 4));
443 
444 
445                 String sDiffGfx = compareJPEGs(sOldGfx, sNewGfx );
446                 StatusHelper aStatus = new StatusHelper(sOldGfx, sNewGfx, sDiffGfx);
447 
448                 // if (FileHelper.exists(sDiffGfx))
449                 if (sDiffGfx.length() > 0)
450                 {
451                     int nResult = identify(sDiffGfx);
452                     if (nResult == 1)
453                     {
454                         aStatus.nDiffStatus = StatusHelper.DIFF_NO_DIFFERENCES;
455                     }
456                     else
457                     {
458                         try
459                         {
460                             int nPercent = estimateGfx(sOldGfx, sNewGfx, sDiffGfx);
461                             // GlobalLogWriter.get().println("Hello World:  Percent:= " + nPercent);
462                             // GlobalLogWriter.get().println("Hello World: TriState:= " + _tUseBorderMove.intValue());
463                             // GlobalLogWriter.get().println("Hello World:  DocType:= " + m_sDocumentType);
464 
465                             aStatus.nDiffStatus = StatusHelper.DIFF_DIFFERENCES_FOUND;
466                             aStatus.nPercent = nPercent;
467 
468                             if (nPercent > 75 &&
469                                 ((_tUseBorderMove == TriState.TRUE ) ||
470                                  ((_tUseBorderMove == TriState.UNSET) &&
471                                   m_sDocumentType.indexOf("MS PowerPoint") > 0)))
472                             {
473                                 _tUseBorderMove = TriState.TRUE;
474 //  TODO: problem is here, that we have to create some new names.
475 
476                                 String sBasename1 = FileHelper.getBasename(sOldGfx);
477                                 String sNameNoSuffix1 = FileHelper.getNameNoSuffix(sBasename1);
478                                 String sBasename2 = FileHelper.getBasename(sNewGfx);
479                                 String sNameNoSuffix2 = FileHelper.getNameNoSuffix(sBasename2);
480 
481                                 String sTmpDir = util.utils.getUsersTempDir();
482                                 String fs = System.getProperty("file.separator");
483 
484                                 String sOld_BM_Gfx =  sTmpDir + fs + sNameNoSuffix1 + "-BM-" + StringHelper.createValueString(i, 4) + ".jpg";
485                                 String sNew_BM_Gfx =  sTmpDir + fs + sNameNoSuffix2 + "-BM-" + StringHelper.createValueString(i, 4) + ".jpg";
486                                 try
487                                 {
488                                     BorderRemover a = new BorderRemover();
489                                     a.createNewImageWithoutBorder(sOldGfx, sOld_BM_Gfx);
490                                     a.createNewImageWithoutBorder(sNewGfx, sNew_BM_Gfx);
491 
492                                     String sDiff_BM_Gfx = compareJPEGs( sOld_BM_Gfx, sNew_BM_Gfx );
493 
494                                     aStatus.setFilesForBorderMove(sOld_BM_Gfx, sNew_BM_Gfx, sDiff_BM_Gfx);
495 
496                                     // if (FileHelper.exists(sDiff_BM_Gfx))
497                                     if (sDiff_BM_Gfx.length() > 0)
498                                     {
499                                         nResult = identify(sDiff_BM_Gfx);
500                                         if (nResult == 1)
501                                         {
502                                             aStatus.nDiffStatus = StatusHelper.DIFF_AFTER_MOVE_DONE_NO_PROBLEMS;
503                                             aStatus.nPercent2 = 0;
504                                         }
505                                         else
506                                         {
507                                             nPercent = estimateGfx(sOld_BM_Gfx, sNew_BM_Gfx, sDiff_BM_Gfx);
508                                             aStatus.nDiffStatus = StatusHelper.DIFF_AFTER_MOVE_DONE_DIFFERENCES_FOUND;
509                                             aStatus.nPercent2 = nPercent;
510                                         }
511                                     }
512                                     else
513                                     {
514                                     }
515                                 }
516                                 catch(java.io.IOException e)
517                                 {
518                                     GlobalLogWriter.get().println("Exception caught. At border remove: " + e.getMessage());
519                                 }
520                             }
521                         }
522                         catch (java.io.IOException e)
523                         {
524                             GlobalLogWriter.get().println(e.getMessage());
525                         }
526                     }
527 
528                     // checkDiff(sOldGfx, sNewGfx, sDiffGfx);
529                     // if (i >= _nMaxDiffs)
530                     // {
531                     //     break;
532                     // }
533                 }
534                 aList[nStatusIndex ++] = aStatus;
535             }
536             return aList;
537         }
538 
539     public static String compareJPEGs(String _sOldGfx, String _sNewGfx)
540         {
541             String sBasename1 = FileHelper.getBasename(_sOldGfx);
542             String sNameNoSuffix1 = FileHelper.getNameNoSuffix(sBasename1);
543             String sBasename2 = FileHelper.getBasename(_sNewGfx);
544             String sNameNoSuffix2 = FileHelper.getNameNoSuffix(sBasename2);
545 
546             String sTmpDir = util.utils.getUsersTempDir();
547             String fs = System.getProperty("file.separator");
548 
549             String sDiffName = sTmpDir + fs + sNameNoSuffix1 + "-" + sNameNoSuffix2 + "-diff.jpg";
550 
551             return compareJPEGs(_sOldGfx, _sNewGfx, sDiffName);
552         }
553 
554     public static String compareJPEGs(String _sOldGfx, String _sNewGfx, String _sDiffGfx)
555         {
556             String sComposite = "composite";
557             if (OSHelper.isWindows())
558             {
559                 sComposite = "composite.exe";
560             }
561 
562             // String sCommand = sComposite + " -compose difference " +
563             //     StringHelper.doubleQuoteIfNeed(_sOldGfx) + " " +
564             //     StringHelper.doubleQuoteIfNeed(_sNewGfx) + " " +
565             //     StringHelper.doubleQuoteIfNeed(_sDiffGfx);
566 
567             String[] sCommandArray =
568                 {
569                     sComposite,
570                     "-compose",
571                     "difference",
572                     _sOldGfx,
573                     _sNewGfx,
574                     _sDiffGfx
575                 };
576 
577             ProcessHandler aHandler = new ProcessHandler(sCommandArray);
578             boolean bBackValue = aHandler.executeSynchronously();
579 
580             String sBack = aHandler.getOutputText();
581             GlobalLogWriter.get().println("'" + sBack + "'");
582 
583             // return aHandler.getExitCode();
584             if (FileHelper.exists(_sDiffGfx))
585             {
586                 return _sDiffGfx;
587             }
588             return "";
589         }
590 
591     /**
592      * wrapper for ImageMagick identify,
593      * function checks how many different colors a picture contains.
594      * if it's only one color (nResult==1), like background color, there is no difference.
595      */
596     int identify(String _sDiffGfx)
597         {
598             int nResult = 0;
599             // would like to know what the meaning of %k is for ImageMagick's 'identify'
600             String sIM_Format = "%k";
601             // if (OSHelper.isWindows())
602             // {
603             //     sIM_Format = "%%k";
604             // }
605 
606             String sIdentify = "identify";
607             if (OSHelper.isWindows())
608             {
609                 sIdentify = "identify.exe";
610             }
611 
612             // String sCommand = sIdentify + " " + sIM_Format + " " + StringHelper.doubleQuoteIfNeed(_sDiffGfx);
613 
614             String[] sCommandArray =
615                 {
616                     sIdentify,
617                     "-format",
618                     sIM_Format,
619                     _sDiffGfx
620                 };
621             ProcessHandler aHandler = new ProcessHandler(sCommandArray);
622             boolean bBackValue = aHandler.executeSynchronously();
623             String sBack = aHandler.getOutputText();
624             GlobalLogWriter.get().println("'" + sBack + "'");
625 
626             // try to interpret the result, which we get as a String
627             try
628             {
629                 int nIdx = sBack.indexOf("\n");
630                 if (nIdx > 0)
631                 {
632                     sBack = sBack.substring(0, nIdx);
633                 }
634 
635                 nResult = Integer.valueOf(sBack).intValue();
636             }
637             catch(java.lang.NumberFormatException e)
638             {
639                 GlobalLogWriter.get().println("Number format exception");
640                 nResult = 0;
641             }
642             return nResult;
643         }
644 
645     /*
646      * Check 2 different differ files
647      * return 1 if there is no difference between both diff files.
648      */
649 
650 //  TODO: Maybe a StatusHelper is a better return value
651     public StatusHelper checkDiffDiff(String _sOutputPath, String _sSourcePath1, String _sSourceFile1, String _sSourcePath2, String _sSourceFile2)
652         {
653             String sNewGfx =  _sSourcePath1 + fs + _sSourceFile1;
654             String sOldGfx =  _sSourcePath2 + fs + _sSourceFile2;
655 
656             int nNumber = 1;
657             String sDiffGfx;
658             sDiffGfx = getJPEGName(_sOutputPath, _sSourceFile1 + ".diff", StringHelper.createValueString(nNumber, 4));
659 
660             StatusHelper aCurrentStatus = new StatusHelper(sOldGfx, sNewGfx, sDiffGfx);
661 
662             // String sComposite = "composite";
663             // if (OSHelper.isWindows())
664             // {
665             //     sComposite = "composite.exe";
666             // }
667             //
668             // String sCommand = sComposite  +" -compose difference " +
669             //     StringHelper.doubleQuoteIfNeed(sOldGfx) + " " +
670             //     StringHelper.doubleQuoteIfNeed(sNewGfx) + " " +
671             //     StringHelper.doubleQuoteIfNeed(sDiffGfx);
672             //
673             //
674             // // System.out.println(sCommand);
675             // // executeSynchronously(sCommand);
676             // ProcessHandler aHandler = new ProcessHandler(sCommand);
677             // boolean bBackValue = aHandler.executeSynchronously();
678 
679             compareJPEGs(sOldGfx, sNewGfx, sDiffGfx);
680 
681             if (FileHelper.exists(sDiffGfx))
682             {
683                 int nResult = identify(sDiffGfx);
684                 if (nResult == 1)
685                 {
686                     aCurrentStatus.nDiffStatus = StatusHelper.DIFF_NO_DIFFERENCES;
687                 }
688                 else
689                 {
690                     aCurrentStatus.nDiffStatus = StatusHelper.DIFF_DIFFERENCES_FOUND;
691                     try
692                     {
693                         aCurrentStatus.nPercent = estimateGfx(sOldGfx, sNewGfx, sDiffGfx);
694                     }
695                     catch (java.io.IOException e)
696                     {
697                         GlobalLogWriter.get().println(e.getMessage());
698                         aCurrentStatus.nPercent = -1;
699                     }
700                 }
701                 // LLA: should diffdiff file delete?
702                 // File aFile = new File(sDiffGfx);
703                 // aFile.delete();
704             }
705             else
706             {
707                 GlobalLogWriter.get().println("composite can't create the diffdiff file.");
708             }
709 
710             return aCurrentStatus;
711         }
712 
713     // -----------------------------------------------------------------------------
714     /**
715      * count how much pixel differ and between Old or New and the Difference graphics
716      *
717      * First, count the old graphics, then the new graphics due to the fact both should be equal
718      * it should be legal to take result from old or new. We take the graphics with less values.
719      *
720      * Second, count the difference graphics, now take the percent algorithm and
721      * build a percent value, which contain the number of different pixels as a percent value
722      *
723      * Interpretation:
724      * 0%    there is no difference
725      *
726      * <100% Take a look into the difference graphics, maybe the difference graphics shows
727      *       text like outlined or the text is little bit move left, right up or down.
728      *
729      * >100% Yes it's possible that there is a difference more then 100%, maybe a font problem
730      *       between old and new graphics. The font of the new graphics is little bit bigger,
731      *       so the pixel count between old graphics and new graphics is twice the more.
732      *
733      */
734     public int estimateGfx(String _sOldGfx, String _sNewGfx, String _sDiffGfx)
735         throws java.io.IOException
736         {
737             // new count pixels
738             int nNotWhiteCount_OldGraphic = PixelCounter.countNotWhitePixelsFromImage(_sOldGfx);
739             int nNotWhiteCount_NewGraphic = PixelCounter.countNotWhitePixelsFromImage(_sNewGfx);
740             int nNotBlackCount_DiffGraphic = PixelCounter.countNotBlackPixelsFromImage(_sDiffGfx);
741 
742             int nMinNotWhiteCount = Math.min(nNotWhiteCount_NewGraphic, nNotWhiteCount_OldGraphic);
743 
744             // check if not zero
745             if (nMinNotWhiteCount == 0)
746             {
747                 nMinNotWhiteCount = Math.max(nNotWhiteCount_NewGraphic, nNotWhiteCount_OldGraphic);
748                 if (nMinNotWhiteCount == 0)
749                 {
750                     nMinNotWhiteCount = 1;
751                 }
752             }
753 
754             int nPercent = Math.abs(nNotBlackCount_DiffGraphic * 100 / nMinNotWhiteCount);
755             GlobalLogWriter.get().println( "Graphics check, pixel based:" + String.valueOf(nPercent) + "% pixel differ ");
756             return nPercent;
757         }
758 
759 
760 
761 /*
762  * Some selftest functionallity
763  */
764 //    public static void main(String[] args)
765 //        {
766             // System.out.println(FileHelper.getNameNoSuffix("doc.sxw"));
767             // System.out.println(FileHelper.getSuffix("doc.sxw"));
768             // System.out.println(FileHelper.getBasename("doc.sxw"));
769             // System.out.println(FileHelper.getBasename("/tmp/doc.sxw"));
770 
771 //            PRNCompare a = new PRNCompare();
772 //             a.setInputPath(     "/cws/so-cwsserv06/qadev18/SRC680/src.m47/convwatch.keep/input/msoffice/xp/PowerPoint");
773 //             a.setReferencePath( "/cws/so-cwsserv06/qadev18/SRC680/src.m47/convwatch.keep/input/msoffice/xp/PowerPoint");
774 //             a.setOutputPath(    "/tmp/convwatch_java");
775 //             a.setDocFile(       "1_Gov.ppt");
776 //             a.setReferenceFile( "1_Gov.prn" );
777 //             a.setPostScriptFile("1_Gov.ps" );
778             // a.compare();
779 
780 
781 // LLA: 20040804 sample how to build jpegs from reference files
782 //             a.createJPEGFromPostscript("/tmp/convwatch_java",
783 //                                        "/home/apitest/WorkFromHome/20040804/reference", "worddoc.prn" );
784 //
785 //             a.createJPEGFromPostscript("/tmp/convwatch_java",
786 //                                        "/home/apitest/WorkFromHome/20040804/reference", "worddoc.ps" );
787 
788 //             Status[] aList = a.createDiffs("/tmp/convwatch_java",
789 //                                            "/tmp/convwatch_java", "worddoc.prn",
790 //                                            "/tmp/convwatch_java", "worddoc.ps",
791 //                                            2);
792 
793 // LLA: 20040805 sample how to check 2 gfx files
794 // this function return DifferenceType.NO_DIFFERENCE if the pictures contain no graphically difference
795 //             DifferenceType aReturnValue = a.checkDiffDiff("/tmp/convwatch_java",
796 //                                                           "/tmp/convwatch_java", "worddoc.prn.diff1.jpg",
797 //                                                           "/tmp/convwatch_java/old", "worddoc.prn.diff1.jpg");
798 //             if (aReturnValue.equals( DifferenceType.NO_DIFFERENCE ))
799 //             {
800 //                 System.out.println("There is no difference between both diff files.");
801 //             }
802 
803             // a.setOldDiff(       "/olddiffs");
804 //        }
805 }
806