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 not used in this program
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}