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