fixing scaling images -> nullpointer, patch by yossarian
[mir.git] / source / mircoders / media / MediaHandlerImagesExternScaling.java
1 /*\r
2  * Copyright (C) 2001, 2002 The Mir-coders group\r
3  *\r
4  * This file is part of Mir.\r
5  *\r
6  * Mir is free software; you can redistribute it and/or modify\r
7  * it under the terms of the GNU General Public License as published by\r
8  * the Free Software Foundation; either version 2 of the License, or\r
9  * (at your option) any later version.\r
10  *\r
11  * Mir is distributed in the hope that it will be useful,\r
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
14  * GNU General Public License for more details.\r
15  *\r
16  * You should have received a copy of the GNU General Public License\r
17  * along with Mir; if not, write to the Free Software\r
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
19  *\r
20  * In addition, as a special exception, The Mir-coders gives permission to link\r
21  * the code of this program with  any library licensed under the Apache Software License,\r
22  * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library\r
23  * (or with modified versions of the above that use the same license as the above),\r
24  * and distribute linked combinations including the two.  You must obey the\r
25  * GNU General Public License in all respects for all of the code used other than\r
26  * the above mentioned libraries.  If you modify this file, you may extend this\r
27  * exception to your version of the file, but you are not obligated to do so.\r
28  * If you do not wish to do so, delete this exception statement from your version.\r
29  */\r
30 package mircoders.media;\r
31 \r
32 \r
33 import java.io.BufferedInputStream;\r
34 import java.io.File;\r
35 import java.io.FileInputStream;\r
36 import java.io.FileNotFoundException;\r
37 import java.io.IOException;\r
38 import java.io.InputStream;\r
39 \r
40 import mir.entity.Entity;\r
41 import mir.log.LoggerWrapper;\r
42 import mir.media.MediaExc;\r
43 import mir.media.MediaFailure;\r
44 import mir.media.image.ImageMagickImageProcessor;\r
45 import mir.media.image.ImageProcessor;\r
46 import mir.misc.StringUtil;\r
47 import mir.util.FileRoutines;\r
48 \r
49 /**\r
50  * Image handler that stores images outside of the database.\r
51  * \r
52  * @author Zapata\r
53  * @version 1.0\r
54  */\r
55 \r
56 public class MediaHandlerImagesExternScaling extends MediaHandlerGeneric\r
57 {\r
58   private int maxSize;\r
59   private int maxIconSize;\r
60   private float minDescaleRatio;\r
61   private int minDescaleReduction;\r
62   public MediaHandlerImagesExternScaling() {\r
63     logger = new LoggerWrapper("Media.Images.Extern");\r
64     maxSize = configuration.getInt("Producer.Image.MaxSize");\r
65     maxIconSize = configuration.getInt("Producer.Image.MaxIconSize");\r
66     minDescaleRatio = configuration.getFloat("Producer.Image.MinDescalePercentage")/100;\r
67     minDescaleReduction = configuration.getInt("Producer.Image.MinDescaleReduction");\r
68   }\r
69   \r
70 \r
71   \r
72   public void produce(Entity anImageEntity, Entity mediaTypeEnt) throws MediaExc, MediaFailure {\r
73     try {\r
74       String date = anImageEntity.getFieldValue("date");\r
75       String datePath = StringUtil.webdbDate2path(date);\r
76       String ext = "." + mediaTypeEnt.getFieldValue("name");\r
77       String fileBasePath = datePath + anImageEntity.getId();\r
78       String filePath = fileBasePath + ext;\r
79 \r
80       String imageFilePath = getBaseStoragePath() + File.separator + filePath;\r
81       File imageFile = new File(imageFilePath);\r
82       \r
83       if (!imageFile.exists()) {\r
84         throw new MediaExc("error in MediaHandlerImagesExtern.execute(): "\r
85             + filePath + " does not exist!");\r
86       } else {\r
87         ImageProcessor processor = new ImageMagickImageProcessor(imageFile);\r
88         String iconPath = getBaseIconStoragePath() + fileBasePath + ".jpg";\r
89         String iconStoragePath = doIconScaling(processor, iconPath);\r
90         anImageEntity.setFieldValue("icon_height", new Integer(processor.getScaledHeight()).toString());\r
91         anImageEntity.setFieldValue("icon_width", new Integer(processor.getScaledWidth()).toString());\r
92         anImageEntity.setFieldValue("icon_path", iconPath);\r
93         \r
94         String imageOriginalRelPath = doImageScaling(filePath, imageFile, processor);\r
95         anImageEntity.setFieldValue("original_file_path", imageOriginalRelPath);\r
96         anImageEntity.setFieldValue("img_height", Integer.toString(processor.getScaledHeight()));\r
97         anImageEntity.setFieldValue("img_width", Integer.toString(processor.getScaledWidth()));\r
98 \r
99         processor.cleanup();\r
100         anImageEntity.setFieldValue("publish_path", filePath);\r
101         anImageEntity.update();\r
102         reportChange(iconStoragePath);\r
103         reportChange(imageFilePath);\r
104       }\r
105     }\r
106     catch(Throwable t) {\r
107       logger.error("MediaHandlerImagesExtern.execute: " + t.getMessage(), t);\r
108       throw new MediaFailure(t.getMessage(), t);\r
109     }\r
110   }\r
111 \r
112     /**\r
113      * Scale an icon image and write it to the file system.\r
114      * @param processor\r
115      * @param iconPath\r
116      * @return\r
117      * @throws MediaExc\r
118      */\r
119     private String doIconScaling(ImageProcessor processor, String iconPath) throws MediaExc {\r
120         String iconStoragePath = configuration.getString("Producer.StorageRoot") + iconPath;\r
121         File iconFile = new File(iconStoragePath);\r
122         processor.descaleImage(maxIconSize, minDescaleRatio, minDescaleReduction);\r
123         File dir = new File(iconFile.getParent());\r
124         if (dir != null && !dir.exists()) {\r
125           dir.mkdirs();\r
126         }\r
127                 try {\r
128                         processor.writeScaledData(iconFile, "JPEG");\r
129                 } catch (FileNotFoundException e) {\r
130                         // TODO Auto-generated catch block\r
131                         e.printStackTrace();\r
132                 } catch (IOException e) {\r
133                         // TODO Auto-generated catch block\r
134                         e.printStackTrace();\r
135                 }\r
136         return iconStoragePath;\r
137     }\r
138 \r
139     /**\r
140      * Make the resized file.\r
141      * @param filePath\r
142      * @param imageFile\r
143      * @param processor\r
144      * @return\r
145      * @throws MediaExc\r
146      * @throws IOException\r
147      */\r
148     private String doImageScaling(String filePath, File imageFile, ImageProcessor processor) throws MediaExc, IOException {\r
149         // get a file path where the the original image should be saved if image resizing is turned on\r
150           String imagesOriginalDir = configuration.getString("Producer.ImagesOriginalDir.Path");\r
151           String imagesOriginalDirRelPath = configuration.getString("Producer.ImagesOriginalDir.RelPath");\r
152           String imageOriginalFilePath = imagesOriginalDir + filePath;\r
153           String imageOriginalRelPath = imagesOriginalDirRelPath +  filePath;\r
154           File originalFile = new File(imageOriginalFilePath);   \r
155           processor.descaleImage(maxSize, minDescaleRatio, minDescaleReduction);\r
156           File originalDir = new File(originalFile.getParent());\r
157           if (originalDir != null && !originalDir.exists()) {\r
158             originalDir.mkdirs();\r
159           }\r
160           if (!originalFile.exists()) {\r
161             FileRoutines.copy(imageFile, originalFile);\r
162             reportChange(originalFile.getAbsolutePath());\r
163           }\r
164           // yoss: don't write the scaled data again if it's the same size as\r
165           // the file that's there right now. Image producer runs are 4 times\r
166           // faster this way.\r
167           if (processor.getScaledFileSize() != imageFile.length()) {\r
168               processor.writeScaledData(imageFile, "JPEG");\r
169           }\r
170         return imageOriginalRelPath;\r
171     }\r
172 \r
173 /** {@inheritDoc} */\r
174   public InputStream getThumbnail(Entity anImageEntity) throws MediaExc, MediaFailure {\r
175     try {\r
176       File file = new File(configuration.getString("Producer.StorageRoot") + anImageEntity.getFieldValue("icon_path"));\r
177 \r
178       if (!file.exists()) {\r
179         // hackish\r
180         file = new File(configuration.getHome(), "../img/photo_big.gif");\r
181       }\r
182 \r
183       return new BufferedInputStream(\r
184         new FileInputStream(file),8192);\r
185     }\r
186     catch (Throwable t) {\r
187       return null;\r
188     }\r
189   }\r
190 \r
191   public String getIconMimeType(Entity anImageEntity, Entity aMediaType) {\r
192     return "image/jpeg";\r
193   }\r
194 \r
195   public String getBaseStoragePath()\r
196   {\r
197     return configuration.getString("Producer.Image.Path");\r
198   }\r
199 \r
200   public String getBaseIconStoragePath()\r
201   {\r
202     return configuration.getString("Producer.Image.IconPath");\r
203   }\r
204 \r
205   public String getPublishHost()\r
206   {\r
207     return StringUtil.removeSlash(configuration.getString("Producer.Image.Host"));\r
208   }\r
209 \r
210   public String getTinyIconName()\r
211   {\r
212     return configuration.getString("Producer.Icon.TinyImage");\r
213   }\r
214 \r
215   public String getBigIconName()\r
216   {\r
217     return configuration.getString("Producer.Icon.BigImage");\r
218   }\r
219 \r
220   public String getIconAltName()\r
221   {\r
222     return "Image";\r
223   }\r
224 \r
225   public String getDescr(Entity mediaType)\r
226   {\r
227      return "image/jpeg";\r
228   }\r
229 }\r