You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@cocoon.apache.org by tc...@apache.org on 2002/12/31 17:25:44 UTC

cvs commit: xml-cocoon2/src/java/org/apache/cocoon/generation ImageDirectoryGenerator.java

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:balld@webslingerZ.com">Donald A. Ball Jr.</a>
  + * @author <a href="mailto:tcurdt@apache.org">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:     webmaster@xml.apache.org
To unsubscribe, e-mail:          cocoon-cvs-unsubscribe@xml.apache.org
For additional commands, e-mail: cocoon-cvs-help@xml.apache.org