diff --git a/src/java/org/apache/poi/ddf/EscherBlipRecord.java b/src/java/org/apache/poi/ddf/EscherBlipRecord.java index d50a6eb93..43d90141a 100644 --- a/src/java/org/apache/poi/ddf/EscherBlipRecord.java +++ b/src/java/org/apache/poi/ddf/EscherBlipRecord.java @@ -1,5 +1,6 @@ + /* ==================================================================== - Copyright 2004 Apache Software Foundation + Copyright 2002-2004 Apache Software Foundation Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -13,26 +14,17 @@ See the License for the specific language governing permissions and limitations under the License. ==================================================================== */ + package org.apache.poi.ddf; -import org.apache.poi.hssf.record.RecordFormatException; -import org.apache.poi.util.HexDump; import org.apache.poi.util.LittleEndian; +import org.apache.poi.util.HexDump; -import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; -import java.io.InputStream; -import java.io.IOException; -import java.util.zip.InflaterInputStream; -import java.util.zip.DeflaterOutputStream; /** - * The blip record is used to hold details about large binary objects that occur in escher such - * as JPEG, GIF, PICT and WMF files. The contents of the stream is usually compressed. Inflate - * can be used to decompress the data. - * * @author Glen Stampoultzis - * @see java.util.zip.Inflater + * @version $Id$ */ public class EscherBlipRecord extends EscherRecord @@ -40,21 +32,14 @@ public class EscherBlipRecord public static final short RECORD_ID_START = (short) 0xF018; public static final short RECORD_ID_END = (short) 0xF117; public static final String RECORD_DESCRIPTION = "msofbtBlip"; + private static final int HEADER_SIZE = 8; - private byte[] field_1_secondaryUID; - private int field_2_cacheOfSize; - private int field_3_boundaryTop; - private int field_4_boundaryLeft; - private int field_5_boundaryWidth; - private int field_6_boundaryHeight; - private int field_7_width; - private int field_8_height; - private int field_9_cacheOfSavedSize; - private byte field_10_compressionFlag; - private byte field_11_filter; - private byte[] field_12_data; + protected byte[] field_pictureData; + public EscherBlipRecord() + { + } /** * This method deserializes the record from a byte array. @@ -64,44 +49,27 @@ public class EscherBlipRecord * @param recordFactory May be null since this is not a container record. * @return The number of bytes read from the byte array. */ - public int fillFields( byte[] data, int offset, - EscherRecordFactory recordFactory - ) + public int fillFields( byte[] data, int offset, EscherRecordFactory recordFactory ) { int bytesAfterHeader = readHeader( data, offset ); int pos = offset + HEADER_SIZE; - int size = 0; - field_1_secondaryUID = new byte[16]; - System.arraycopy( data, pos + size, field_1_secondaryUID, 0, 16 ); size += 16; - field_2_cacheOfSize = LittleEndian.getInt( data, pos + size );size+=4; - field_3_boundaryTop = LittleEndian.getInt( data, pos + size );size+=4; - field_4_boundaryLeft = LittleEndian.getInt( data, pos + size );size+=4; - field_5_boundaryWidth = LittleEndian.getInt( data, pos + size );size+=4; - field_6_boundaryHeight = LittleEndian.getInt( data, pos + size );size+=4; - field_7_width = LittleEndian.getInt( data, pos + size );size+=4; - field_8_height = LittleEndian.getInt( data, pos + size );size+=4; - field_9_cacheOfSavedSize = LittleEndian.getInt( data, pos + size );size+=4; - field_10_compressionFlag = data[pos + size]; size++; - field_11_filter = data[pos + size]; size++; + field_pictureData = new byte[bytesAfterHeader]; + System.arraycopy(data, pos, field_pictureData, 0, bytesAfterHeader); - int bytesRemaining = bytesAfterHeader - size; - field_12_data = new byte[bytesRemaining]; - System.arraycopy(data, pos + size, field_12_data, 0, bytesRemaining); - - return bytesRemaining + HEADER_SIZE + bytesAfterHeader; + return bytesAfterHeader + 8; } - /** - * This method serializes this escher record into a byte array. + * Serializes the record to an existing byte array. * - * @param offset The offset into data to start writing the record data to. - * @param data The byte array to serialize to. - * @param listener A listener to retrieve start and end callbacks. Use a NullEscherSerailizationListener to ignore these events. - * @return The number of bytes written. - * - * @see NullEscherSerializationListener + * @param offset the offset within the byte array + * @param data the data array to serialize to + * @param listener a listener for begin and end serialization events. This + * is useful because the serialization is + * hierarchical/recursive and sometimes you need to be able + * break into that. + * @return the number of bytes written. */ public int serialize( int offset, byte[] data, EscherSerializationListener listener ) { @@ -109,25 +77,11 @@ public class EscherBlipRecord LittleEndian.putShort( data, offset, getOptions() ); LittleEndian.putShort( data, offset + 2, getRecordId() ); - int remainingBytes = field_12_data.length + 36; - LittleEndian.putInt( data, offset + 4, remainingBytes ); - int pos = offset + HEADER_SIZE; - System.arraycopy(field_1_secondaryUID, 0, data, pos, 16 ); pos += 16; - LittleEndian.putInt( data, pos, field_2_cacheOfSize); pos += 4; - LittleEndian.putInt( data, pos, field_3_boundaryTop); pos += 4; - LittleEndian.putInt( data, pos, field_4_boundaryLeft); pos += 4; - LittleEndian.putInt( data, pos, field_5_boundaryWidth); pos += 4; - LittleEndian.putInt( data, pos, field_6_boundaryHeight); pos += 4; - LittleEndian.putInt( data, pos, field_7_width); pos += 4; - LittleEndian.putInt( data, pos, field_8_height); pos += 4; - LittleEndian.putInt( data, pos, field_9_cacheOfSavedSize); pos += 4; - data[pos++] = field_10_compressionFlag; - data[pos++] = field_11_filter; - System.arraycopy(field_12_data, 0, data, pos, field_12_data.length); pos += field_12_data.length; + System.arraycopy( field_pictureData, 0, data, offset + 4, field_pictureData.length ); - listener.afterRecordSerialize(pos, getRecordId(), pos - offset, this); - return pos - offset; + listener.afterRecordSerialize(offset + 4 + field_pictureData.length, getRecordId(), field_pictureData.length + 4, this); + return field_pictureData.length + 4; } /** @@ -137,7 +91,7 @@ public class EscherBlipRecord */ public int getRecordSize() { - return 58 + field_12_data.length; + return field_pictureData.length + 4; } /** @@ -148,203 +102,6 @@ public class EscherBlipRecord return "Blip"; } - /** - * Retrieve the secondary UID - */ - public byte[] getSecondaryUID() - { - return field_1_secondaryUID; - } - - /** - * Set the secondary UID - */ - public void setSecondaryUID( byte[] field_1_secondaryUID ) - { - this.field_1_secondaryUID = field_1_secondaryUID; - } - - /** - * Retrieve the cache of the metafile size - */ - public int getCacheOfSize() - { - return field_2_cacheOfSize; - } - - /** - * Set the cache of the metafile size - */ - public void setCacheOfSize( int field_2_cacheOfSize ) - { - this.field_2_cacheOfSize = field_2_cacheOfSize; - } - - /** - * Retrieve the top boundary of the metafile drawing commands - */ - public int getBoundaryTop() - { - return field_3_boundaryTop; - } - - /** - * Set the top boundary of the metafile drawing commands - */ - public void setBoundaryTop( int field_3_boundaryTop ) - { - this.field_3_boundaryTop = field_3_boundaryTop; - } - - /** - * Retrieve the left boundary of the metafile drawing commands - */ - public int getBoundaryLeft() - { - return field_4_boundaryLeft; - } - - /** - * Set the left boundary of the metafile drawing commands - */ - public void setBoundaryLeft( int field_4_boundaryLeft ) - { - this.field_4_boundaryLeft = field_4_boundaryLeft; - } - - /** - * Retrieve the boundary width of the metafile drawing commands - */ - public int getBoundaryWidth() - { - return field_5_boundaryWidth; - } - - /** - * Set the boundary width of the metafile drawing commands - */ - public void setBoundaryWidth( int field_5_boundaryWidth ) - { - this.field_5_boundaryWidth = field_5_boundaryWidth; - } - - /** - * Retrieve the boundary height of the metafile drawing commands - */ - public int getBoundaryHeight() - { - return field_6_boundaryHeight; - } - - /** - * Set the boundary height of the metafile drawing commands - */ - public void setBoundaryHeight( int field_6_boundaryHeight ) - { - this.field_6_boundaryHeight = field_6_boundaryHeight; - } - - /** - * Retrieve the width of the metafile in EMU's (English Metric Units). - */ - public int getWidth() - { - return field_7_width; - } - - /** - * Set the width of the metafile in EMU's (English Metric Units). - */ - public void setWidth( int width ) - { - this.field_7_width = width; - } - - /** - * Retrieve the height of the metafile in EMU's (English Metric Units). - */ - public int getHeight() - { - return field_8_height; - } - - /** - * Set the height of the metafile in EMU's (English Metric Units). - */ - public void setHeight( int height ) - { - this.field_8_height = height; - } - - /** - * Retrieve the cache of the saved size - */ - public int getCacheOfSavedSize() - { - return field_9_cacheOfSavedSize; - } - - /** - * Set the cache of the saved size - */ - public void setCacheOfSavedSize( int field_9_cacheOfSavedSize ) - { - this.field_9_cacheOfSavedSize = field_9_cacheOfSavedSize; - } - - /** - * Is the contents of the blip compressed? - */ - public byte getCompressionFlag() - { - return field_10_compressionFlag; - } - - /** - * Set whether the contents of the blip is compressed - */ - public void setCompressionFlag( byte field_10_compressionFlag ) - { - this.field_10_compressionFlag = field_10_compressionFlag; - } - - /** - * Filter should always be 0 - */ - public byte getFilter() - { - return field_11_filter; - } - - /** - * Filter should always be 0 - */ - public void setFilter( byte field_11_filter ) - { - this.field_11_filter = field_11_filter; - } - - /** - * The BLIP data - */ - public byte[] getData() - { - return field_12_data; - } - - /** - * The BLIP data - */ - public void setData( byte[] field_12_data ) - { - this.field_12_data = field_12_data; - } - - /** - * The string representation of this record. - * - * @return A string - */ public String toString() { String nl = System.getProperty( "line.separator" ); @@ -353,7 +110,7 @@ public class EscherBlipRecord ByteArrayOutputStream b = new ByteArrayOutputStream(); try { - HexDump.dump( this.field_12_data, 0, b, 0 ); + HexDump.dump( this.field_pictureData, 0, b, 0 ); extraData = b.toString(); } catch ( Exception e ) @@ -363,70 +120,7 @@ public class EscherBlipRecord return getClass().getName() + ":" + nl + " RecordId: 0x" + HexDump.toHex( getRecordId() ) + nl + " Options: 0x" + HexDump.toHex( getOptions() ) + nl + - " Secondary UID: " + HexDump.toHex( field_1_secondaryUID ) + nl + - " CacheOfSize: " + field_2_cacheOfSize + nl + - " BoundaryTop: " + field_3_boundaryTop + nl + - " BoundaryLeft: " + field_4_boundaryLeft + nl + - " BoundaryWidth: " + field_5_boundaryWidth + nl + - " BoundaryHeight: " + field_6_boundaryHeight + nl + - " X: " + field_7_width + nl + - " Y: " + field_8_height + nl + - " CacheOfSavedSize: " + field_9_cacheOfSavedSize + nl + - " CompressionFlag: " + field_10_compressionFlag + nl + - " Filter: " + field_11_filter + nl + - " Data:" + nl + extraData; + " Extra Data:" + nl + extraData; + } - - /** - * Compress the contents of the provided array - * - * @param data An uncompressed byte array - * @see DeflaterOutputStream#write(int b) - */ - public static byte[] compress( byte[] data ) - { - ByteArrayOutputStream out = new ByteArrayOutputStream(); - DeflaterOutputStream deflaterOutputStream = new DeflaterOutputStream( out ); - try - { - for ( int i = 0; i < data.length; i++ ) - deflaterOutputStream.write( data[i] ); - } - catch ( IOException e ) - { - throw new RecordFormatException( e.toString() ); - } - - return out.toByteArray(); - } - - /** - * Decompresses a byte array. - * - * @param data The compressed byte array - * @param pos The starting position into the byte array - * @param length The number of compressed bytes to decompress - * @return An uncompressed byte array - * @see InflaterInputStream#read - */ - public static byte[] decompress( byte[] data, int pos, int length ) - { - byte[] compressedData = new byte[length]; - System.arraycopy( data, pos + 50, compressedData, 0, length ); - InputStream compressedInputStream = new ByteArrayInputStream( compressedData ); - InflaterInputStream inflaterInputStream = new InflaterInputStream( compressedInputStream ); - ByteArrayOutputStream out = new ByteArrayOutputStream(); - int c; - try - { - while ( ( c = inflaterInputStream.read() ) != -1 ) - out.write( c ); - } - catch ( IOException e ) - { - throw new RecordFormatException( e.toString() ); - } - return out.toByteArray(); - } - } diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFSimpleShape.java b/src/java/org/apache/poi/hssf/usermodel/HSSFSimpleShape.java index 9969cdcda..3adaff9f8 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFSimpleShape.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFSimpleShape.java @@ -34,7 +34,7 @@ public class HSSFSimpleShape // public final static short OBJECT_TYPE_CHART = 5; // public final static short OBJECT_TYPE_TEXT = 6; // public final static short OBJECT_TYPE_BUTTON = 7; -// public final static short OBJECT_TYPE_PICTURE = 8; + public final static short OBJECT_TYPE_PICTURE = 8; // public final static short OBJECT_TYPE_POLYGON = 9; // public final static short OBJECT_TYPE_CHECKBOX = 11; // public final static short OBJECT_TYPE_OPTION_BUTTON = 12; @@ -63,6 +63,7 @@ public class HSSFSimpleShape * @see #OBJECT_TYPE_LINE * @see #OBJECT_TYPE_OVAL * @see #OBJECT_TYPE_RECTANGLE + * @see #OBJECT_TYPE_PICTURE */ public int getShapeType() { return shapeType; } @@ -74,6 +75,7 @@ public class HSSFSimpleShape * @see #OBJECT_TYPE_LINE * @see #OBJECT_TYPE_OVAL * @see #OBJECT_TYPE_RECTANGLE + * @see #OBJECT_TYPE_PICTURE */ public void setShapeType( int shapeType ){ this.shapeType = shapeType; } diff --git a/src/testcases/org/apache/poi/ddf/TestEscherBlipRecord.java b/src/testcases/org/apache/poi/ddf/TestEscherBlipRecord.java deleted file mode 100644 index 2a072d0da..000000000 --- a/src/testcases/org/apache/poi/ddf/TestEscherBlipRecord.java +++ /dev/null @@ -1,126 +0,0 @@ -/* ==================================================================== - Copyright 2003-2004 Apache Software Foundation - - Licensed 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.poi.ddf; - -import junit.framework.TestCase; -import org.apache.poi.util.HexDump; -import org.apache.poi.util.HexRead; - -public class TestEscherBlipRecord extends TestCase -{ - private String dataStr; - private byte[] data; - - protected void setUp() throws Exception - { - dataStr = "2C 15 18 F0 34 00 00 00 01 01 01 01 01 01 01 01 " + - "01 01 01 01 01 01 01 01 06 00 00 00 03 00 00 00 " + - "01 00 00 00 04 00 00 00 02 00 00 00 0A 00 00 00 " + - "0B 00 00 00 05 00 00 00 08 07 01 02"; - data = HexRead.readFromString(dataStr); - } - - public void testSerialize() throws Exception - { - EscherBlipRecord r = new EscherBlipRecord(); - r.setBoundaryLeft(1); - r.setBoundaryHeight(2); - r.setBoundaryTop(3); - r.setBoundaryWidth(4); - r.setCacheOfSavedSize(5); - r.setCacheOfSize(6); - r.setFilter((byte)7); - r.setCompressionFlag((byte)8); - r.setSecondaryUID(new byte[] { (byte)0x01, (byte)0x01, (byte)0x01, (byte)0x01, - (byte)0x01, (byte)0x01, (byte)0x01, (byte)0x01, - (byte)0x01, (byte)0x01, (byte)0x01, (byte)0x01, - (byte)0x01, (byte)0x01, (byte)0x01, (byte)0x01, }); - r.setWidth(10); - r.setHeight(11); - r.setRecordId(EscherBlipRecord.RECORD_ID_START); - r.setOptions((short)5420); - r.setData(new byte[] { (byte)0x01, (byte)0x02 } ); - - byte[] buf = new byte[r.getRecordSize()]; - r.serialize(0, buf, new NullEscherSerializationListener() ); - - assertEquals("[2C, 15, 18, F0, 26, 00, 00, 00, " + - "01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, " + - "06, 00, 00, 00, " + // field_2_cacheOfSize - "03, 00, 00, 00, " + // field_3_boundaryTop - "01, 00, 00, 00, " + // field_4_boundaryLeft - "04, 00, 00, 00, " + // field_5_boundaryWidth - "02, 00, 00, 00, " + // field_6_boundaryHeight - "0A, 00, 00, 00, " + // field_7_x - "0B, 00, 00, 00, " + // field_8_y - "05, 00, 00, 00, " + // field_9_cacheOfSavedSize - "08, " + // field_10_compressionFlag - "07, " + // field_11_filter - "01, 02, ]", // field_12_data - HexDump.toHex(buf)); - assertEquals(60, r.getRecordSize() ); - - } - - public void testFillFields() throws Exception - { - EscherBlipRecord r = new EscherBlipRecord(); - r.fillFields( data, 0, new DefaultEscherRecordFactory()); - - assertEquals( EscherBlipRecord.RECORD_ID_START, r.getRecordId() ); - assertEquals( 1, r.getBoundaryLeft() ); - assertEquals( 2, r.getBoundaryHeight() ); - assertEquals( 3, r.getBoundaryTop() ); - assertEquals( 4, r.getBoundaryWidth() ); - assertEquals( 5, r.getCacheOfSavedSize() ); - assertEquals( 6, r.getCacheOfSize() ); - assertEquals( 7, r.getFilter() ); - assertEquals( 8, r.getCompressionFlag() ); - assertEquals( "[01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, ]", HexDump.toHex(r.getSecondaryUID() ) ); - assertEquals( 10, r.getWidth() ); - assertEquals( 11, r.getHeight() ); - assertEquals( (short)5420, r.getOptions() ); - assertEquals( "[01, 02, ]", HexDump.toHex( r.getData() ) ); - } - - public void testToString() throws Exception - { - EscherBlipRecord r = new EscherBlipRecord(); - r.fillFields( data, 0, new DefaultEscherRecordFactory() ); - - String nl = System.getProperty("line.separator"); - - assertEquals( "org.apache.poi.ddf.EscherBlipRecord:" + nl + - " RecordId: 0xF018" + nl + - " Options: 0x152C" + nl + - " Secondary UID: [01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, ]" + nl + - " CacheOfSize: 6" + nl + - " BoundaryTop: 3" + nl + - " BoundaryLeft: 1" + nl + - " BoundaryWidth: 4" + nl + - " BoundaryHeight: 2" + nl + - " X: 10" + nl + - " Y: 11" + nl + - " CacheOfSavedSize: 5" + nl + - " CompressionFlag: 8" + nl + - " Filter: 7" + nl + - " Data:" + nl + - "00000000 01 02 .." + nl - , r.toString() ); - } - -}