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 
30 package graphical;
31 
32 import helper.OSHelper;
33 import helper.ProcessHandler;
34 import helper.StringHelper;
35 import java.io.File;
36 
37 /**
38  *
39  * @author ll93751
40  */
41 public class JPEGCreator extends EnhancedComplexTestCase
42 {
43     // @Override
44     public String[] getTestMethodNames()
45     {
46         return new String[]{"PostscriptOrPDFToJPEG"};
47     }
48 
49     /**
50      * test function.
51      */
52     public void PostscriptOrPDFToJPEG()
53     {
54         GlobalLogWriter.set(log);
55         ParameterHelper aParam = new ParameterHelper(param);
56 
57         // run through all documents found in Inputpath
58         foreachPSorPDFinInputPath(aParam);
59     }
60 
61 
62     public void checkOneFile(String _sDocumentName, String _sResult, ParameterHelper _aParams) throws OfficeException
63     {
64          GlobalLogWriter.println("  Document: " + _sDocumentName);
65          GlobalLogWriter.println("   results: " + _sResult);
66 //         IOffice aOffice = new Office(_aParams, _sResult);
67 //         aOffice.start();
68 //         aOffice.load(_sDocumentName);
69 //         aOffice.storeAsPostscript();
70 //         aOffice.close();
71          String sJPEGNameSchema = createJPEG(_sDocumentName, "", _aParams);
72 
73          // store information only if jpeg files exists
74          int nPages = countPages(sJPEGNameSchema);
75          if (nPages > 0)
76          {
77              createSmallPictures(sJPEGNameSchema);
78 
79              // read out tolerance file
80              String sFileDir = FileHelper.getPath(_sDocumentName);
81              String sBasename = FileHelper.getBasename(_sDocumentName);
82              int nTolerance = 0;
83              String sToleranceFile = FileHelper.appendPath(sFileDir, "tolerance.ini");
84              File aToleranceFile = new File(sToleranceFile);
85              if (aToleranceFile.exists())
86              {
87                  IniFile aIniFile = new IniFile(sToleranceFile);
88                  nTolerance = aIniFile.getIntValue(sBasename, "accept", 0); // default for all pages
89                  aIniFile.close();
90              }
91 
92              String sIndexFile = FileHelper.appendPath(_sResult, "index.ini");
93              File aIndexFile = new File(sIndexFile);
94              if (aIndexFile.exists())
95              {
96                  // store only if an index file exists
97                  IniFile aIniFile = new IniFile(sIndexFile);
98                  aIniFile.insertValue(sBasename, "jpegschema", sJPEGNameSchema);
99                  aIniFile.insertValue(sBasename, "pages", nPages);
100                  aIniFile.insertValue(sBasename, "tolerance", nTolerance);
101                  aIniFile.close();
102              }
103          }
104          else
105          {
106              assure("There are no pages in document:'" + _sDocumentName + "', maybe document currupt?", false, true);
107          }
108     }
109 
110 /**
111  * Create a lot of smaller and nicer Pictures of the big fat pages.
112  * Looks better
113  * @param _sJPEGSchema
114  */
115     public void createSmallPictures(String _sJPEGSchema)
116     {
117         ParameterHelper aParam = new ParameterHelper(param);
118         if (! aParam.createSmallPictures())
119         {
120             return;
121         }
122 
123         int nPages = 0;
124         if (_sJPEGSchema.length() > 0)
125         {
126             // TODO: if there doesn't exists a '%04d' in the schema we will return 9999 which is a little bit wrong here.
127             for (int i=1;i<10000;i++)
128             {
129                 String sJPEGFilename = getFilenameForJPEGSchema(_sJPEGSchema, i);
130                 if (FileHelper.exists(sJPEGFilename))
131                 {
132                     convertToNearSameFileWithWidth340(sJPEGFilename);
133                     // m_aFileList.add(sNewJPEGFilename); // as long as the files exist, fill the array
134                     nPages ++;
135                 }
136                 else
137                 {
138                     break;                             // stop file check
139                 }
140             }
141         }
142         // return nPages;
143     }
144 
145 /**
146  * convert a picture to a new picture with 340 pixel width.
147  * @param _sJPEGFilename
148  */
149 public static void convertToNearSameFileWithWidth340(String _sJPEGFilename)
150 {
151     ParameterHelper aParam = new ParameterHelper(param);
152     if (! aParam.createSmallPictures())
153     {
154         return;
155     }
156     String sJPEGFilename = _sJPEGFilename.replaceAll("\\\\", "/");
157 //    if (OSHelper.isWindows())
158 //    {
159 //        sJPEGFilename = sJPEGFilename.replaceAll("/", "\\\\");
160 //    }
161     String sNewJPEGFilename;
162     sNewJPEGFilename = util.utils.replaceAll13(sJPEGFilename, ".jpg", "_w340.jpg");
163     convertToWidth340(sJPEGFilename, sNewJPEGFilename);
164 }
165 
166     /**
167  * convert chart2_Regression.ods.ps_180DPI_0001.jpg -filter Catrom -resize
168 340x chart2_Regression.ods.ps_180DPI_0001_w340.jpg
169 
170 Point wie bisher
171 Cubic schlecht, weil unscharf
172 ...
173 Triangle ganz brauchbar (default?)
174 Catrom am besten
175 
176  * @param _sFrom
177  * @param _To
178  */
179 private static void convertToWidth340(String _sFrom, String _To)
180 {
181             // int nResult = 0;
182 
183             String sConvertEXE = "convert";
184             if (OSHelper.isLinuxIntel())
185             {
186                 sConvertEXE = "convert";
187             }
188             if (OSHelper.isWindows())
189             {
190                 // TODO!
191                 // HACK Hard coded!
192                 // sConvertEXE = "C:\\Programme\\ImageMagick-6.0.3-q8\\convert.exe";
193                 sConvertEXE = "convert.exe";
194                 String sConvertPath = (String)param.get("imagemagick.path");
195                 if (sConvertPath != null)
196                 {
197                     sConvertEXE = FileHelper.appendPath(sConvertPath, sConvertEXE);
198                 }
199             }
200 
201             String[] sCommandArray =
202                 {
203                     sConvertEXE,
204                     _sFrom,
205                      "-filter", "Catrom",
206                     "-resize", "340x",
207                     _To
208                 };
209             ProcessHandler aHandler = new ProcessHandler(sCommandArray);
210             boolean bBackValue = aHandler.executeSynchronously();
211             int nExitCode = aHandler.getExitCode();
212 
213             String sBack = aHandler.getOutputText();
214             if (sBack.length() > 0)
215             {
216                 GlobalLogWriter.println("'" + sBack + "'");
217             }
218             // try to interpret the result, which we get as a String
219 //            try
220 //            {
221 //                int nIdx = sBack.indexOf("\n");
222 //                if (nIdx > 0)
223 //                {
224 //                    sBack = sBack.substring(0, nIdx);
225 //                }
226 //
227 //                nResult = Integer.valueOf(sBack).intValue();
228 //            }
229 //            catch(java.lang.NumberFormatException e)
230 //            {
231 //                GlobalLogWriter.get().println("Number format exception");
232 //                nResult = 0;
233 //            }
234             // return nResult;
235 }
236 
237 /**
238  * create out of a given Postscript/PDF _sFile a list of JPEGs, one for every page
239  * @param _sFile
240  * @param _sAdditional
241  * @param _aParam
242  * @return the schema of the first jpeg name
243  */
244     String createJPEG(String _sFile, String _sAdditional, ParameterHelper _aParam)
245         {
246             if (_sFile.startsWith("file:///"))
247             {
248                 _sFile = FileHelper.getSystemPathFromFileURL(_sFile);
249             }
250             File aFile = new File(_sFile);
251             if (aFile.exists())
252             {
253                 String sAbsFile = aFile.getAbsolutePath();
254                 if (!sAbsFile.equals(_sFile))
255                 {
256                     _sFile = sAbsFile;
257                 }
258             }
259             else
260             {
261                 GlobalLogWriter.println("File: '" + _sFile + "' doesn't exist.");
262                 return "";
263             }
264             String sFileDir = FileHelper.getPath(_sFile);
265             String sBasename = FileHelper.getBasename(_sFile);
266 //            String sNameNoSuffix = FileHelper.getNameNoSuffix(sBasename);
267 
268             String sTmpDir = util.utils.getUsersTempDir();
269             if (_aParam.getOutputPath() != null)
270             {
271                 sTmpDir = _aParam.getOutputPath();
272             }
273 
274             String sJPEGNameSchema = "";
275             if (_sFile.toLowerCase().endsWith("ps") ||
276                 _sFile.toLowerCase().endsWith("prn") ||
277                 _sFile.toLowerCase().endsWith("pdf"))
278             {
279                 // seems to be a Postscript of PDF file
280 
281                 sJPEGNameSchema = createJPEGsFromPostscript(sTmpDir, sFileDir, sBasename, _aParam.getResolutionInDPI());
282             }
283             else if (_sFile.toLowerCase().endsWith("jpg") ||
284                      _sFile.toLowerCase().endsWith("jpeg"))
285             {
286                 // do nothing, it's already a picture.
287                 return _sFile;
288             }
289             else
290             {
291                 // we assume it's an office document.
292                 // Office files will not handled here, we need a PS or PDF file
293             }
294             return sJPEGNameSchema;
295         }
296 
297         private String getJPEGName(String _sOutputPath, String _sBasename, int _nResolutionInDPI, String _sGS_PageOutput)
298         {
299             // String fs = System.getProperty("file.separator");
300             String sName = _sBasename + "_" + String.valueOf(_nResolutionInDPI) + "DPI_" + _sGS_PageOutput + ".jpg";
301             String sJPEGName = FileHelper.appendPath(_sOutputPath, sName);
302             return sJPEGName;
303         }
304 
305         /**
306      * Create via ghostscript (gs) from the reference file for every page a JPEG file
307      *
308      * MUST set:
309      * m_sOutputPath, m_sReferenceFile, m_sReferencePath
310      *
311      * return exit code from gs command
312      */
313 
314      private static final String m_sGS_PageOutput = "%04d";
315 
316      private String createJPEGsFromPostscript(String _sOutputPath, String _sSourcePath, String _sSourceFile, int _nResolutionInDPI)
317         {
318             FileHelper.makeDirectories("", _sOutputPath);
319 
320             // create a jpeg from original prn
321             // String fs = System.getProperty("file.separator");
322 
323             String sJPEGNameSchema = getJPEGName(_sOutputPath, _sSourceFile, _nResolutionInDPI, m_sGS_PageOutput);
324             String sPostscriptOrPDFFile = FileHelper.appendPath(_sSourcePath, _sSourceFile);
325             String sGhostscriptEXE = "gs";
326             if (OSHelper.isWindows())
327             {
328                 sGhostscriptEXE = "gswin32c.exe";
329                 String sGhostscriptEXE2 = (String)param.get("gs.exe");
330                 if (sGhostscriptEXE2 != null)
331                 {
332                     sGhostscriptEXE = sGhostscriptEXE2;
333                 }
334                 String sGhostscriptPath = (String)param.get("gs.path");
335                 if (sGhostscriptPath != null)
336                 {
337                     sGhostscriptEXE = FileHelper.appendPath(sGhostscriptPath, sGhostscriptEXE);
338                 }
339             }
340 
341 //            String sCommand = sGhostscriptEXE + " -dNOPROMPT -dBATCH -sDEVICE=jpeg -r" + String.valueOf(_nResolutionInDPI) + " -dNOPAUSE -sOutputFile=" + StringHelper.doubleQuoteIfNeed(sJPGFilename) + " " + StringHelper.doubleQuoteIfNeed(sOriginalFile);
342             String[] sCommandArray =
343                 {
344                     sGhostscriptEXE,
345                     "-dNOPROMPT",
346                     "-dBATCH",
347                     "-sDEVICE=jpeg",
348                     "-r" + String.valueOf(_nResolutionInDPI),
349                     "-dNOPAUSE",
350                     "-sOutputFile=" + sJPEGNameSchema,
351                     sPostscriptOrPDFFile
352 
353 
354 
355                 };
356             // System.out.println("Start Command array");
357             // try
358             // {
359             //     Runtime.getRuntime().exec(sCommandArray);
360             // } catch (Exception e) {
361             //     System.out.println("FAILED");
362             // }
363             // System.out.println("done");
364 
365 // TODO: gives ghostscript an error we can handle?
366             ProcessHandler aHandler = new ProcessHandler(sCommandArray);
367             boolean bBackValue = aHandler.executeSynchronously();
368             assure("There seems to be a problem with ghostscript", bBackValue, true);
369             int nExitCode = aHandler.getExitCode();
370             // ArrayList m_aFileList = new ArrayList();
371 
372             // String sJPEGNameSchema = "";
373             if (nExitCode == 0)
374             {
375                 // TODO: return a real filename, due to the fact we don't know how much files are created, maybe better to return a list
376                 int nPages = countPages(sJPEGNameSchema);
377                 if (nPages == 0)
378                 {
379                     // return only a valid schema name if there at least one page.
380                     sJPEGNameSchema = "";
381                     assure("Document '" + sPostscriptOrPDFFile + "' doesn't create pages.", false, true);
382                 }
383             }
384             else
385             {
386                 assure("There seems to be a problem with ghostscript and '" + sPostscriptOrPDFFile + "' exit code: " + nExitCode, false, true);
387                 GlobalLogWriter.println("Warning: There seems to be a problem with '" + sGhostscriptEXE + "'...");
388             }
389             // String[] aList = new String[m_aFileList.size()];
390             // aList = (String[])m_aFileList.toArray(aList);
391             return sJPEGNameSchema; // sNewJPEGFilename;
392         }
393 
394     public static String getFilenameForJPEGSchema(String _sJPEGSchema, int _nPage)
395         {
396             if (_nPage < 1 || _nPage > 9999)
397             {
398                 return "";
399             }
400             final String sFilename = util.utils.replaceAll13(_sJPEGSchema, m_sGS_PageOutput, StringHelper.createValueString(_nPage, 4));
401             return sFilename;
402         }
403 
404         /**
405          * Return the number of really exists JPEG files
406          * Give a JPEG Schema which contains something like '%04d' which will be converted by a number between 0001 and 9999 always
407          * with leading '0' (zero)
408          * @param _sJPEGSchema
409          * @return number of really existing pages of a given JPEG schema
410          */
411     public int countPages(String _sJPEGSchema)
412     {
413         int nPages = 0;
414         if (_sJPEGSchema.length() > 0)
415         {
416             // TODO: if there doesn't exists a '%04d' in the schema we will return 9999 which is a little bit wrong here.
417             for (int i=1;i<10000;i++)
418             {
419                 String sNewJPEGFilename = getFilenameForJPEGSchema(_sJPEGSchema, i);
420                 if (FileHelper.exists(sNewJPEGFilename))
421                 {
422                     // m_aFileList.add(sNewJPEGFilename); // as long as the files exist, fill the array
423                     nPages ++;
424                 }
425                 else
426                 {
427                     break;                             // stop file check
428                 }
429             }
430         }
431         return nPages;
432     }
433 
434 //    public static void main(String [] _args)
435 //    {
436 //// DONE: give an index.ini file ok
437 ////        String args[] = {
438 ////            "-TimeOut", "3600000",
439 ////            "-tb", "java_complex",
440 ////            "-o", "graphical.JPEGCreator",
441 ////            "-DOC_COMPARATOR_INPUT_PATH", "C:\\CWS\\temp\\output\\index.ini",
442 ////            "-DOC_COMPARATOR_OUTPUT_PATH", "C:\\CWS\\temp\\output",
443 ////            "-DOC_COMPARATOR_PRINT_MAX_PAGE", "9999",
444 ////            "-DOC_COMPARATOR_GFX_OUTPUT_DPI_RESOLUTION", "180",
445 ////            "-DOC_COMPARATOR_HTML_OUTPUT_PREFIX", "http://so-gfxcmp-lin.germany.sun.com/gfxcmp_ui/cw.php?inifile=",
446 //////            "-DOC_COMPARATOR_REFERENCE_CREATOR_TYPE", "PDF",      /* default: "OOo" */
447 //////            "-DOC_COMPARATOR_REFERENCE_CREATOR_TYPE", "msoffice", /* default: "OOo" */
448 //////            "-OFFICE_VIEWABLE", "false",
449 ////            "-AppExecutionCommand", "\"C:/Programme/sun/staroffice 9/program/soffice.exe\"  -norestore -nocrashreport -accept=pipe,name=ll93751;urp;",
450 ////            "-NoOffice"
451 ////        };
452 //
453 //// Done: give a directory, where exist pdf/ps files ok.
454 //// Done: inputpath (given file) doesn't exists, ok.
455 //// Done: give a ps/pdf file. ok.
456 //
457 //        String args[] = {
458 //            "-TimeOut", "3600000",
459 //            "-tb", "java_complex",
460 //            "-o", "graphical.JPEGCreator",
461 //            "-DOC_COMPARATOR_INPUT_PATH", "C:\\CWS\\temp\\output\\Names7.odt.pdf",
462 //            "-DOC_COMPARATOR_OUTPUT_PATH", "C:\\CWS\\temp\\output",
463 //            "-DOC_COMPARATOR_PRINT_MAX_PAGE", "9999",
464 //            "-DOC_COMPARATOR_GFX_OUTPUT_DPI_RESOLUTION", "180",
465 //            "-DOC_COMPARATOR_HTML_OUTPUT_PREFIX", "http://so-gfxcmp-lin.germany.sun.com/gfxcmp_ui/cw.php?inifile=",
466 ////            "-DOC_COMPARATOR_REFERENCE_CREATOR_TYPE", "PDF",      /* default: "OOo" */
467 ////            "-DOC_COMPARATOR_REFERENCE_CREATOR_TYPE", "msoffice", /* default: "OOo" */
468 ////            "-OFFICE_VIEWABLE", "false",
469 //            "-AppExecutionCommand", "\"C:/Programme/sun/staroffice 9/program/soffice.exe\"  -norestore -nocrashreport -accept=pipe,name=ll93751;urp;",
470 //            "-NoOffice"
471 //        };
472 //
473 //        org.openoffice.Runner.main(args);
474 //    }
475 
476 }
477