tcurdt 2002/12/31 08:25:44 Modified: src/java/org/apache/cocoon/generation ImageDirectoryGenerator.java Log: major cleanup, removed the RuntimeExceptions, added support for the JPEG comment marker Revision Changes Path 1.7 +190 -90 xml-cocoon2/src/java/org/apache/cocoon/generation/ImageDirectoryGenerator.java Index: ImageDirectoryGenerator.java =================================================================== RCS file: /home/cvs/xml-cocoon2/src/java/org/apache/cocoon/generation/ImageDirectoryGenerator.java,v retrieving revision 1.6 retrieving revision 1.7 diff -u -r1.6 -r1.7 --- ImageDirectoryGenerator.java 21 Nov 2002 18:18:49 -0000 1.6 +++ ImageDirectoryGenerator.java 31 Dec 2002 16:25:44 -0000 1.7 @@ -61,12 +61,39 @@ * files. * * @author <a href="mailto:[EMAIL PROTECTED]">Donald A. Ball Jr.</a> + * @author <a href="mailto:[EMAIL PROTECTED]">Torsten Curdt</a> * @version CVS $Id$ */ -public class ImageDirectoryGenerator extends DirectoryGenerator { +final public class ImageDirectoryGenerator extends DirectoryGenerator { protected static String IMAGE_WIDTH_ATTR_NAME = "width"; protected static String IMAGE_HEIGHT_ATTR_NAME = "height"; + protected static String IMAGE_COMMENT_ATTR_NAME = "comment"; + + /** + * TODO: as long as the generator is pooled we could use a single instance to reduce object creations + * TODO: don't open the file twice + */ + final private class ImageProperties { + int width; + int height; + char[] comment; + + public ImageProperties(int width, int height, char[] comment) { + this.width = width; + this.height = height; + this.comment = comment; + } + + public String toString() { + StringBuffer sb = new StringBuffer(); + sb.append(width).append("x").append(height); + if (comment != null) { + sb.append(" (").append(comment).append(")"); + } + return (sb.toString()); + } + } /** * Extends the <code>setNodeAttributes</code> method from the @@ -79,137 +106,210 @@ return; } try { - int dim[] = getSize(path); - if (this.getLogger().isDebugEnabled()) { - this.getLogger().debug("getSize(path) = " + dim); - } - attributes.addAttribute("",IMAGE_WIDTH_ATTR_NAME,IMAGE_WIDTH_ATTR_NAME,"CDATA",String.valueOf(dim[0])); - attributes.addAttribute("",IMAGE_HEIGHT_ATTR_NAME,IMAGE_HEIGHT_ATTR_NAME,"CDATA",String.valueOf(dim[1])); - } catch (RuntimeException e) { - getLogger().debug("ImageDirectoryGenerator.setNodeAttributes", e); - } catch (Exception e) { + ImageProperties p = getImageProperties(path); + if (p != null) { + if (getLogger().isDebugEnabled()) { + getLogger().debug(String.valueOf(path) + " = " + String.valueOf(p)); + } + attributes.addAttribute("", IMAGE_WIDTH_ATTR_NAME, IMAGE_WIDTH_ATTR_NAME, "CDATA", String.valueOf(p.width)); + attributes.addAttribute("", IMAGE_HEIGHT_ATTR_NAME, IMAGE_HEIGHT_ATTR_NAME, "CDATA", String.valueOf(p.height)); + if (p.comment != null) attributes.addAttribute("", IMAGE_COMMENT_ATTR_NAME, IMAGE_COMMENT_ATTR_NAME, "CDATA", String.valueOf(p.comment)); + } + } + catch (FileNotFoundException e) { + throw new SAXException(e); + } + catch (IOException e) { throw new SAXException(e); } } - // returns width as first element, height as second - public static int[] getSize(File file) throws FileNotFoundException, IOException { + private ImageProperties getImageProperties(File file) throws FileNotFoundException, IOException { String type = getFileType(file); - try { - if(type.equals("gif")) return getGifSize(file); - else return getJpegSize(file); - } catch(Exception e) { - throw new CascadingRuntimeException("File is not a valid GIF or Jpeg", e); + if ("gif".equals(type)) { + return (getGifProperties(file)); + } + else if ("jpeg".equals(type)) { + return (getJpegProperties(file)); + } + else { + if (getLogger().isDebugEnabled()) { + getLogger().debug("cannot handle type " + type + ". not a known image"); + } + return (null); } - } - // returns width as first element, height as second - public static int[] getJpegSize(File file) throws FileNotFoundException, IOException { + private ImageProperties getJpegProperties(File file) throws FileNotFoundException, IOException { BufferedInputStream in = null; try { in = new BufferedInputStream(new FileInputStream(file)); // check for "magic" header byte[] buf = new byte[2]; int count = in.read(buf, 0, 2); - if(count < 2) throw new RuntimeException("Not a valid Jpeg file!"); - if((buf[0]) != (byte)0xFF - || (buf[1]) != (byte)0xD8 ) - throw new RuntimeException("Not a valid Jpeg file!"); + if (count < 2) { + if (getLogger().isErrorEnabled()) { + getLogger().error("Not a valid Jpeg file!"); + } + return (null); + } + if ((buf[0]) != (byte) 0xFF || (buf[1]) != (byte) 0xD8) { + if (getLogger().isErrorEnabled()) { + getLogger().error("Not a valid Jpeg file!"); + } + return (null); + } int width = 0; int height = 0; + char[] comment = null; - boolean done = false; + boolean hasDims = false; + boolean hasComment = false; int ch = 0; - try { - while(ch != 0xDA && !done) { - /* Find next marker (JPEG markers begin with 0xFF) */ - while (ch != 0xFF) { ch = in.read(); } - /* JPEG markers can be padded with unlimited 0xFF's */ - while (ch == 0xFF) { ch = in.read(); } - /* Now, ch contains the value of the marker. */ - if(ch >= 0xC0 && ch <= 0xC3) { - // skip 3 bytes - in.read(); - in.read(); - in.read(); - height = 256 * in.read(); - height += in.read(); - width = 256 * in.read(); - width += in.read(); - done = true; - } else { - /* We MUST skip variables, since FF's within variable names are NOT valid JPEG markers */ - int length = 256 * in.read(); - length += in.read(); - if(length < 2) throw new RuntimeException("Erroneous JPEG marker length"); - for(int foo = 0; foo<length-2; foo++) - in.read(); - } - } - } catch(Exception e) { - throw new RuntimeException("Not a valid Jpeg file!"); - } + while (ch != 0xDA && !(hasDims && hasComment)) { + /* Find next marker (JPEG markers begin with 0xFF) */ + while (ch != 0xFF) { + ch = in.read(); + } + /* JPEG markers can be padded with unlimited 0xFF's */ + while (ch == 0xFF) { + ch = in.read(); + } + /* Now, ch contains the value of the marker. */ + + int length = 256 * in.read(); + length += in.read(); + if (length < 2) { + if (getLogger().isErrorEnabled()) { + getLogger().error("Not a valid Jpeg file!"); + } + return (null); + } + /* Now, length contains the length of the marker. */ + + /* + if (getLogger().isDebugEnabled()) { + getLogger().debug("marker 0x" + Integer.toHexString(ch) + " len=" + length); + } + */ - int[] dim = { width, height }; - return dim; + if (ch >= 0xC0 && ch <= 0xC3) { + in.read(); + height = 256 * in.read(); + height += in.read(); + width = 256 * in.read(); + width += in.read(); + for (int foo = 0; foo < length - 2 - 5; foo++) { + int i = in.read(); + } + hasDims = true; + } + else if (ch == 0xFE) { + // that's the comment marker + comment = new char[length-2]; + for (int foo = 0; foo < length - 2; foo++) + comment[foo] = (char) in.read(); + hasComment = true; + } + else { + // just skip marker + for (int foo = 0; foo < length - 2; foo++) { + int i = in.read(); + } + } + } + return (new ImageProperties(width, height, comment)); - } finally { - if(in != null) try { in.close(); } catch(Exception e) {Hierarchy.getDefaultHierarchy().getLoggerFor("cocoon").debug("Close stream", e);} + } + finally { + if (in != null) { + try { + in.close(); + } + catch (IOException e) { + if (getLogger().isErrorEnabled()) { + getLogger().error("close stream", e); + } + } + } } } - // returns width as first element, height as second - public static int[] getGifSize(File file) throws FileNotFoundException, IOException { + private ImageProperties getGifProperties(File file) throws FileNotFoundException, IOException { BufferedInputStream in = null; try { in = new BufferedInputStream(new FileInputStream(file)); byte[] buf = new byte[10]; int count = in.read(buf, 0, 10); - if(count < 10) throw new RuntimeException("Not a valid GIF file!"); - if((buf[0]) != (byte)'G' - || (buf[1]) != (byte)'I' - || (buf[2]) != (byte)'F' ) - throw new RuntimeException("Not a valid GIF file!"); - - int w1 = ((int)buf[6] & 0xff) | (buf[6] & 0x80); - int w2 = ((int)buf[7] & 0xff) | (buf[7] & 0x80); - int h1 = ((int)buf[8] & 0xff) | (buf[8] & 0x80); - int h2 = ((int)buf[9] & 0xff) | (buf[9] & 0x80); + if (count < 10) { + if (getLogger().isErrorEnabled()) { + getLogger().error("Not a valid GIF file!"); + } + return (null); + } + if ((buf[0]) != (byte) 'G' || (buf[1]) != (byte) 'I' || (buf[2]) != (byte) 'F') { + if (getLogger().isErrorEnabled()) { + getLogger().error("Not a valid GIF file!"); + } + return (null); + } + + int w1 = ((int) buf[6] & 0xff) | (buf[6] & 0x80); + int w2 = ((int) buf[7] & 0xff) | (buf[7] & 0x80); + int h1 = ((int) buf[8] & 0xff) | (buf[8] & 0x80); + int h2 = ((int) buf[9] & 0xff) | (buf[9] & 0x80); int width = w1 + (w2 << 8); int height = h1 + (h2 << 8); - int[] dim = { width, height }; - return dim; + return (new ImageProperties(width, height, null)); - } finally { - if(in != null) try { in.close(); } catch(Exception e) {Hierarchy.getDefaultHierarchy().getLoggerFor("cocoon").debug("Close stream", e);} + } + finally { + if (in != null) { + try { + in.close(); + } + catch (IOException e) { + if (getLogger().isErrorEnabled()) { + getLogger().error("close stream", e); + } + } + } } } - // returns "gif", "jpeg" or NULL - public static String getFileType(File file) throws FileNotFoundException, IOException { + private String getFileType(File file) throws FileNotFoundException, IOException { BufferedInputStream in = null; try { in = new BufferedInputStream(new FileInputStream(file)); byte[] buf = new byte[3]; int count = in.read(buf, 0, 3); - if(count < 3) return null; - if((buf[0]) == (byte)'G' - && (buf[1]) == (byte)'I' - && (buf[2]) == (byte)'F' ) - return "gif"; - - if((buf[0]) == (byte)0xFF - && (buf[1]) == (byte)0xD8 ) - return "jpeg"; - - return null; - } finally { - if(in != null) try { in.close(); } catch(Exception e) {Hierarchy.getDefaultHierarchy().getLoggerFor("cocoon").debug("Close stream", e);} + + if (count < 3) + return (null); + + if ((buf[0]) == (byte) 'G' && (buf[1]) == (byte) 'I' && (buf[2]) == (byte) 'F') + return ("gif"); + + if ((buf[0]) == (byte) 0xFF && (buf[1]) == (byte) 0xD8) + return ("jpeg"); + + return (null); + } + finally { + if (in != null) { + try { + in.close(); + } + catch (IOException e) { + if (getLogger().isErrorEnabled()) { + getLogger().error("close stream", e); + } + } + } } } }
---------------------------------------------------------------------- In case of troubles, e-mail: [EMAIL PROTECTED] To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]