Author: damjan
Date: Tue Feb 21 18:50:17 2012
New Revision: 1291956

URL: http://svn.apache.org/viewvc?rev=1291956&view=rev
Log:
Added support for reading the RGBE / Radiance HDR image format.

Submitted by: Peter Royal <proyal at apache dot org>
Jira issue key: SANSELAN-25


Added:
    
commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/rgbe/
    
commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/rgbe/InfoHeaderReader.java
   (with props)
    
commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/rgbe/RgbeConstants.java
   (with props)
    
commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/rgbe/RgbeImageParser.java
   (with props)
    
commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/rgbe/RgbeInfo.java
   (with props)
    commons/proper/sanselan/trunk/src/test/data/images/rgbe/
    commons/proper/sanselan/trunk/src/test/data/images/rgbe/1/
    
commons/proper/sanselan/trunk/src/test/data/images/rgbe/1/body_wave_N_0001.hdr  
 (with props)
    
commons/proper/sanselan/trunk/src/test/java/org/apache/commons/sanselan/formats/rgbe/
    
commons/proper/sanselan/trunk/src/test/java/org/apache/commons/sanselan/formats/rgbe/RgbeBaseTest.java
   (with props)
    
commons/proper/sanselan/trunk/src/test/java/org/apache/commons/sanselan/formats/rgbe/RgbeReadTest.java
   (with props)
Modified:
    commons/proper/sanselan/trunk/RELEASE_NOTES
    
commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/ImageFormat.java
    
commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/ImageParser.java
    
commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/Sanselan.java
    commons/proper/sanselan/trunk/src/site/xdoc/formatsupport.xml

Modified: commons/proper/sanselan/trunk/RELEASE_NOTES
URL: 
http://svn.apache.org/viewvc/commons/proper/sanselan/trunk/RELEASE_NOTES?rev=1291956&r1=1291955&r2=1291956&view=diff
==============================================================================
--- commons/proper/sanselan/trunk/RELEASE_NOTES (original)
+++ commons/proper/sanselan/trunk/RELEASE_NOTES Tue Feb 21 18:50:17 2012
@@ -44,6 +44,7 @@ Release 0.98
  * Altered TIFF tag searching to do an exact directory match when possible.
  * SANSELAN-48 - added support for reading and writing CCITT Modified Huffman, 
Group 3 and Group 4 images.
  * SANSELAN-31 - added a high level type-safe API for reading and writing EXIF 
fields.
+ * SANSELAN-25 - added support for the RGBE (Radiance HDR) image format.
 
 Release 0.97
 ------------

Modified: 
commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/ImageFormat.java
URL: 
http://svn.apache.org/viewvc/commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/ImageFormat.java?rev=1291956&r1=1291955&r2=1291956&view=diff
==============================================================================
--- 
commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/ImageFormat.java
 (original)
+++ 
commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/ImageFormat.java
 Tue Feb 21 18:50:17 2012
@@ -78,6 +78,8 @@ public class ImageFormat
     public static final ImageFormat IMAGE_FORMAT_DCX = new ImageFormat("DCX");
     public static final ImageFormat IMAGE_FORMAT_XBM = new ImageFormat("XBM");
     public static final ImageFormat IMAGE_FORMAT_XPM = new ImageFormat("XPM");
+    public static final ImageFormat IMAGE_FORMAT_RGBE = new 
ImageFormat("RGBE");
+
 
     public static final ImageFormat[] getAllFormats()
     {
@@ -88,7 +90,7 @@ public class ImageFormat
                 IMAGE_FORMAT_PPM, IMAGE_FORMAT_PNM, IMAGE_FORMAT_TGA,
                 IMAGE_FORMAT_JBIG2, IMAGE_FORMAT_ICNS, IMAGE_FORMAT_WBMP,
                 IMAGE_FORMAT_PCX, IMAGE_FORMAT_DCX, IMAGE_FORMAT_XBM,
-                IMAGE_FORMAT_XPM,
+                IMAGE_FORMAT_XPM, IMAGE_FORMAT_RGBE
         };
 
         return result;

Modified: 
commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/ImageParser.java
URL: 
http://svn.apache.org/viewvc/commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/ImageParser.java?rev=1291956&r1=1291955&r2=1291956&view=diff
==============================================================================
--- 
commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/ImageParser.java
 (original)
+++ 
commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/ImageParser.java
 Tue Feb 21 18:50:17 2012
@@ -44,6 +44,7 @@ import org.apache.commons.sanselan.forma
 import org.apache.commons.sanselan.formats.png.PngImageParser;
 import org.apache.commons.sanselan.formats.pnm.PnmImageParser;
 import org.apache.commons.sanselan.formats.psd.PsdImageParser;
+import org.apache.commons.sanselan.formats.rgbe.RgbeImageParser;
 import org.apache.commons.sanselan.formats.tiff.TiffImageParser;
 import org.apache.commons.sanselan.formats.wbmp.WbmpImageParser;
 import org.apache.commons.sanselan.formats.xbm.XbmImageParser;
@@ -63,6 +64,7 @@ public abstract class ImageParser extend
                 new IcnsImageParser(), new WbmpImageParser(),
                 new PcxImageParser(), new DcxImageParser(),
                 new XbmImageParser(), new XpmImageParser(),
+                new RgbeImageParser()
         // new JBig2ImageParser(),
         // new TgaImageParser(),
         };

Modified: 
commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/Sanselan.java
URL: 
http://svn.apache.org/viewvc/commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/Sanselan.java?rev=1291956&r1=1291955&r2=1291956&view=diff
==============================================================================
--- 
commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/Sanselan.java
 (original)
+++ 
commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/Sanselan.java
 Tue Feb 21 18:50:17 2012
@@ -150,7 +150,8 @@ public abstract class Sanselan implement
     private static final int[] MAGIC_NUMBERS_JBIG2_1 = { 0x97, 0x4A, };
     private static final int[] MAGIC_NUMBERS_JBIG2_2 = { 0x42, 0x32, };
     private static final int[] MAGIC_NUMBERS_ICNS = { 0x69, 0x63, };
-    private static final int[] MAGIC_NUMBERS_DCX = {0xB1, 0x68,};
+    private static final int[] MAGIC_NUMBERS_DCX = { 0xB1, 0x68, };
+    private static final int[] MAGIC_NUMBERS_RGBE = { 0x23, 0x3F, };
 
     private static boolean compareBytePair(int[] a, int b[]) {
         if (a.length != 2 && b.length != 2) {
@@ -224,6 +225,8 @@ public abstract class Sanselan implement
                 return ImageFormat.IMAGE_FORMAT_ICNS;
             } else if (compareBytePair(MAGIC_NUMBERS_DCX, bytePair)) {
                 return ImageFormat.IMAGE_FORMAT_DCX;
+            } else if (compareBytePair(MAGIC_NUMBERS_RGBE, bytePair)) {
+                return ImageFormat.IMAGE_FORMAT_RGBE;
             }
 
             return ImageFormat.IMAGE_FORMAT_UNKNOWN;

Added: 
commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/rgbe/InfoHeaderReader.java
URL: 
http://svn.apache.org/viewvc/commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/rgbe/InfoHeaderReader.java?rev=1291956&view=auto
==============================================================================
--- 
commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/rgbe/InfoHeaderReader.java
 (added)
+++ 
commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/rgbe/InfoHeaderReader.java
 Tue Feb 21 18:50:17 2012
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.sanselan.formats.rgbe;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+class InfoHeaderReader {
+    private final InputStream is;
+
+    public InfoHeaderReader( InputStream is ) {
+        this.is = is;
+    }
+
+    private char read() throws IOException {
+        int result = is.read();
+        if ( result < 0 ) {
+            throw new IOException( "HDR: Unexpected EOF" );
+        }
+        return (char) result;
+    }
+
+    public String readLine() throws IOException {
+        StringBuffer buffer = new StringBuffer();
+        char c;
+
+        while ( ( c = read() ) != '\n' ) {
+            buffer.append( c );
+        }
+
+        return buffer.toString();
+    }
+}
\ No newline at end of file

Propchange: 
commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/rgbe/InfoHeaderReader.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: 
commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/rgbe/RgbeConstants.java
URL: 
http://svn.apache.org/viewvc/commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/rgbe/RgbeConstants.java?rev=1291956&view=auto
==============================================================================
--- 
commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/rgbe/RgbeConstants.java
 (added)
+++ 
commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/rgbe/RgbeConstants.java
 Tue Feb 21 18:50:17 2012
@@ -0,0 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.sanselan.formats.rgbe;
+
+interface RgbeConstants {
+    // #?RADIANCE
+    byte[] HEADER = new byte[]{ 0x23, 0x3F, 0x52, 0x41, 0x44, 0x49, 0x41, 
0x4E, 0x43, 0x45 };
+}

Propchange: 
commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/rgbe/RgbeConstants.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: 
commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/rgbe/RgbeImageParser.java
URL: 
http://svn.apache.org/viewvc/commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/rgbe/RgbeImageParser.java?rev=1291956&view=auto
==============================================================================
--- 
commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/rgbe/RgbeImageParser.java
 (added)
+++ 
commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/rgbe/RgbeImageParser.java
 Tue Feb 21 18:50:17 2012
@@ -0,0 +1,154 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.sanselan.formats.rgbe;
+
+import java.awt.Dimension;
+import java.awt.Point;
+import java.awt.Transparency;
+import java.awt.color.ColorSpace;
+import java.awt.image.BandedSampleModel;
+import java.awt.image.BufferedImage;
+import java.awt.image.ComponentColorModel;
+import java.awt.image.DataBuffer;
+import java.awt.image.DataBufferFloat;
+import java.awt.image.Raster;
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Map;
+
+import org.apache.commons.sanselan.ImageFormat;
+import org.apache.commons.sanselan.ImageInfo;
+import org.apache.commons.sanselan.ImageParser;
+import org.apache.commons.sanselan.ImageReadException;
+import org.apache.commons.sanselan.common.BinaryConstants;
+import org.apache.commons.sanselan.common.IImageMetadata;
+import org.apache.commons.sanselan.common.bytesource.ByteSource;
+
+/**
+* Parser for Radiance HDR images
+*
+* @author <a href="mailto:pe...@electrotank.com";>peter royal</a>
+*/
+public class RgbeImageParser extends ImageParser {
+
+    public RgbeImageParser() {
+        setByteOrder( BinaryConstants.BYTE_ORDER_BIG_ENDIAN );
+    }
+
+    public String getName() {
+        return "Radiance HDR";
+    }
+
+    public String getDefaultExtension() {
+        return ".hdr";
+    }
+
+    protected String[] getAcceptedExtensions() {
+        return new String[]{ ".hdr", ".pic" };
+    }
+
+    protected ImageFormat[] getAcceptedTypes() {
+        return new ImageFormat[]{ ImageFormat.IMAGE_FORMAT_RGBE };
+    }
+
+    public IImageMetadata getMetadata( ByteSource byteSource, Map params ) 
throws ImageReadException, IOException {
+        RgbeInfo info = new RgbeInfo( byteSource );
+
+        try {
+            return info.getMetadata();
+        } finally {
+            info.close();
+        }
+    }
+
+    public ImageInfo getImageInfo( ByteSource byteSource, Map params ) throws 
ImageReadException, IOException {
+        RgbeInfo info = new RgbeInfo( byteSource );
+
+        try {
+            return new ImageInfo( getName(),
+                                  32, // todo may be 64 if double?
+                                  new ArrayList(),
+                                  ImageFormat.IMAGE_FORMAT_RGBE,
+                                  getName(),
+                                  info.getHeight(),
+                                  "image/vnd.radiance",
+                                  1,
+                                  -1,
+                                  -1,
+                                  -1,
+                                  -1,
+                                  info.getWidth(),
+                                  false,
+                                  false,
+                                  false,
+                                  ImageInfo.COLOR_TYPE_RGB,
+                                  "Adaptive RLE" );
+        } finally {
+            info.close();
+        }
+    }
+
+    public BufferedImage getBufferedImage( ByteSource byteSource, Map params ) 
throws ImageReadException, IOException {
+        RgbeInfo info = new RgbeInfo( byteSource );
+
+        try {
+            // It is necessary to create our own BufferedImage here as the
+            // org.apache.sanselan.common.IBufferedImageFactory interface does 
not expose this complexity
+            DataBuffer buffer = new DataBufferFloat( info.getPixelData(), 
info.getWidth() * info.getHeight() );
+
+            return new BufferedImage(
+                new ComponentColorModel( ColorSpace.getInstance( 
ColorSpace.CS_sRGB ),
+                                         false,
+                                         false,
+                                         Transparency.OPAQUE,
+                                         buffer.getDataType() ),
+                Raster.createWritableRaster( new BandedSampleModel( 
buffer.getDataType(),
+                                                                    
info.getWidth(),
+                                                                    
info.getHeight(),
+                                                                    3 ),
+                                             buffer,
+                                             new Point() ),
+                false,
+                null );
+        } finally {
+            info.close();
+        }
+    }
+
+    public Dimension getImageSize( ByteSource byteSource, Map params ) throws 
ImageReadException, IOException {
+        RgbeInfo info = new RgbeInfo( byteSource );
+
+        try {
+            return new Dimension( info.getWidth(), info.getHeight() );
+        } finally {
+            info.close();
+        }
+    }
+
+    public byte[] getICCProfileBytes( ByteSource byteSource, Map params ) 
throws ImageReadException, IOException {
+        return null;
+    }
+
+    public boolean embedICCProfile( File src, File dst, byte[] profile ) {
+        return false;
+    }
+
+    public String getXmpXml( ByteSource byteSource, Map params ) throws 
ImageReadException, IOException {
+        return null;
+    }
+}
\ No newline at end of file

Propchange: 
commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/rgbe/RgbeImageParser.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: 
commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/rgbe/RgbeInfo.java
URL: 
http://svn.apache.org/viewvc/commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/rgbe/RgbeInfo.java?rev=1291956&view=auto
==============================================================================
--- 
commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/rgbe/RgbeInfo.java
 (added)
+++ 
commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/rgbe/RgbeInfo.java
 Tue Feb 21 18:50:17 2012
@@ -0,0 +1,190 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.sanselan.formats.rgbe;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.commons.sanselan.ImageReadException;
+import org.apache.commons.sanselan.common.BinaryConstants;
+import org.apache.commons.sanselan.common.BinaryFileFunctions;
+import org.apache.commons.sanselan.common.BinaryInputStream;
+import org.apache.commons.sanselan.common.IImageMetadata;
+import org.apache.commons.sanselan.common.ImageMetadata;
+import org.apache.commons.sanselan.common.bytesource.ByteSource;
+import org.apache.commons.sanselan.util.Debug;
+
+class RgbeInfo extends BinaryFileFunctions {
+    private static final Pattern RESOLUTION_STRING = Pattern.compile( "-Y 
(\\d+) \\+X (\\d+)" );
+
+    private final BinaryInputStream in;
+    private ImageMetadata metadata;
+    private int width = -1;
+    private int height = -1;
+    private static final byte[] TWO_TWO = new byte[]{ 0x2, 0x2 };
+
+    RgbeInfo( ByteSource byteSource ) throws IOException {
+        this.in = new BinaryInputStream( byteSource.getInputStream(), 
BinaryConstants.BYTE_ORDER_BIG_ENDIAN );
+    }
+
+    IImageMetadata getMetadata() throws IOException, ImageReadException {
+        if ( null == metadata ) {
+            readMetadata();
+        }
+
+        return metadata;
+    }
+
+    int getWidth() throws IOException, ImageReadException {
+        if ( -1 == width ) {
+            readDimensions();
+        }
+
+        return width;
+    }
+
+    int getHeight() throws IOException, ImageReadException {
+        if ( -1 == height ) {
+            readDimensions();
+        }
+
+        return height;
+    }
+
+    void close() {
+        try {
+            in.close();
+        } catch( IOException e ) {
+            Debug.debug( e );
+        }
+    }
+
+    private void readDimensions() throws IOException, ImageReadException {
+        getMetadata(); // Ensure we've read past this
+
+        InfoHeaderReader reader = new InfoHeaderReader( in );
+        String resolution = reader.readLine();
+        Matcher matcher = RESOLUTION_STRING.matcher( resolution );
+
+        if ( !matcher.matches() ) {
+            throw new ImageReadException(
+                "Invalid HDR resolution string. Only \"-Y N +X M\" is 
supported. Found \"" + resolution + "\"" );
+        }
+
+        height = Integer.parseInt( matcher.group( 1 ) );
+        width = Integer.parseInt( matcher.group( 2 ) );
+    }
+
+    private void readMetadata() throws IOException, ImageReadException {
+        in.readAndVerifyBytes( RgbeConstants.HEADER, "Not a valid HDR: 
Incorrect Header" );
+
+        InfoHeaderReader reader = new InfoHeaderReader( in );
+
+        if ( reader.readLine().length() != 0 ) {
+            throw new ImageReadException( "Not a valid HDR: Incorrect Header" 
);
+        }
+
+        metadata = new ImageMetadata();
+
+        String info = reader.readLine();
+
+        while ( info.length() != 0 ) {
+            int equals = info.indexOf( "=" );
+
+            if ( equals > 0 ) {
+                String variable = info.substring( 0, equals );
+                String value = info.substring( equals + 1 );
+
+                if ( "FORMAT".equals( value ) ) {
+                    if ( !"32-bit_rle_rgbe".equals( value ) ) {
+                        throw new ImageReadException(
+                            "Only 32-bit_rle_rgbe images are supported, trying 
to read " + value );
+                    }
+                }
+
+                metadata.add( variable, value );
+            } else {
+                metadata.add( "<command>", info );
+            }
+
+            info = reader.readLine();
+        }
+    }
+
+    public float[][] getPixelData() throws IOException, ImageReadException {
+        // Read into local variables to ensure that we have seeked into the 
file far enough
+        int height = getHeight();
+        int width = getWidth();
+
+        if ( width >= 32768 ) {
+            throw new ImageReadException( "Scan lines must be less than 32768 
bytes long" );
+        }
+
+        byte[] scanLineBytes = convertShortToByteArray( width, 
BinaryConstants.BYTE_ORDER_BIG_ENDIAN );
+        byte[] rgbe = new byte[width * 4];
+        float[][] out = new float[3][width * height];
+
+        for ( int i = 0; i < height; i++ ) {
+            in.readAndVerifyBytes( TWO_TWO, "Scan line " + i + " expected to 
start with 0x2 0x2" );
+            in.readAndVerifyBytes( scanLineBytes, "Scan line " + i + " length 
expected" );
+
+            decompress( in, rgbe );
+
+            for ( int channel = 0; channel < 3; channel++ ) {
+                int channelOffset = channel * width;
+                int eOffset = 3 * width;
+
+                for ( int p = 0; p < width; p++ ) {
+                    int mantissa = rgbe[p + eOffset] & 0xff;
+                    int pos = p + i * width;
+
+                    if ( 0 == mantissa ) {
+                        out[channel][pos] = 0;
+                    } else {
+                        float mult = (float) Math.pow( 2, mantissa - ( 128 + 8 
) );
+                        out[channel][pos] = ( ( rgbe[p + channelOffset] & 0xff 
) + 0.5f ) * mult;
+                    }
+                }
+            }
+        }
+
+        return out;
+    }
+
+    private static void decompress( InputStream in, byte[] out ) throws 
IOException {
+        int position = 0;
+        int total = out.length;
+
+        while ( position < total ) {
+            int n = in.read();
+
+            if ( n > 128 ) {
+                int value = in.read();
+
+                for ( int i = 0; i < ( n & 0x7f ); i++ ) {
+                    out[position++] = (byte) value;
+                }
+            } else {
+                for ( int i = 0; i < n; i++ ) {
+                    out[position++] = (byte) in.read();
+                }
+            }
+        }
+    }
+}
\ No newline at end of file

Propchange: 
commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/rgbe/RgbeInfo.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: commons/proper/sanselan/trunk/src/site/xdoc/formatsupport.xml
URL: 
http://svn.apache.org/viewvc/commons/proper/sanselan/trunk/src/site/xdoc/formatsupport.xml?rev=1291956&r1=1291955&r2=1291956&view=diff
==============================================================================
--- commons/proper/sanselan/trunk/src/site/xdoc/formatsupport.xml (original)
+++ commons/proper/sanselan/trunk/src/site/xdoc/formatsupport.xml Tue Feb 21 
18:50:17 2012
@@ -153,6 +153,17 @@ limitations under the License.
     </td>
   </tr>
 
+  <!-- RGBE/Radiance HDR Format -->
+  <tr>
+    <td>RGBE/Radiance HDR</td><td>yes</td><td>no</td>
+    <td>
+        Basic support.
+    </td>
+    <td>
+      <a href="http://en.wikipedia.org/wiki/RGBE_image_format";>Wikipedia</a>
+    </td>
+  </tr>
+
   <!-- TIFF Format -->
   <tr>
     <td>TIFF</td><td>yes</td><td>yes</td>
@@ -244,7 +255,7 @@ limitations under the License.
   <tr>
     <td>JPEG/JFIF IPTC Metadata</td><td>yes</td><td>soon</td>
     <td>
-        Can read IPTC data from exsiting JPEG/JFIF files WITHOUT modifying 
image data.
+        Can read IPTC data from existing JPEG/JFIF files WITHOUT modifying 
image data.
     </td>
     <td>
        <a href="http://www.iptc.org/cms/site/index.html?channel=CH0108";>IPTC 
Specs, etc.</a>

Added: 
commons/proper/sanselan/trunk/src/test/data/images/rgbe/1/body_wave_N_0001.hdr
URL: 
http://svn.apache.org/viewvc/commons/proper/sanselan/trunk/src/test/data/images/rgbe/1/body_wave_N_0001.hdr?rev=1291956&view=auto
==============================================================================
Binary file - no diff available.

Propchange: 
commons/proper/sanselan/trunk/src/test/data/images/rgbe/1/body_wave_N_0001.hdr
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: 
commons/proper/sanselan/trunk/src/test/java/org/apache/commons/sanselan/formats/rgbe/RgbeBaseTest.java
URL: 
http://svn.apache.org/viewvc/commons/proper/sanselan/trunk/src/test/java/org/apache/commons/sanselan/formats/rgbe/RgbeBaseTest.java?rev=1291956&view=auto
==============================================================================
--- 
commons/proper/sanselan/trunk/src/test/java/org/apache/commons/sanselan/formats/rgbe/RgbeBaseTest.java
 (added)
+++ 
commons/proper/sanselan/trunk/src/test/java/org/apache/commons/sanselan/formats/rgbe/RgbeBaseTest.java
 Tue Feb 21 18:50:17 2012
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.sanselan.formats.rgbe;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+
+import org.apache.commons.sanselan.ImageFormat;
+import org.apache.commons.sanselan.ImageReadException;
+import org.apache.commons.sanselan.Sanselan;
+import org.apache.commons.sanselan.SanselanTest;
+
+public abstract class RgbeBaseTest extends SanselanTest {
+    private static boolean isRgbe( File file ) throws IOException,
+                                                     ImageReadException
+    {
+        ImageFormat format = Sanselan.guessFormat( file );
+        return format == ImageFormat.IMAGE_FORMAT_RGBE;
+    }
+
+    private static final ImageFilter IMAGE_FILTER = new ImageFilter() {
+        public boolean accept( File file ) throws IOException, 
ImageReadException {
+            return isRgbe( file );
+        }
+    };
+
+    protected List getRgbeImages() throws IOException, ImageReadException {
+        return getTestImages( IMAGE_FILTER );
+    }
+}
\ No newline at end of file

Propchange: 
commons/proper/sanselan/trunk/src/test/java/org/apache/commons/sanselan/formats/rgbe/RgbeBaseTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: 
commons/proper/sanselan/trunk/src/test/java/org/apache/commons/sanselan/formats/rgbe/RgbeReadTest.java
URL: 
http://svn.apache.org/viewvc/commons/proper/sanselan/trunk/src/test/java/org/apache/commons/sanselan/formats/rgbe/RgbeReadTest.java?rev=1291956&view=auto
==============================================================================
--- 
commons/proper/sanselan/trunk/src/test/java/org/apache/commons/sanselan/formats/rgbe/RgbeReadTest.java
 (added)
+++ 
commons/proper/sanselan/trunk/src/test/java/org/apache/commons/sanselan/formats/rgbe/RgbeReadTest.java
 Tue Feb 21 18:50:17 2012
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.sanselan.formats.rgbe;
+
+import java.awt.image.BufferedImage;
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+
+import org.apache.commons.sanselan.ImageInfo;
+import org.apache.commons.sanselan.ImageReadException;
+import org.apache.commons.sanselan.ImageWriteException;
+import org.apache.commons.sanselan.Sanselan;
+import org.apache.commons.sanselan.common.IImageMetadata;
+import org.apache.commons.sanselan.util.Debug;
+
+public class RgbeReadTest extends RgbeBaseTest {
+    public void test() throws IOException, ImageReadException,
+                              ImageWriteException
+    {
+        Debug.debug( "start" );
+
+        List images = getRgbeImages();
+
+        for ( int i = 0; i < images.size(); i++ ) {
+            if ( i % 10 == 0 ) {
+                Debug.purgeMemory();
+            }
+
+            File imageFile = (File) images.get( i );
+            Debug.debug( "imageFile", imageFile );
+
+            IImageMetadata metadata = Sanselan.getMetadata( imageFile );
+            assertNotNull(metadata);
+
+            ImageInfo imageInfo = Sanselan.getImageInfo( imageFile );
+            assertNotNull( imageInfo );
+
+            BufferedImage image = Sanselan.getBufferedImage( imageFile );
+            assertNotNull( image );
+        }
+    }
+}
\ No newline at end of file

Propchange: 
commons/proper/sanselan/trunk/src/test/java/org/apache/commons/sanselan/formats/rgbe/RgbeReadTest.java
------------------------------------------------------------------------------
    svn:eol-style = native


Reply via email to