001package bradleyross.j2ee.servlets; 002import java.io.IOException; 003import java.io.PrintWriter; 004import java.io.StringWriter; 005import java.net.URL; 006import java.util.Iterator; 007import javax.servlet.http.HttpServlet; 008import javax.servlet.http.HttpServletRequest; 009import javax.servlet.http.HttpServletResponse; 010import javax.servlet.ServletException; 011import javax.imageio.ImageIO; 012import javax.imageio.ImageReader; 013import javax.imageio.ImageReadParam; 014import javax.imageio.ImageWriter; 015import javax.imageio.plugins.jpeg.JPEGImageWriteParam; 016import javax.imageio.ImageWriteParam; 017import javax.imageio.spi.ImageWriterSpi; 018@SuppressWarnings("serial") 019/** 020 * Get information on codecs. 021 * 022 * <p>It looks like com.sun.media.imageioimpl.plugins.jpeg2000.ImageWriter and 023 * com.sun.media.imageioimpl.plugins.jpeg2000.ImageReader are pure java 024 * while com.sun.media.imageioimpl.plugins.jpeg.CLibJPEGImageReader, 025 * com.sun.media.imageioimpl.plugins.jpeg.CLibJPEGImageWriter, 026 * com.sun.media.imageioimpl.plugins.jpeg2000.J2KImageWriterCodecLib and 027 * com.sun.media.imageioimpl.plugins.jpeg2000.J2KImageReaderCodecLib use 028 * compiled C code.</p> 029 * @author Bradley Ross 030 * 031 */ 032public class CodecInfo extends HttpServlet { 033 /* 034 * This approach was recommended by 035 * http://tomcat.10.n6.nabble.com/Problems-with-ImageIO-td2073212.html 036 * See also 037 * http://www.java.net/node/702588 038 * 039 * Without this line, the ImageIO was unable to find the codecs unless they 040 * were placed in the Java system library or the Java system extensions library. 041 * Apparently, when ImageIO first initialized itself, it was only able to see 042 * the Java system libraries. It is not clear if it would have been able to see 043 * the CLASSPATH at the time that Tomcat was started. 044 * 045 * The problem with codecs not being visible occurred with Windows but not 046 * with Mac OS X. 047 */ 048 static { 049 ImageIO.scanForPlugins(); 050 } 051 /** 052 * List of ImageWriter objects. 053 * <p>ImagWriterFactory.properties says jpeg2000.J2KImageWriterCodecLib.</p> 054 */ 055 protected String[] writerCodecs = { 056 "com.sun.media.imageioimpl.plugins.jpeg.CLibJPEGImageWriter", 057 "com.sun.media.imageioimpl.plugins.jpeg2000.J2KImageWriter", 058 "com.sun.media.imageioimpl.plugins.jpeg2000.J2KImageWriterCodecLib" 059 }; 060 /** 061 * List of ImageReader objects. 062 * <p>ImageReaderFactory.properties says jpeg2000.J2KImageReaderCodecLib.</p> 063 * <p>jai_imageio has J2KImageReader and J2KImageReaderCodecLib.</p> 064 */ 065 protected String[] readerCodecs = { 066 "com.sun.media.imageioimpl.plugins.jpeg.CLibJPEGImageReader", 067 "com.sun.media.imageioimpl.plugins.jpeg2000.J2KImageReader", 068 "com.sun.media.imageioimpl.plugins.jpeg2000.J2KImageReaderCodecLib" 069 }; 070 /** 071 * Show information on an ImageReader codec. 072 * @param reader ImageReader object 073 * @param out destination for printing 074 */ 075 protected void printReader(ImageReader reader, PrintWriter out) { 076 out.println(reader.getClass().getName()); 077 ImageReadParam param = reader.getDefaultReadParam(); 078 out.println("<ol>"); 079 out.println("<p>" + param.getClass().getName() + "</p>"); 080 out.println("</ol>"); 081 } 082 /** 083 * Show information on an ImageWriter codec. 084 * @param writer ImageWriter object 085 * @param out destination for printing 086 */ 087 protected void printWriter(ImageWriter writer, PrintWriter out) { 088 String className = writer.getClass().getName(); 089 String resourceName = "/" + className.replaceAll("\\.", "/") + ".class"; 090 out.println("<p>" + writer.getClass().getName() + "</p>"); 091 out.println("<p>" + resourceName + "</p>"); 092 out.println("<ul>"); 093 out.println("<li>"); 094 URL url = writer.getClass().getResource(resourceName); 095 if (url==null) { 096 out.println("<p>null URL</p>"); 097 } else { 098 out.println("<p>" + url.toString() + "</p>"); 099 } 100 ClassLoader loader = writer.getClass().getClassLoader(); 101 if (loader == null) { 102 out.println("<p>System Class Loader<p>"); 103 try { 104 out.println("<p>" + writer.getClass().getResource(resourceName).toString() + "</p>"); 105 } catch (Exception e) { 106 out.println("<p>" + e.getMessage() + "</p>"); 107 } 108 } else { 109 out.println("<p>" + loader.getClass().getName() + "</p>"); 110 try { 111 URL url2 = loader.getResource(resourceName); 112 if (url2 == null) { 113 out.println("<p>Can't obtain resource URL</p>"); 114 } else { 115 out.println("<p>" + url2.toString() + "</p>"); 116 } 117 } catch (Exception e) { 118 out.println("<p>" + e.getMessage() + "</p>"); 119 } 120 } 121 out.println("</li>"); 122 ImageWriteParam param = writer.getDefaultWriteParam(); 123 out.println("<li>"); 124 boolean compressed = param.canWriteCompressed(); 125 out.println("<p>" + param.getClass().getName() + "</p>"); 126 out.println("<p>Codec can write compressed: " + Boolean.toString(compressed) +"</p>"); 127 if (compressed) { 128 out.println("<p>The types of compression are listed below:</p>"); 129 String[] types = param.getCompressionTypes(); 130 out.println("<ol>"); 131 for (int i2 = 0; i2 < types.length; i2++) { 132 out.println("<li><p>" + types[i2] + "</p>"); 133 out.println("</li>"); 134 } 135 out.println("</ol>"); 136 } 137 out.println("</li>"); 138 if (JPEGImageWriteParam.class.isAssignableFrom(param.getClass())) { 139 /* 140 * The default for compression quality value for JPEG appears to be 0.75. 141 * The standard codec can not handle lossless. 142 */ 143 out.println("<li>"); 144 int mode = param.getCompressionMode(); 145 param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT); 146 out.println("<p>Current quality is " + Float.toString(param.getCompressionQuality()) + "</p>"); 147 out.print("<p>Estimated compressed bit rate is "); 148 float estimate = param.getBitRate(param.getCompressionQuality()); 149 if (estimate < 0.0f) { 150 out.print("<i>estimate not available</i>"); 151 } else { 152 out.print(Float.toString(estimate)); 153 } 154 out.println("</p>"); 155 String[] descriptions = param.getCompressionQualityDescriptions(); 156 float[] values = param.getCompressionQualityValues(); 157 for (int i = 0; i < descriptions.length; i++) { 158 out.println("<p>" + descriptions[i] + " " + Float.toString(values[i]) + 159 " " + Float.toString(values[i+1]) + "</p>"); 160 } 161 param.setCompressionMode(mode); 162 out.println("</li>"); 163 } 164 out.println("<li>"); 165 ImageWriterSpi spi = writer.getOriginatingProvider(); 166 if (spi != null) { 167 out.println("<p>Spi class is " + spi.getClass().getName() + "</p>"); 168 out.println("<ol>"); 169 String[] list = spi.getFileSuffixes(); 170 if (list != null) { 171 out.print("<li>File suffixes are "); 172 for (int i = 0; i < list.length; i++) { 173 if (i > 0) { out.print(", "); } 174 out.print(list[i]); 175 } 176 out.println("</li>"); 177 } 178 list = spi.getFormatNames(); 179 if (list != null) { 180 out.print("<li>Format names are "); 181 for (int i = 0; i < list.length; i++) { 182 if (i > 0) { out.print(", "); } 183 out.print(list[i]); 184 } 185 out.println("</li>"); 186 } 187 list = spi.getMIMETypes(); 188 if (list != null) { 189 out.print("<li>MIME types are "); 190 for (int i = 0; i < list.length; i++) { 191 if (i > 0) { out.print(", "); } 192 out.print(list[i]); 193 } 194 out.println("</li>"); 195 } 196 out.println("</ol>"); 197 out.println("</li>"); 198 } 199 out.println("</ul>"); 200 } 201 /** 202 * Display information on image reader and writer codecs. 203 * @param out destination for listing 204 */ 205 protected void printInfo(PrintWriter out) { 206 out.println("<html><head>"); 207 out.println("<title>Codec Information</title>"); 208 out.println("</head><body>"); 209 Iterator<ImageReader> readerList = null; 210 out.println("<h1>ImageIO Reader Codecs</h1>"); 211 String[] mimeList = ImageIO.getReaderMIMETypes(); 212 for (int i = 0; i < mimeList.length; i++) { 213 if (mimeList[i] == null) { 214 out.println("<h2>blank name</h2>"); 215 } else if (mimeList[i].trim().length() == 0) { 216 out.println("<h2>blank name</h2>"); 217 } else { 218 out.println("<h2>" + mimeList[i] + "</h2>"); 219 } 220 readerList = ImageIO.getImageReadersByMIMEType(mimeList[i]); 221 out.println("<ul>"); 222 while (readerList.hasNext()) { 223 out.println("<li>"); 224 ImageReader reader = readerList.next(); 225 printReader(reader, out); 226 out.println("</li>"); 227 } 228 out.println("</ul>"); 229 } 230 out.println("<h1>ImageIO Writer Codecs</h1>"); 231 Iterator<ImageWriter> writerList = null; 232 for (int i = 0; i < mimeList.length; i++) { 233 if (mimeList[i] == null) { 234 out.println("<h2>blank name</h2>"); 235 } else if (mimeList[i].trim().length() == 0) { 236 out.println("<h2>blank name</h2>"); 237 } else { 238 out.println("<h2>" + mimeList[i] + "</h2>"); 239 } 240 writerList = ImageIO.getImageWritersByMIMEType(mimeList[i]); 241 out.println("<ul>"); 242 while (writerList.hasNext()) { 243 out.println("<li>"); 244 ImageWriter writer = writerList.next(); 245 printWriter(writer, out); 246 out.println("</li>"); 247 } 248 out.println("</ul>"); 249 } 250 out.println("<h1>ImageIO</h1>"); 251 ClassLoader imageLoader = javax.imageio.ImageIO.class.getClassLoader(); 252 if (imageLoader == null) { 253 out.println("<p>System class loader</p>"); 254 } else { 255 out.println("<p>Loader is " + imageLoader.getClass().getName() + "</p>"); 256 } 257 out.println("</body></html>"); 258 } 259 @Override 260 public void service(HttpServletRequest req, HttpServletResponse res) 261 throws IOException, ServletException { 262 PrintWriter out = res.getWriter(); 263 printInfo(out); 264 } 265 /** 266 * Test driver. 267 * @param args 268 */ 269 public static void main(String[] args) { 270 CodecInfo instance = new CodecInfo(); 271 StringWriter string = new StringWriter(); 272 PrintWriter out = new PrintWriter(string); 273 instance.printInfo(out); 274 System.out.println(string.toString()); 275 } 276 277}