001/**
002 *
003 * Copyright (c) 2014, the Railo Company Ltd. All rights reserved.
004 *
005 * This library is free software; you can redistribute it and/or
006 * modify it under the terms of the GNU Lesser General Public
007 * License as published by the Free Software Foundation; either 
008 * version 2.1 of the License, or (at your option) any later version.
009 * 
010 * This library is distributed in the hope that it will be useful,
011 * but WITHOUT ANY WARRANTY; without even the implied warranty of
012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
013 * Lesser General Public License for more details.
014 * 
015 * You should have received a copy of the GNU Lesser General Public 
016 * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
017 * 
018 **/
019package lucee.runtime.img;
020
021import java.awt.image.BufferedImage;
022import java.awt.image.RenderedImage;
023import java.io.File;
024import java.io.IOException;
025import java.io.InputStream;
026import java.io.OutputStream;
027import java.lang.reflect.InvocationTargetException;
028import java.lang.reflect.Method;
029
030import lucee.commons.io.IOUtil;
031import lucee.commons.io.SystemUtil;
032import lucee.commons.io.res.Resource;
033import lucee.commons.io.res.util.ResourceUtil;
034import lucee.commons.lang.ClassUtil;
035import lucee.commons.lang.IDGenerator;
036import lucee.commons.lang.StringUtil;
037
038public class JAIUtil {
039
040        private static Class _RenderedOp;
041        private static Method getAsBufferedImage;
042        private static Class _JAI;
043        private static Method create1;
044        private static Method create3;
045        private static Boolean supported=null;
046        private static String[] readFormats=new String[]{"tiff","pnm","fpx"};
047        private static String[] writeFormats=new String[]{"tiff","pnm"};
048        
049
050        public static boolean isSupportedWriteFormat(String format) {
051                return "tiff".equalsIgnoreCase(format) || "pnm".equalsIgnoreCase(format);
052        }
053        
054        public static boolean isSupportedReadFormat(String format) {
055                return "tiff".equalsIgnoreCase(format) || "pnm".equalsIgnoreCase(format) || "fpx".equalsIgnoreCase(format);
056        }
057
058        public static String[] getSupportedReadFormat() {
059                return readFormats;
060        }
061
062        public static String[] getSupportedWriteFormat() {
063                return writeFormats;
064        }
065        
066        public static boolean isJAISupported() {
067                if(supported==null) {
068                        supported=ClassUtil.loadClass("javax.media.jai.JAI",null)!=null?Boolean.TRUE:Boolean.FALSE;
069                }
070                return supported.booleanValue();
071        }
072
073
074
075        public static BufferedImage read(Resource res) throws IOException {
076                Resource tmp=null;
077                try{
078                        if(!(res instanceof File)) {
079                                tmp=SystemUtil.getTempDirectory().getRealResource(IDGenerator.intId()+"-"+res.getName());
080                                IOUtil.copy(res, tmp);
081                                res=tmp;
082                        }
083                        //Object im = JAI.create("fileload", res.getAbsolutePath());
084                        return getAsBufferedImage(create("fileload", res.getAbsolutePath()));
085                }
086                finally {
087                        if(tmp!=null) ResourceUtil.removeEL(tmp, false);
088                }
089        }
090        public static BufferedImage read(InputStream is,String format) throws IOException {
091                Resource tmp=null;
092                try{
093                        tmp=SystemUtil.getTempDirectory().getRealResource(IDGenerator.intId()+(StringUtil.isEmpty(format)?"":"."+format));
094                        IOUtil.copy(is, tmp,false);
095                        //Object im = JAI.create("fileload", tmp.getAbsolutePath());
096                        return getAsBufferedImage(create("fileload", tmp.getAbsolutePath()));
097                }
098                finally {
099                        if(tmp!=null) ResourceUtil.removeEL(tmp, false);
100                }
101        }
102        
103        public static void write(BufferedImage img, Resource res,String format) throws IOException {
104                Resource tmp=res;
105                try{
106                        if(!(res instanceof File)) {
107                                tmp=SystemUtil.getTempDirectory().getRealResource(IDGenerator.intId()+"-"+res.getName());
108                        }
109                        //JAI.create("filestore", img, tmp.getAbsolutePath(),format);
110                        create("filestore", img, tmp.getAbsolutePath(),format);
111                }
112                finally {
113                        if(tmp!=res) {
114                                IOUtil.copy(tmp, res);
115                                ResourceUtil.removeEL(tmp, false);
116                        }
117                }
118        }
119        
120        public static void write(BufferedImage img, OutputStream os,String format) throws IOException {
121                Resource tmp=null;
122                try{
123                        tmp=SystemUtil.getTempDirectory().getRealResource(IDGenerator.intId()+"."+format);
124                        create("filestore", img, tmp.getAbsolutePath(),format);
125                        IOUtil.copy(tmp, os,false);
126                }
127                finally {
128                        if(tmp!=null) ResourceUtil.removeEL(tmp, false);
129                }
130        }
131        
132////////////////////////////////////////////////////////////////////
133
134        private static Object create(String name, Object param) throws IOException {
135                try {
136                        return create1().invoke(null, new Object[]{name,param});
137                } catch (Exception e) {
138                        throw toIOException(e);
139                }
140        }
141        
142        private static Object create(String name, Object img, Object param1, Object param2) throws IOException {
143                try {
144                        return create3().invoke(null, new Object[]{name,img,param1,param2});
145                }
146                catch (Exception e) {
147                        throw toIOException(e);
148                }
149        }
150
151        private static BufferedImage getAsBufferedImage(Object im) throws IOException {
152                //RenderedOp.getAsBufferedImage();
153                try {
154                        return (BufferedImage) getAsBufferedImage().invoke(im, new Object[0]);
155                } 
156                catch (Exception e) {
157                        throw toIOException(e);
158                }
159        }
160
161        private static Method getAsBufferedImage() throws IOException {
162                if(getAsBufferedImage==null) {
163                        try {
164                                getAsBufferedImage = getRenderedOp().getMethod("getAsBufferedImage", new Class[0]);
165                        }
166                        catch (Exception e) {
167                                throw toIOException(e);
168                        }
169                }
170                return getAsBufferedImage;
171        }
172
173        private static Method create1() throws IOException {
174                if(create1==null) {
175                        try {
176                                create1 = getJAI().getMethod("create", new Class[]{String.class,Object.class});
177                        } 
178                        catch (Exception e) {
179                                throw toIOException(e);
180                        }
181                }
182                return create1;
183        }
184
185        private static Method create3() throws IOException {
186                if(create3==null) {
187                        try {
188                                create3 = getJAI().getMethod("create", new Class[]{String.class,RenderedImage.class,Object.class,Object.class});
189                        } catch (Exception e) {
190                                throw toIOException(e);
191                        }
192                }
193                return create3;
194        }
195        
196        private static Class getRenderedOp() throws IOException {
197                if(_RenderedOp==null) {
198                        _RenderedOp = ClassUtil.loadClass("javax.media.jai.RenderedOp",null);
199                        if(_RenderedOp==null)
200                                throw new IOException("JAI is not installed on the system but needed for this extension");
201                }
202                return _RenderedOp;
203        }
204        
205        private static Class getJAI() throws IOException {
206                if(_JAI==null) {
207                        _JAI = ClassUtil.loadClass("javax.media.jai.JAI",null);
208                        if(_JAI==null)
209                                throw new IOException("JAI is not installed on the system but needed for this extension");
210                }
211                return _JAI;
212        }
213
214        
215
216        
217        private static IOException toIOException(Throwable e) {
218                if(e instanceof InvocationTargetException)
219                        e=((InvocationTargetException)e).getTargetException();
220                
221                if(e instanceof IOException) return (IOException) e;
222                IOException ioe = new IOException(e.getMessage());
223                ioe.setStackTrace(e.getStackTrace());
224                return ioe;
225        }
226}