001    // ============================================== 
002    //                                                                                              
003    // Module-Imaging 1.0, 05-2006                  
004    // +++++++++++++++++++++++++++++++++++++                        
005    //                                                                                              
006    // Andreas Trappe       - idea, concept
007    // Chi Vu Huu           - concept, development
008    //
009    // $Revision$ $Date$ 
010    // ============================================== 
011    
012    package org.mycore.services.imaging;
013    
014    import java.io.IOException;
015    import java.io.InputStream;
016    import java.io.OutputStream;
017    
018    import org.apache.log4j.Logger;
019    import org.jdom.JDOMException;
020    import org.mycore.common.MCRConfiguration;
021    import org.mycore.datamodel.ifs.MCRFile;
022    
023    public class MCRImgService {
024    
025        public final int THUMBNAIL = 0;
026    
027        public final int IMAGE = 1;
028    
029        protected float scaleFactor = 0.0F;
030    
031        protected boolean USE_CACHE = false;
032    
033        protected int format = -1;
034    
035        private static Logger LOGGER = Logger.getLogger(MCRImgService.class.getName());
036    
037        public enum ScaleMode {
038            fitWidth, fitHeight, normal
039        }
040    
041        public MCRImgService() {
042            MCRConfiguration config = MCRConfiguration.instance();
043            USE_CACHE = (new Boolean(config.getString("MCR.Module-iview.useCache"))).booleanValue();
044        }
045    
046        // Image getter methods
047    
048        // fit to Width x Heigth, even Thumbnail
049        public void getImage(MCRFile image, int newWidth, int newHeight, OutputStream output, ScaleMode scaleMode) throws IOException {
050            MCRConfiguration config = MCRConfiguration.instance();
051            ImgProcessor processor = new MCRImgProcessor();
052            float jpegQuality = java.lang.Float.parseFloat(config.getString("MCR.Module-iview.jpegQuality"));
053            processor.setJpegQuality(jpegQuality);
054    
055            String filename = image.getName();
056    
057            float scaleHelp = 1;
058    
059            try {
060                if (image.getAdditionalData("ImageMetaData") == null) {
061                    LOGGER.debug("MCRImgService create Add-Data");
062                    MCRImgCacheCommands.cacheFile(image, true);
063                }
064            } catch (IOException e) {
065                // TODO Auto-generated catch block
066                e.printStackTrace();
067            } catch (JDOMException e) {
068                // TODO Auto-generated catch block
069                e.printStackTrace();
070            } catch (Exception e) {
071                // TODO Auto-generated catch block
072                e.printStackTrace();
073            }
074    
075            if (USE_CACHE) {
076                LOGGER.debug("Get " + filename + " Width x Height - use Cache");
077    
078                CacheManager cache = MCRImgCacheManager.instance();
079    
080                InputStream input = null;
081    
082                int thumbWidth = Integer.parseInt(config.getString("MCR.Module-iview.thumbnail.size.width"));
083                int thumbHeight = Integer.parseInt(config.getString("MCR.Module-iview.thumbnail.size.height"));
084    
085                int origWidth = cache.getImgWidth(image);
086                int origHeight = cache.getImgHeight(image);
087    
088                int cacheWidth = Integer.parseInt(config.getString("MCR.Module-iview.cache.size.width"));
089                int cacheHeight = Integer.parseInt(config.getString("MCR.Module-iview.cache.size.height"));
090    
091                float scaleHelpW = (float) cacheWidth / (float) origWidth;
092                float scaleHelpH = (float) cacheHeight / (float) origHeight;
093    
094                if (scaleHelpW > scaleHelpH) {
095                    scaleHelp = scaleHelpH;
096                    cacheWidth = (int) (cacheWidth * scaleHelp);
097                } else {
098                    scaleHelp = scaleHelpW;
099                    cacheHeight = (int) (cacheHeight * scaleHelp);
100                }
101    
102                if ((newWidth == thumbWidth || newHeight == thumbHeight) && cache.existInCache(image, MCRImgCacheManager.THUMB)) {
103                    LOGGER.debug("Get Thumbnail from ImgCache for " + filename);
104    
105                    cache.getImage(image, MCRImgCacheManager.THUMB, output);
106                    // newWidth <= cacheWidth && newHeight <= cacheHeight
107                } else if ((newWidth <= cacheWidth) && cache.existInCache(image, MCRImgCacheManager.CACHE)) {
108                    LOGGER.debug("Get Cache from ImgCache for " + filename);
109    
110                    // scaleFactor = scaleFactor / scalefactor;
111    
112                    // get the small cached version
113                    input = cache.getImageAsInputStream(image, MCRImgCacheManager.CACHE);
114                } else if (cache.existInCache(image, MCRImgCacheManager.ORIG)) {
115                    LOGGER.debug("Get Orig from ImgCache for " + filename);
116                    scaleHelp = 1;
117                    input = cache.getImageAsInputStream(image, MCRImgCacheManager.ORIG);
118    
119                } else {
120                    LOGGER.debug("Get Orig from IFS for " + filename);
121                    input = image.getContentAsInputStream();
122                }
123    
124                if (input != null) {
125                    try {
126                        switch (scaleMode) {
127                        case fitWidth:
128                            processor.resizeFitWidth(input, newWidth, output);
129                            break;
130                        default:
131                            processor.resize(input, newWidth, newHeight, output);
132                            break;
133                        }
134                    } finally {
135                        input.close();
136                    }
137                }
138            } else {
139                LOGGER.debug("Get " + filename + " Width x Height - use Processor");
140                InputStream input = image.getContentAsInputStream();
141                try {
142                    switch (scaleMode) {
143                    case fitWidth:
144                        processor.resizeFitWidth(input, newWidth, output);
145                        break;
146                    default:
147                        processor.resize(input, newWidth, newHeight, output);
148                        break;
149                    }
150                } finally {
151                    input.close();
152                }
153            }
154    
155            output.close();
156            scaleFactor = processor.getScaleFactor() * scaleHelp;
157        }
158    
159        // fitToWidth
160        public void getImage(MCRFile image, int xTopPos, int yTopPos, int boundWidth, int boundHeight, OutputStream output) throws IOException {
161            // CacheManager cache = new MCRImgCacheManager();
162            CacheManager cache = MCRImgCacheManager.instance();
163            int origWidth = cache.getImgWidth(image);
164            LOGGER.debug("getImage - fitToWidth # xTopPos: " + xTopPos);
165            LOGGER.debug("getImage - fitToWidth # yTopPos: " + yTopPos);
166            LOGGER.debug("getImage - fitToWidth # boundWidth: " + boundWidth);
167            LOGGER.debug("getImage - fitToWidth # boundHeight: " + boundHeight);
168    
169            getImage(image, xTopPos, yTopPos, boundWidth, boundHeight, (float) boundWidth / (float) origWidth, output);
170        }
171    
172        public void getImage(MCRFile image, int xTopPos, int yTopPos, int boundWidth, int boundHeight, float scaleFactor, OutputStream output)
173                throws IOException {
174            MCRConfiguration config = MCRConfiguration.instance();
175            ImgProcessor processor = new MCRImgProcessor();
176            float jpegQuality = java.lang.Float.parseFloat(config.getString("MCR.Module-iview.jpegQuality"));
177            processor.setJpegQuality(jpegQuality);
178    
179            LOGGER.debug("getImage - ROI # scaleFactor: " + scaleFactor);
180            LOGGER.debug("getImage - ROI # xTopPos: " + xTopPos);
181            LOGGER.debug("getImage - ROI # yTopPos: " + yTopPos);
182            LOGGER.debug("getImage - ROI # boundWidth: " + boundWidth);
183            LOGGER.debug("getImage - ROI # boundHeight: " + boundHeight);
184    
185            this.scaleFactor = scaleFactor;
186    
187            try {
188                if (image.getAdditionalData("ImageMetaData") == null) {
189                    MCRImgCacheCommands.cacheFile(image, true);
190                }
191            } catch (IOException e) {
192                // TODO Auto-generated catch block
193                e.printStackTrace();
194            } catch (JDOMException e) {
195                // TODO Auto-generated catch block
196                e.printStackTrace();
197            } catch (Exception e) {
198                // TODO Auto-generated catch block
199                e.printStackTrace();
200            }
201    
202            if (USE_CACHE) {
203                LOGGER.debug("getImage - ROI using 'if (USE_CACHE)'");
204                CacheManager cache = MCRImgCacheManager.instance();
205                InputStream input = null;
206    
207                int origWidth = cache.getImgWidth(image);
208                int origHeight = cache.getImgHeight(image);
209    
210                LOGGER.debug("getImage - ROI # OrigWidth: " + origWidth);
211                LOGGER.debug("getImage - ROI # OrigHeight: " + origHeight);
212    
213                int resWidth = (int) (scaleFactor * origWidth);
214    
215                int cacheWidth = Integer.parseInt(config.getString("MCR.Module-iview.cache.size.width"));
216    
217                xTopPos = (int) (xTopPos * scaleFactor);
218                yTopPos = (int) (yTopPos * scaleFactor);
219    
220                if ((resWidth <= cacheWidth) && cache.existInCache(image, MCRImgCacheManager.CACHE)) {
221                    LOGGER.debug("getImage - ROI # get Cache version");
222    
223                    float scaleHelp = (float) cacheWidth / (float) origWidth;
224    
225                    scaleFactor = scaleFactor / scaleHelp;
226    
227                    xTopPos = (int) (xTopPos / scaleHelp);
228                    yTopPos = (int) (yTopPos / scaleHelp);
229    
230                    // get the small cached version
231                    input = cache.getImageAsInputStream(image, MCRImgCacheManager.CACHE);
232                } else if (cache.existInCache(image, MCRImgCacheManager.ORIG)) {
233                    LOGGER.debug("getImage - ROI # get orig version from Cache");
234    
235                    // get the orig cached version
236                    input = cache.getImageAsInputStream(image, MCRImgCacheManager.ORIG);
237                } else {
238                    LOGGER.debug("getImage - ROI # get orig version from IFS");
239    
240                    // get the orig version from IFS
241                    input = image.getContentAsInputStream();
242                }
243                LOGGER.debug("getImage - ROI # edited scaleFactor: " + scaleFactor);
244                LOGGER.debug("getImage - ROI # edited xTopPos: " + xTopPos);
245                LOGGER.debug("getImage - ROI # edited yTopPos: " + yTopPos);
246                LOGGER.debug("getImage - ROI # edited boundWidth: " + boundWidth);
247                LOGGER.debug("getImage - ROI # edited boundHeight: " + boundHeight);
248    
249                if (input != null) {
250                    processor.scaleROI(input, xTopPos, yTopPos, boundWidth, boundHeight, scaleFactor, output);
251                }
252                input.close();
253            } else {
254                InputStream input = image.getContentAsInputStream();
255                processor.scaleROI(input, xTopPos, yTopPos, boundWidth, boundHeight, scaleFactor, output);
256                input.close();
257            }
258            output.close();
259        }
260    
261        public float getScaleFactor() {
262            return scaleFactor;
263        }
264    
265    }