001    package railo.runtime.img;
002    
003    import java.awt.image.BufferedImage;
004    import java.awt.image.ColorModel;
005    import java.awt.image.IndexColorModel;
006    import java.io.IOException;
007    
008    import javax.imageio.stream.ImageInputStream;
009    
010    import org.apache.commons.codec.binary.Base64;
011    
012    import railo.commons.io.IOUtil;
013    import railo.commons.io.res.Resource;
014    import railo.commons.io.res.util.ResourceUtil;
015    import railo.commons.lang.StringUtil;
016    import railo.runtime.exp.ExpressionException;
017    import railo.runtime.img.coder.Coder;
018    
019    public class ImageUtil {
020            
021            private static Coder coder;
022            
023            static {
024                    coder = Coder.getInstance();
025            }
026            
027    
028    
029            public static String[] getWriterFormatNames() {
030                    return coder.getWriterFormatNames();
031            }
032            public static String[] getReaderFormatNames() {
033                    return coder.getReaderFormatNames();
034            }
035            
036    
037            /**
038             * translate a file resource to a buffered image
039             * @param res
040             * @return
041             * @throws IOException
042             */
043            public static BufferedImage toBufferedImage(Resource res,String format) throws IOException {
044                    return coder.toBufferedImage(res, format);
045            }
046    
047            /**
048             * translate a binary array to a buffered image
049             * @param binary
050             * @return
051             * @throws IOException
052             */
053            public static BufferedImage toBufferedImage(byte[] bytes,String format) throws IOException {
054                    return coder.toBufferedImage(bytes, format);
055            }
056    
057            
058            
059            
060    
061            public static byte[] readBase64(String b64str) throws ExpressionException {
062                    if(StringUtil.isEmpty(b64str))
063                            throw new ExpressionException("base64 string is empty");
064                    
065                    int index = b64str.indexOf("base64,");
066                    if(index!=-1)b64str=b64str.substring(index + 7);
067                    
068                    return Base64.decodeBase64(b64str.getBytes());
069            }
070            
071            public static String getFormat(Resource res) throws IOException {
072                    String ext=getFormatFromExtension(res,null);
073                    if(ext!=null) return ext;
074                    String mt=ResourceUtil.getMimeType(res, null);
075                    if(mt==null) return null;//throw new IOException("can't extract mimetype from ["+res+"]");
076                    return getFormatFromMimeType(mt);
077            }
078    
079            public static String getFormat(byte[] binary) throws IOException {
080                    return getFormatFromMimeType(IOUtil.getMimeType(binary, ""));
081            }
082    
083            public static String getFormat(byte[] binary,String defaultValue) {
084                    return getFormatFromMimeType(IOUtil.getMimeType(binary, ""),defaultValue);
085            }
086    
087            public static String getFormatFromExtension(Resource res, String defaultValue) {
088                    String ext=ResourceUtil.getExtension(res,null);
089                    if("gif".equalsIgnoreCase(ext))return "gif";
090                    if("jpg".equalsIgnoreCase(ext))return "jpg";
091                    if("jpe".equalsIgnoreCase(ext))return "jpg";
092                    if("jpeg".equalsIgnoreCase(ext))return "jpg";
093                    if("png".equalsIgnoreCase(ext))return "png";
094                    if("tiff".equalsIgnoreCase(ext))return "tiff";
095                    if("tif".equalsIgnoreCase(ext))return "tiff";
096                    if("bmp".equalsIgnoreCase(ext))return "bmp";
097                    if("bmp".equalsIgnoreCase(ext))return "bmp";
098                    if("wbmp".equalsIgnoreCase(ext))return "wbmp";
099                    if("ico".equalsIgnoreCase(ext))return "bmp";
100                    if("wbmp".equalsIgnoreCase(ext))return "wbmp";
101                    if("psd".equalsIgnoreCase(ext))return "psd";
102                    if("fpx".equalsIgnoreCase(ext))return "fpx";
103                    
104                    if("pnm".equalsIgnoreCase(ext))return "pnm";
105                    if("pgm".equalsIgnoreCase(ext))return "pgm";
106                    if("pbm".equalsIgnoreCase(ext))return "pbm";
107                    if("ppm".equalsIgnoreCase(ext))return "ppm";
108                    return defaultValue;    
109            }
110            
111            
112            
113            
114            public static String getFormatFromMimeType(String mt) throws IOException {
115                    String format = getFormatFromMimeType(mt, null);
116                    if(format!=null) return format;
117                    
118                    if(StringUtil.isEmpty(mt))throw new IOException("cannot find Format of given image");//31
119                    throw new IOException("can't find Format ("+mt+") of given image");
120            }
121            
122            public static String getFormatFromMimeType(String mt, String defaultValue) {
123                    if("image/gif".equals(mt)) return "gif";
124                    if("image/gi_".equals(mt)) return "gif";
125                    
126                    if("image/jpeg".equals(mt)) return "jpg";
127                    if("image/jpg".equals(mt)) return "jpg";
128                    if("image/jpe".equals(mt)) return "jpg";
129                    if("image/pjpeg".equals(mt)) return "jpg";
130                    if("image/vnd.swiftview-jpeg".equals(mt)) return "jpg";
131                    if("image/pipeg".equals(mt)) return "jpg";
132                    if("application/x-jpg".equals(mt)) return "jpg";
133                    if("application/jpg".equals(mt)) return "jpg";
134                    if("image/jp_".equals(mt)) return "jpg";
135                    
136                    if("image/png".equals(mt)) return "png";
137                    if("image/x-png".equals(mt))return "png";
138                    if("application/x-png".equals(mt)) return "png";
139                    if("application/png".equals(mt)) return "png";
140                    
141                    if("image/tiff".equals(mt)) return "tiff";
142                    if("image/tif".equals(mt)) return "tiff";
143                    if("image/x-tif".equals(mt)) return "tiff";
144                    if("image/x-tiff".equals(mt)) return "tiff";
145                    if("application/tif".equals(mt)) return "tiff";
146                    if("application/x-tif".equals(mt)) return "tiff";
147                    if("application/tiff".equals(mt)) return "tiff";
148                    if("application/x-tiff".equals(mt)) return "tiff";
149                    
150                    if("image/bmp".equals(mt)) return "bmp";
151                    if("image/vnd.wap.wbmp".equals(mt)) return "wbmp";
152                    
153                    if("image/fpx".equals(mt)) return "fpx";
154                    if("image/x-fpx".equals(mt)) return "fpx";
155                    if("image/vnd.fpx".equals(mt)) return "fpx";
156                    if("image/vnd.netfpx".equals(mt)) return "fpx";
157                    if("image/vnd.fpx".equals(mt)) return "fpx";
158                    if("application/vnd.netfpx".equals(mt)) return "fpx";
159                    if("application/vnd.fpx".equals(mt)) return "fpx";
160                    
161                    if("image/x-portable-anymap".equals(mt)) return "pnm";
162                    if("image/x-portable/anymap".equals(mt)) return "pnm";
163                    if("image/x-pnm".equals(mt)) return "pnm";
164                    if("image/pnm".equals(mt)) return "pnm";
165                    
166                    if("image/x-portable-graymap".equals(mt)) return "pgm";
167                    if("image/x-portable/graymap".equals(mt)) return "pgm";
168                    if("image/x-pgm".equals(mt)) return "pgm";
169                    if("image/pgm".equals(mt)) return "pgm";
170                    
171                    if("image/portable bitmap".equals(mt)) return "pbm";
172                    if("image/x-portable-bitmap".equals(mt)) return "pbm";
173                    if("image/x-portable/bitmap".equals(mt)) return "pbm";
174                    if("image/x-pbm".equals(mt)) return "pbm";
175                    if("image/pbm".equals(mt)) return "pbm";
176                    
177                    if("image/x-portable-pixmap".equals(mt)) return "ppm";
178                    if("application/ppm".equals(mt)) return "ppm";
179                    if("application/x-ppm".equals(mt)) return "ppm";
180                    if("image/x-p".equals(mt)) return "ppm";
181                    if("image/x-ppm".equals(mt)) return "ppm";
182                    if("image/ppm".equals(mt)) return "ppm";
183    
184                    if("image/ico".equals(mt)) return "ico";
185                    if("image/x-icon".equals(mt)) return "ico";
186                    if("application/ico".equals(mt)) return "ico";
187                    if("application/x-ico".equals(mt)) return "ico";
188    
189                    if("image/photoshop".equals(mt)) return "psd";
190                    if("image/x-photoshop".equals(mt)) return "psd";
191                    if("image/psd".equals(mt)) return "psd";
192                    if("application/photoshop".equals(mt)) return "psd";
193                    if("application/psd".equals(mt)) return "psd";
194                    if("zz-application/zz-winassoc-psd".equals(mt)) return "psd";
195                    
196                    // can not terminate this types exactly
197                    // image/x-xbitmap
198                    // application/x-win-bitmap
199                    // image/x-win-bitmap
200                    // application/octet-stream
201                    return defaultValue;
202            }
203            
204            
205            public static String getMimeTypeFromFormat(String mt) throws IOException {
206                    if("gif".equals(mt)) return "image/gif";
207                    if("jpeg".equals(mt)) return "image/jpg";
208                    if("jpg".equals(mt)) return "image/jpg";
209                    if("jpe".equals(mt)) return "image/jpg";
210                    if("png".equals(mt)) return "image/png";
211                    if("tiff".equals(mt)) return "image/tiff";
212                    if("tif".equals(mt)) return "image/tiff";
213                    if("bmp".equals(mt)) return "image/bmp";
214                    if("bmp".equals(mt)) return "image/bmp";
215                    if("wbmp".equals(mt)) return "image/vnd.wap.wbmp";
216                    if("fpx".equals(mt)) return "image/fpx";
217                    
218                    if("pgm".equals(mt)) return "image/x-portable-graymap";
219                    if("pnm".equals(mt)) return "image/x-portable-anymap";
220                    if("pbm".equals(mt)) return "image/x-portable-bitmap";
221                    if("ppm".equals(mt)) return "image/x-portable-pixmap";
222    
223                    if("ico".equals(mt)) return "image/ico";
224                    if("psd".equals(mt)) return "image/psd";
225                    
226                    if(StringUtil.isEmpty(mt))throw new IOException("can't find Format of given image");//31
227                    throw new IOException("can't find Format ("+mt+") of given image");
228            }
229    
230            public static void closeEL(ImageInputStream iis) {
231                     try {
232                     if(iis!=null)iis.close();
233             } 
234             catch (Throwable t) {}
235                    
236                    
237            }
238    
239            public static BufferedImage createBufferedImage(BufferedImage image, int columns, int rows) {
240            ColorModel colormodel = image.getColorModel();
241            BufferedImage newImage;
242            if(colormodel instanceof IndexColorModel) {
243                if(colormodel.getTransparency() != 1)
244                    newImage = new BufferedImage(columns, rows, 2);
245                else
246                    newImage = new BufferedImage(columns, rows, 1);
247            } 
248            else {
249                newImage = new BufferedImage(colormodel, image.getRaster().createCompatibleWritableRaster(columns, rows), colormodel.isAlphaPremultiplied(), null);
250            }
251            return newImage;
252        }
253        
254        public static BufferedImage createBufferedImage(BufferedImage image) {
255            return createBufferedImage(image, image.getWidth(), image.getHeight());
256        }
257    }