1 /*
2  * ************************************************************************
3  *
4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5  *
6  * Copyright 2000, 2010 Oracle and/or its affiliates.
7  *
8  * OpenOffice.org - a multi-platform office productivity suite
9  *
10  * This file is part of OpenOffice.org.
11  *
12  * OpenOffice.org is free software: you can redistribute it and/or modify
13  * it under the terms of the GNU Lesser General Public License version 3
14  * only, as published by the Free Software Foundation.
15  *
16  * OpenOffice.org is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU Lesser General Public License version 3 for more details
20  * (a copy is included in the LICENSE file that accompanied this code).
21  *
22  * You should have received a copy of the GNU Lesser General Public License
23  * version 3 along with OpenOffice.org.  If not, see
24  * <http://www.openoffice.org/license.html>
25  * for a copy of the LGPLv3 License.
26  *
27  * ***********************************************************************
28  */
29 package graphical;
30 
31 import helper.OSHelper;
32 import helper.ProcessHandler;
33 import java.io.File;
34 import java.io.IOException;
35 
36 /**
37  * Helper class to interpret a jpg filename
38  */
39 class NameDPIPage
40 {
41 
42     String Name;
43     int DPI;
44     int Page;
45 
46     private NameDPIPage(String _sName, int _nDPI, int _nPage)
47     {
48         Name = _sName;
49         DPI = _nDPI;
50         Page = _nPage;
51     }
52 
53     public static NameDPIPage interpret(String _sFilename)
54     {
55         String sBasename = FileHelper.getBasename(_sFilename);         // if exist a path, remove it
56         String sNameNoSuffix = FileHelper.getNameNoSuffix(sBasename);  // remove extension (.jpg)
57 
58         // check if there exist a 'DPI_' at specific position
59         String sDPICheck = sNameNoSuffix.substring(sNameNoSuffix.length() - 8, sNameNoSuffix.length() - 4);
60         String sName;
61         int nDPI = -1;
62         int nPage = -1;
63         if (sDPICheck.equals("DPI_"))
64         {
65             // seems to be a generated filename by us.
66             int nDPIStart = sNameNoSuffix.lastIndexOf("_", sNameNoSuffix.length() - 8);
67             sName = sNameNoSuffix.substring(0, nDPIStart);
68             if (nDPIStart > 0)
69             {
70                 String sDPI = sNameNoSuffix.substring(nDPIStart + 1, sNameNoSuffix.length() - 8);
71                 try
72                 {
73                     nDPI = Integer.valueOf(sDPI).intValue();
74                 }
75                 catch (java.lang.NumberFormatException e)
76                 {
77                     GlobalLogWriter.println("DPI: Number format exception");
78                 }
79                 String sPage = sNameNoSuffix.substring(sNameNoSuffix.length() - 4);
80                 try
81                 {
82                     nPage = Integer.valueOf(sPage).intValue();
83                 }
84                 catch (java.lang.NumberFormatException e)
85                 {
86                     GlobalLogWriter.println("Page: Number format exception");
87                 }
88             }
89         }
90         else
91         {
92             sName = sNameNoSuffix;
93         }
94 
95         return new NameDPIPage(sName, nDPI, nPage);
96     }
97 }
98 
99 class CountNotXXXPixelsFromImage extends Thread
100 {
101 
102     private String m_sFilename;
103     protected int m_nValue;
104 
105     CountNotXXXPixelsFromImage(String _sFilename)
106     {
107         m_sFilename = _sFilename;
108     }
109 
110     public int getValue()
111     {
112         return m_nValue;
113     }
114 
115     protected void setValue(int _nValue)
116     {
117         m_nValue = _nValue;
118     }
119 
120     protected String getFilename()
121     {
122         return m_sFilename;
123     }
124 }
125 
126 class CountNotWhitePixelsFromImage extends CountNotXXXPixelsFromImage
127 {
128 
129     CountNotWhitePixelsFromImage(String _sFilename)
130     {
131         super(_sFilename);
132     }
133 
134     public void run()
135     {
136         try
137         {
138             final int nNotWhiteCount = PixelCounter.countNotWhitePixelsFromImage(getFilename());
139             setValue(nNotWhiteCount);
140         }
141         catch (java.io.IOException e)
142         {
143             m_nValue = -1;
144         }
145     }
146 }
147 
148 class CountNotBlackPixelsFromImage extends CountNotXXXPixelsFromImage
149 {
150 
151     CountNotBlackPixelsFromImage(String _sFilename)
152     {
153         super(_sFilename);
154     }
155 
156     public void run()
157     {
158         try
159         {
160             final int nNotBlackCount = PixelCounter.countNotBlackPixelsFromImage(getFilename());
161             setValue(nNotBlackCount);
162         }
163         catch (java.io.IOException e)
164         {
165             m_nValue = -1;
166         }
167     }
168 }
169 
170 /**
171  *
172  * @author ll93751
173  */
174 public class JPEGComparator extends EnhancedComplexTestCase
175 {
176     // @Override
177 
178     public String[] getTestMethodNames()
179     {
180         return new String[]{"CompareJPEGvsJPEG"};
181     }
182     private Tolerance m_aTolerance;
183 
184     /**
185      * test function.
186      */
187     public void CompareJPEGvsJPEG()
188     {
189         GlobalLogWriter.set(log);
190         ParameterHelper aParam = new ParameterHelper(param);
191 
192         // run through all documents found in Inputpath
193         foreachJPEGcompareWithJPEG(aParam);
194     }
195 
196     public void checkOneFile(String _sDocumentName, String _sResult, ParameterHelper _aParams) throws OfficeException
197     {
198         // private void callEveryPictureInIniFile(IniFile _aIniFile, String _sSectionName, ParameterHelper _aParam)
199         // {
200         String sPath = FileHelper.getPath(_sDocumentName);
201         String sSectionName = FileHelper.getBasename(_sDocumentName);
202 
203         // take the build id out of the ini file in the reference file and put it into the current parameter helper
204         String sIniFileForRefBuildID = FileHelper.appendPath(sPath, sSectionName + ".ini");
205         IniFile aIniFileForRefBuildID = new IniFile(sIniFileForRefBuildID);
206         String sRefBuildID = aIniFileForRefBuildID.getValue("global", "buildid");
207         aIniFileForRefBuildID.close();
208 
209         _aParams.getTestParameters().put("RefBuildId", sRefBuildID);
210 
211         String sIniFile = FileHelper.appendPath(sPath, "index.ini");
212         IniFile aIniFile = new IniFile(sIniFile);
213         if (aIniFile.hasValue(sSectionName, "pages"))
214         {
215             // only which has 'pages' has also pictures
216             int nPages = aIniFile.getIntValue(sSectionName, "pages", 0);
217             String sJPEGSchema = aIniFile.getValue(sSectionName, "jpegschema");
218             int nTolerance = aIniFile.getIntValue(sSectionName, "tolerance", 0);
219             m_aTolerance = new Tolerance(nTolerance);
220             for (int i = 1; i <= nPages; i++)
221             {
222                 String sJPEGFilename = JPEGCreator.getFilenameForJPEGSchema(sJPEGSchema, i);
223                 // String sPath = FileHelper.getPath(_aParam.getInputPath());
224                 String sJPEGPath = FileHelper.getPath(sJPEGFilename);
225                 if (!sPath.equals(sJPEGPath))
226                 {
227                     GlobalLogWriter.println("Path where to find the index and where to file the JPEG pictures are not the same.");
228 
229                 }
230                 // String sEntry = FileHelper.appendPath(sPath, sSection);
231                 File aFile = new File(sJPEGFilename);
232                 assure("File '" + sJPEGFilename + "' doesn't exists.", aFile.exists(), true);
233                 if (aFile.exists())
234                 {
235                     GlobalLogWriter.println("Page: " + i);
236                     checkOnePicture(sJPEGFilename, _sResult, _aParams);
237                 }
238             }
239         }
240         else
241         {
242             GlobalLogWriter.println("The document '" + sSectionName + "' seems to have no picture representation.");
243         }
244 
245         String sResultIniFile = FileHelper.appendPath(_sResult, sSectionName);
246         evaluateResult(sResultIniFile, _aParams);
247     }
248 
249     private void evaluateResult(String _sDocument, ParameterHelper _aParams)
250     {
251         String sResultIniFile = _sDocument + ".ini";
252         File aFile = new File(sResultIniFile);
253         assure("Result file doesn't exists " + sResultIniFile, aFile.exists());
254 
255         int good = 0;
256         int bad = 0;
257         int ugly = 0;
258         int ok_status = 1; // 1=ok 2=bad 3=ugly
259 
260         IniFile aResultIniFile = new IniFile(sResultIniFile);
261         int nPages = aResultIniFile.getIntValue("global", "pages", 0);
262         for (int i = 0; i < nPages; i++)
263         {
264             String sCurrentPage = "page" + String.valueOf(i + 1);
265             int nPercent = aResultIniFile.getIntValue(sCurrentPage, "percent", -1);
266             if (nPercent == 0)
267             {
268                 good++;
269             }
270             else if (nPercent <= 5)
271             {
272                 bad++;
273                 ok_status = 2;
274             }
275             else
276             {
277                 ugly++;
278                 ok_status = 3;
279             }
280         }
281 
282         assure("Error: document doesn't contains pages", nPages > 0);
283 
284 // TODO: this information has to come out of the ini files
285         String sStatusRunThrough = "PASSED, ";
286         String sPassed = "OK";
287 
288         String sStatusMessage = "From " + nPages + " page(s) are: ";
289         String sGood = "";
290         String sBad = "";
291         String sUgly = "";
292 
293         if (good > 0)
294         {
295             sGood = " good:=" + good;
296             sStatusMessage += sGood;
297         }
298         if (bad > 0)
299         {
300             sBad = " bad:=" + bad;
301             sStatusMessage += sBad;
302         }
303         if (ugly > 0)
304         {
305             sUgly = " ugly:=" + ugly;
306             sStatusMessage += sUgly;
307         }
308 
309         // Failure matrix
310         //         0     1
311         // ugly    OK    FAILED
312         // bad     OK
313         // good    OK
314 
315         if (ugly > 0)
316         {
317             sPassed = "FAILED";
318         }
319         else
320         {
321             if (bad > 0)
322             {
323                 sPassed = "NEED A LOOK";
324             }
325             else
326             {
327                 sPassed = "OK";
328             }
329         }
330         sStatusRunThrough += sPassed;
331         aResultIniFile.insertValue("global", "state", sStatusRunThrough);
332         aResultIniFile.insertValue("global", "info", sStatusMessage);
333         aResultIniFile.close();
334 
335         _aParams.getTestParameters().put("current_state", sStatusRunThrough);
336         _aParams.getTestParameters().put("current_info", sStatusMessage);
337         _aParams.getTestParameters().put("current_ok_status", ok_status);
338 
339         // if we have a ugly page, we must return this as a FAILED STATUS in Log file!
340         assure("There exist pages marked as ugly.", ugly == 0);
341     }
342 
343     private void checkOnePicture(String _sDocumentName, String _sResult, ParameterHelper _aParams)
344     {
345         GlobalLogWriter.println("JPEG: Compare difference between '" + _sDocumentName + "'  and '" + _sResult + "'");
346         File aResultFile = new File(_sResult);
347         if (aResultFile.isDirectory())
348         {
349             // result is just a directory, so we search for the basename of the source and take this.
350             String sBasename = FileHelper.getBasename(_sDocumentName);
351             String sResultFilename = FileHelper.appendPath(_sResult, sBasename);
352             aResultFile = new File(sResultFilename);
353             if (aResultFile.exists())
354             {
355                 // Original and Result exists
356                 String sInputPath = _aParams.getInputPath();
357                 if (sInputPath.toLowerCase().endsWith("index.ini"))
358                 {
359                     // special case
360                     // we want to get the buildid from the info file.
361                 }
362 
363                 compareJPEG(_sDocumentName, sResultFilename, _aParams);
364 
365             }
366             else
367             {
368                 String sResultFilenamePDF = util.utils.replaceAll13(sResultFilename, ".ps_", ".pdf_");
369                 File aResultPDFFile = new File(sResultFilenamePDF);
370                 if (aResultPDFFile.exists())
371                 {
372                     // Original and Result exists
373                     String sInputPath = _aParams.getInputPath();
374                     if (sInputPath.toLowerCase().endsWith("index.ini"))
375                     {
376                         // special case
377                         // we want to get the buildid from the info file.
378                     }
379 
380                     compareJPEG(_sDocumentName, sResultFilenamePDF, _aParams);
381                 }
382                 else
383                 {
384                     GlobalLogWriter.println("Warning: Result JPEG doesn't exists '" + sResultFilename + "'");
385                 }
386             }
387         }
388         else
389         {
390             // result is also a file
391             if (aResultFile.exists())
392             {
393                 compareJPEG(_sDocumentName, _sResult, _aParams);
394             }
395             else
396             {
397                 GlobalLogWriter.println("Warning: Result JPEG doesn't exists '" + _sResult + "'");
398             }
399         }
400     }
401 
402     /**
403      * compare 2 JPEGs, it is a need, that both _sDocumentName and _sResultFilename exist.
404      * @param _sDocumentName
405      * @param _sResult
406      * @param _aParams
407      * @return 0=no difference !=0 both files differ
408      */
409     private void compareJPEG(String _sDocumentName, String _sResult, ParameterHelper _aParams)
410     {
411         NameDPIPage aNameDPIPage = NameDPIPage.interpret(_sDocumentName);
412 
413         String sSourceBasename = FileHelper.getBasename(_sDocumentName);
414         String sSourcePath = FileHelper.getPath(_sDocumentName);
415         String sDestinationBasename = FileHelper.getBasename(_sResult);
416         String sDestinationPath = FileHelper.getPath(_sResult);
417 
418         if (!sSourcePath.equals(sDestinationPath))
419         {
420             // we want to have all in one Directory, Original, Reference and the Difference result.
421             // copy the original file to the reference path
422             String sNewSourceBasename = "Original_" + sSourceBasename;
423             // String sSource = FileHelper.appendPath(sSourcePath, sSourceBasename);
424             String sSource = _sDocumentName;
425             String sDestination = FileHelper.appendPath(sDestinationPath, sNewSourceBasename);
426             FileHelper.copy(sSource, sDestination);
427             sSourceBasename = sNewSourceBasename;
428             //
429             JPEGCreator.convertToNearSameFileWithWidth340(sDestination);
430         }
431         String sDifferenceBasename = "Difference_between_" + FileHelper.getNameNoSuffix(sSourceBasename) + "_and_" + FileHelper.getNameNoSuffix(sDestinationBasename) + ".jpg";
432         // String sDifferencePath = sDestinationPath;
433 
434         String sSource = FileHelper.appendPath(sDestinationPath, sSourceBasename);
435         String sDestination = FileHelper.appendPath(sDestinationPath, sDestinationBasename);
436         String sDifference = FileHelper.appendPath(sDestinationPath, sDifferenceBasename);
437         int nErr = compareJPEG(sSource, sDestination, sDifference);
438         if (nErr == 0 && FileHelper.exists(sDifference))
439         {
440             // check the difference, returns the count of different colors
441             // this means, 1=only one color, no differences found.
442             int nResult = identify(sDifference);
443             int nPercentColorDiffer = 0;
444 
445             String sResult = "YES";
446 
447             if (m_aTolerance != null)
448             {
449                 final int nAcceptedTolerance = m_aTolerance.getAccept();
450                 if (nResult <= nAcceptedTolerance)
451                 {
452                     nResult = 1;
453                     sResult = "IN TOLERANCE";
454                     GlobalLogWriter.println("The differences are in tolerance.");
455 
456                 }
457             }
458             if (nResult != 1)
459             {
460                 sResult = "NO";
461                 try
462                 {
463                     nPercentColorDiffer = estimateGfx(sSource, sDestination, sDifference);
464                 }
465                 catch (java.io.IOException e)
466                 {
467                     GlobalLogWriter.println("Can't estimate the different colors. " + e.getMessage());
468                 }
469             }
470 
471             // store the result in a result.ini file
472             String sResultFile = FileHelper.appendPath(sDestinationPath, aNameDPIPage.Name + ".ini");
473             int nPage = aNameDPIPage.Page;
474             if (nPage < 0)
475             {
476                 nPage = 0;
477             }
478             IniFile aResultIni = new IniFile(sResultFile);
479 
480             String[] aComment =
481             {
482                 "; This file is automatically created by a graphical.JPEGComparator run",
483                 "; ",
484                 "; If you see this file in a browser you may have forgotten to set the follows in the property file",
485                 "; " + PropertyName.DOC_COMPARATOR_HTML_OUTPUT_PREFIX + "=http://<computer>/gfxcmp_ui/cw.php?inifile=",
486                 "; Please check the documentation if you got confused.",
487                 "; ",
488                 "; "
489             };
490             aResultIni.insertFirstComment(aComment);
491 
492             // write down the global flags
493             int nMaxPage = Math.max(nPage, aResultIni.getIntValue("global", "pages", 0));
494             aResultIni.insertValue("global", "pages", nMaxPage);
495 
496             // INIoutput.writeValue("buildid", _sBuildID);
497             // INIoutput.writeValue("refbuildid", _sRefBuildID);
498             String sRefBuildId = (String) _aParams.getTestParameters().get("RefBuildId");
499             if (sRefBuildId == null)
500             {
501                 sRefBuildId = "";
502             }
503             aResultIni.insertValue("global", "refbuildid", sRefBuildId);
504 
505             aResultIni.insertValue("global", "diffdiff", "no");
506             aResultIni.insertValue("global", "basename", aNameDPIPage.Name);
507             aResultIni.insertValue("global", "dpi", aNameDPIPage.DPI);
508 
509             // write down flags for each page
510             String sSection = "page" + String.valueOf(nPage);
511 
512             aResultIni.insertValue(sSection, "oldgfx", sSource);
513             aResultIni.insertValue(sSection, "newgfx", sDestination);
514             aResultIni.insertValue(sSection, "diffgfx", sDifference);
515             aResultIni.insertValue(sSection, "percent", nPercentColorDiffer);
516             aResultIni.insertValue(sSection, "BM", "false");
517             aResultIni.insertValue(sSection, "result", sResult);
518 
519             aResultIni.close();
520         }
521     }
522 
523 //    // This creates a status for exact on document
524 //    static boolean createINIStatus(StatusHelper[] aList, String _sFilenamePrefix, String _sOutputPath, String _sAbsoluteInputFile, String _sBuildID, String _sRefBuildID)
525 //        {
526 //            // Status
527 //            String fs = System.getProperty("file.separator");
528 //            String sBasename = FileHelper.getBasename(_sAbsoluteInputFile);
529 //            String sNameNoSuffix = FileHelper.getNameNoSuffix(sBasename);
530 ////            String sHTMLFile = _sFilenamePrefix + sNameNoSuffix + ".html";
531 ////            HTMLOutputter HTMLoutput = HTMLOutputter.create(_sOutputPath, sHTMLFile, "", "");
532 ////            HTMLoutput.header(sNameNoSuffix);
533 ////  TODO: version info was fine
534 ////            HTMLoutput.checkSection(sBasename);
535 //            // Status end
536 //
537 //            String sINIFile = _sFilenamePrefix + sNameNoSuffix + ".ini";
538 //            INIOutputter INIoutput = INIOutputter.create(_sOutputPath, sINIFile, "", "");
539 //            INIoutput.createHeader();
540 ////  TODO: version info was fine
541 //
542 //            INIoutput.writeSection("global");
543 //            INIoutput.writeValue("pages", String.valueOf(aList.length));
544 //            INIoutput.writeValue("buildid", _sBuildID);
545 //            INIoutput.writeValue("refbuildid", _sRefBuildID);
546 //            INIoutput.writeValue("diffdiff", "no");
547 //            INIoutput.writeValue("basename", sBasename);
548 //
549 //            boolean bResultIsOk = true;          // result over all pages
550 //            for (int i=0;i<aList.length; i++)
551 //            {
552 //                INIoutput.writeSection("page" + String.valueOf(i + 1));   // list start at point 0, but this is page 1 and so on... current_page = (i + 1)
553 //                aList[i].printStatus();
554 //
555 //                boolean bCurrentResult = true;   // result over exact one page
556 //
557 //                int nCurrentDiffStatus = aList[i].nDiffStatus;
558 //
559 //                // check if the status is in a defined range
560 //                if (nCurrentDiffStatus == StatusHelper.DIFF_NO_DIFFERENCES)
561 //                {
562 //                    // ok.
563 //                }
564 //                else if (nCurrentDiffStatus == StatusHelper.DIFF_DIFFERENCES_FOUND && aList[i].nPercent < 5)
565 //                {
566 //                    // ok.
567 //                }
568 //                else if (nCurrentDiffStatus == StatusHelper.DIFF_AFTER_MOVE_DONE_NO_PROBLEMS)
569 //                {
570 //                    // ok.
571 //                }
572 //                else if (nCurrentDiffStatus == StatusHelper.DIFF_AFTER_MOVE_DONE_DIFFERENCES_FOUND && aList[i].nPercent2 < 5)
573 //                {
574 //                    // ok.
575 //                }
576 //                else
577 //                {
578 //                    // failed.
579 //                    bCurrentResult = false; // logic: nDiff==0 = true if there is no difference
580 //                }
581 //
582 //                // Status
583 ////                HTMLoutput.checkLine(aList[i], bCurrentResult);
584 //                INIoutput.checkLine(aList[i], bCurrentResult);
585 //                bResultIsOk &= bCurrentResult;
586 //            }
587 //            // Status
588 ////            HTMLoutput.close();
589 //            INIoutput.close();
590 //            return bResultIsOk;
591 //        }
592     /**
593      * count how much pixel differ and between Old or New and the Difference graphics
594      *
595      * First, count the old graphics, then the new graphics due to the fact both should be equal
596      * it should be legal to take result from old or new. We take the graphics with less values.
597      *
598      * Second, count the difference graphics, now take the percent algorithm and
599      * build a percent value, which contain the number of different pixels as a percent value
600      *
601      * Interpretation:
602      * 0%    there is no difference
603      *
604      * &lt;100% Take a look into the difference graphics, maybe the difference graphics shows
605      *       text like outlined or the text is little bit move left, right up or down.
606      *
607      * &gt;>100% Yes it's possible that there is a difference more then 100%, maybe a font problem
608      *       between old and new graphics. The font of the new graphics is little bit bigger,
609      *       so the pixel count between old graphics and new graphics is twice the more.
610      *
611      * @param _sOldGfx path & name to the jpeg file (1)
612      * @param _sNewGfx path & name to the other jpeg file (2)
613      * @param _sDiffGfx path & name to the new difference file which shows the difference between (1) and (2)
614      * @return the count of different pixels
615      * @throws java.io.IOException if file access is not possible
616      */
617     public static int estimateGfx(String _sOldGfx, String _sNewGfx, String _sDiffGfx)
618             throws java.io.IOException
619     {
620         TimeHelper a = new TimeHelper();
621         a.start();
622         // Count Pixels
623         final int nNotWhiteCount_OldGraphic = PixelCounter.countNotWhitePixelsFromImage(_sOldGfx);
624         final int nNotWhiteCount_NewGraphic = PixelCounter.countNotWhitePixelsFromImage(_sNewGfx);
625         final int nNotBlackCount_DiffGraphic = PixelCounter.countNotBlackPixelsFromImage(_sDiffGfx);
626 
627         // Count Pixels in different threads
628 //        CountNotWhitePixelsFromImage t1 = new CountNotWhitePixelsFromImage(_sOldGfx);
629 //        CountNotWhitePixelsFromImage t2 = new CountNotWhitePixelsFromImage(_sNewGfx);
630 //        CountNotBlackPixelsFromImage t3 = new CountNotBlackPixelsFromImage(_sDiffGfx);
631 //        t1.start();
632 //        t2.start();
633 //        t3.start();
634 //        try
635 //        {
636 //            t1.join();
637 //        }
638 //        catch (InterruptedException ex)
639 //        {
640 //            GlobalLogWriter.get().println("Thread 1 failed: " + ex.getMessage());
641 //        }
642 //        try
643 //        {
644 //            t2.join();
645 //        }
646 //        catch (InterruptedException ex)
647 //        {
648 //            GlobalLogWriter.get().println("Thread 2 failed: " + ex.getMessage());
649 //        }
650 //        try
651 //        {
652 //            t3.join();
653 //        }
654 //        catch (InterruptedException ex)
655 //        {
656 //            GlobalLogWriter.get().println("Thread 3 failed: " + ex.getMessage());
657 //        }
658 //        final int nNotWhiteCount_OldGraphic = t1.getValue();
659 //        final int nNotWhiteCount_NewGraphic = t2.getValue();
660 //        final int nNotBlackCount_DiffGraphic = t3.getValue();
661 
662         a.stop();
663         GlobalLogWriter.println("Thread Time is: " + a.getTime());
664 
665         int nMinNotWhiteCount = Math.min(nNotWhiteCount_NewGraphic, nNotWhiteCount_OldGraphic);
666 
667         // check if not zero
668         if (nMinNotWhiteCount == 0)
669         {
670             nMinNotWhiteCount = Math.max(nNotWhiteCount_NewGraphic, nNotWhiteCount_OldGraphic);
671             if (nMinNotWhiteCount == 0)
672             {
673                 nMinNotWhiteCount = 1;
674             }
675         }
676 
677         int nPercent = Math.abs(nNotBlackCount_DiffGraphic * 100 / nMinNotWhiteCount);
678         GlobalLogWriter.println("Graphics check, pixel based:" + String.valueOf(nPercent) + "% pixel differ ");
679         return nPercent;
680     }
681 
682     private static int compareJPEG(String _sOldGfx, String _sNewGfx, String _sDiffGfx)
683     {
684         String sComposite = "composite";
685         if (OSHelper.isWindows())
686         {
687             sComposite = "composite.exe";
688             String sIMPath = (String) param.get("imagemagick.path");
689             if (sIMPath != null)
690             {
691                 sComposite = FileHelper.appendPath(sIMPath, sComposite);
692             }
693         }
694 
695         // String sCommand = sComposite + " -compose difference " +
696         //     StringHelper.doubleQuoteIfNeed(_sOldGfx) + " " +
697         //     StringHelper.doubleQuoteIfNeed(_sNewGfx) + " " +
698         //     StringHelper.doubleQuoteIfNeed(_sDiffGfx);
699 
700         String[] sCommandArray =
701         {
702             sComposite,
703             "-compose",
704             "difference",
705             _sOldGfx,
706             _sNewGfx,
707             _sDiffGfx
708         };
709 
710         ProcessHandler aHandler = new ProcessHandler(sCommandArray);
711         boolean bBackValue = aHandler.executeSynchronously();
712         int nExitCode = aHandler.getExitCode();
713         if (nExitCode != 0)
714         {
715             GlobalLogWriter.println("'" + sComposite + "' return with ");
716             String sBack = aHandler.getOutputText();
717             GlobalLogWriter.println("'" + sBack + "'");
718         }
719         else
720         {
721             // creates an extra smaller difference picture
722             File aDiffFile = new File(_sDiffGfx);
723             if (aDiffFile.exists())
724             {
725                 JPEGCreator.convertToNearSameFileWithWidth340(_sDiffGfx);
726             }
727         }
728         return nExitCode;
729     }
730 
731     /**
732      * wrapper for ImageMagick identify,
733      * function checks how many different colors a picture contains.
734      * if it's only one color (nResult==1), like background color, there is no difference.
735      */
736     int identify(String _sDiffGfx)
737     {
738         int nResult = 0;
739         // would like to know what the meaning of %k is for ImageMagick's 'identify'
740         String sIM_Format = "%k";
741         // if (OSHelper.isWindows())
742         // {
743         //     sIM_Format = "%%k";
744         // }
745 
746         String sIdentify = "identify";
747         if (OSHelper.isWindows())
748         {
749             sIdentify = "identify.exe";
750             String sIMPath = (String) param.get("imagemagick.path");
751             if (sIMPath != null)
752             {
753                 sIdentify = FileHelper.appendPath(sIMPath, sIdentify);
754             }
755         }
756 
757         // String sCommand = sIdentify + " " + sIM_Format + " " + StringHelper.doubleQuoteIfNeed(_sDiffGfx);
758 
759         String[] sCommandArray =
760         {
761             sIdentify,
762             "-format",
763             sIM_Format,
764             _sDiffGfx
765         };
766         ProcessHandler aHandler = new ProcessHandler(sCommandArray);
767         boolean bBackValue = aHandler.executeSynchronously();
768         int nExitCode = aHandler.getExitCode();
769 
770         String sBack = aHandler.getOutputText();
771         GlobalLogWriter.println("'" + sBack + "'");
772 
773         // try to interpret the result, which we get as a String
774         try
775         {
776             int nIdx = sBack.indexOf("\n");
777             if (nIdx > 0)
778             {
779                 sBack = sBack.substring(0, nIdx);
780             }
781 
782             nResult = Integer.valueOf(sBack).intValue();
783         }
784         catch (java.lang.NumberFormatException e)
785         {
786             GlobalLogWriter.println("identify(): Number format exception");
787             nResult = 0;
788         }
789         return nResult;
790     }
791 //    public static void main(String [] _args)
792 //    {
793 //// give an index.ini file, ok
794 //// give a directory, where exist jpeg files ok
795 //// inputpath (given file) doesn't exists
796 //// give a jpeg file.
797 //
798 //        String args[] = {
799 //            "-TimeOut", "3600000",
800 //            "-tb", "java_complex",
801 //            "-o", "graphical.JPEGComparator",
802 //            "-DOC_COMPARATOR_INPUT_PATH", "C:\\CWS\\temp\\output\\index.ini",
803 //            "-DOC_COMPARATOR_OUTPUT_PATH", "C:\\CWS\\temp\\output2",
804 ////            "-DOC_COMPARATOR_INPUT_PATH", "C:\\CWS\\temp\\output\\GroupReport.odt.pdf_180DPI_0001.jpg",
805 ////            "-DOC_COMPARATOR_OUTPUT_PATH", "C:\\CWS\\temp\\output2\\Report1.odt.pdf_180DPI_0001.jpg",
806 //            "-DOC_COMPARATOR_HTML_OUTPUT_PREFIX", "http://so-gfxcmp-lin.germany.sun.com/gfxcmp_ui/cw.php?inifile=",
807 ////            "-DOC_COMPARATOR_REFERENCE_CREATOR_TYPE", "PDF",      /* default: "OOo" */
808 ////            "-DOC_COMPARATOR_REFERENCE_CREATOR_TYPE", "msoffice", /* default: "OOo" */
809 ////            "-OFFICE_VIEWABLE", "false",
810 ////            "-AppExecutionCommand", "\"C:/Programme/sun/staroffice 9/program/soffice.exe\"  -norestore -nocrashreport -accept=pipe,name=ll93751;urp;",
811 //            "-NoOffice"
812 //        };
813 //
814 //        org.openoffice.Runner.main(args);
815 //    }
816 }
817