KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > poi > ddf > EscherBlipRecord


1
2 /* ====================================================================
3    Copyright 2002-2004 Apache Software Foundation
4
5    Licensed under the Apache License, Version 2.0 (the "License");
6    you may not use this file except in compliance with the License.
7    You may obtain a copy of the License at
8
9        http://www.apache.org/licenses/LICENSE-2.0
10
11    Unless required by applicable law or agreed to in writing, software
12    distributed under the License is distributed on an "AS IS" BASIS,
13    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14    See the License for the specific language governing permissions and
15    limitations under the License.
16 ==================================================================== */

17         
18 package org.apache.poi.ddf;
19
20 import org.apache.poi.hssf.record.RecordFormatException;
21 import org.apache.poi.util.HexDump;
22 import org.apache.poi.util.LittleEndian;
23
24 import java.io.ByteArrayInputStream JavaDoc;
25 import java.io.ByteArrayOutputStream JavaDoc;
26 import java.io.InputStream JavaDoc;
27 import java.io.IOException JavaDoc;
28 import java.util.zip.InflaterInputStream JavaDoc;
29 import java.util.zip.DeflaterOutputStream JavaDoc;
30
31 /**
32  * The blip record is used to hold details about large binary objects that occur in escher such
33  * as JPEG, GIF, PICT and WMF files. The contents of the stream is usually compressed. Inflate
34  * can be used to decompress the data.
35  *
36  * @author Glen Stampoultzis
37  * @see java.util.zip.Inflater
38  */

39 public class EscherBlipRecord
40         extends EscherRecord
41 {
42     public static final short RECORD_ID_START = (short) 0xF018;
43     public static final short RECORD_ID_END = (short) 0xF117;
44     public static final String JavaDoc RECORD_DESCRIPTION = "msofbtBlip";
45     private static final int HEADER_SIZE = 8;
46
47     private byte[] field_1_secondaryUID;
48     private int field_2_cacheOfSize;
49     private int field_3_boundaryTop;
50     private int field_4_boundaryLeft;
51     private int field_5_boundaryWidth;
52     private int field_6_boundaryHeight;
53     private int field_7_width;
54     private int field_8_height;
55     private int field_9_cacheOfSavedSize;
56     private byte field_10_compressionFlag;
57     private byte field_11_filter;
58     private byte[] field_12_data;
59
60
61     /**
62      * This method deserializes the record from a byte array.
63      *
64      * @param data The byte array containing the escher record information
65      * @param offset The starting offset into <code>data</code>.
66      * @param recordFactory May be null since this is not a container record.
67      * @return The number of bytes read from the byte array.
68      */

69     public int fillFields( byte[] data, int offset,
70                               EscherRecordFactory recordFactory
71                               )
72     {
73         int bytesAfterHeader = readHeader( data, offset );
74         int pos = offset + HEADER_SIZE;
75
76         int size = 0;
77         field_1_secondaryUID = new byte[16];
78         System.arraycopy( data, pos + size, field_1_secondaryUID, 0, 16 ); size += 16;
79         field_2_cacheOfSize = LittleEndian.getInt( data, pos + size );size+=4;
80         field_3_boundaryTop = LittleEndian.getInt( data, pos + size );size+=4;
81         field_4_boundaryLeft = LittleEndian.getInt( data, pos + size );size+=4;
82         field_5_boundaryWidth = LittleEndian.getInt( data, pos + size );size+=4;
83         field_6_boundaryHeight = LittleEndian.getInt( data, pos + size );size+=4;
84         field_7_width = LittleEndian.getInt( data, pos + size );size+=4;
85         field_8_height = LittleEndian.getInt( data, pos + size );size+=4;
86         field_9_cacheOfSavedSize = LittleEndian.getInt( data, pos + size );size+=4;
87         field_10_compressionFlag = data[pos + size]; size++;
88         field_11_filter = data[pos + size]; size++;
89
90         int bytesRemaining = bytesAfterHeader - size;
91         field_12_data = new byte[bytesRemaining];
92         System.arraycopy(data, pos + size, field_12_data, 0, bytesRemaining);
93
94         return bytesRemaining + HEADER_SIZE + bytesAfterHeader;
95     }
96
97
98     /**
99      * This method serializes this escher record into a byte array.
100      *
101      * @param offset The offset into <code>data</code> to start writing the record data to.
102      * @param data The byte array to serialize to.
103      * @param listener A listener to retrieve start and end callbacks. Use a <code>NullEscherSerailizationListener</code> to ignore these events.
104      * @return The number of bytes written.
105      *
106      * @see NullEscherSerializationListener
107      */

108     public int serialize( int offset, byte[] data, EscherSerializationListener listener )
109     {
110         listener.beforeRecordSerialize(offset, getRecordId(), this);
111
112         LittleEndian.putShort( data, offset, getOptions() );
113         LittleEndian.putShort( data, offset + 2, getRecordId() );
114         int remainingBytes = field_12_data.length + 36;
115         LittleEndian.putInt( data, offset + 4, remainingBytes );
116
117         int pos = offset + HEADER_SIZE;
118         System.arraycopy(field_1_secondaryUID, 0, data, pos, 16 ); pos += 16;
119         LittleEndian.putInt( data, pos, field_2_cacheOfSize); pos += 4;
120         LittleEndian.putInt( data, pos, field_3_boundaryTop); pos += 4;
121         LittleEndian.putInt( data, pos, field_4_boundaryLeft); pos += 4;
122         LittleEndian.putInt( data, pos, field_5_boundaryWidth); pos += 4;
123         LittleEndian.putInt( data, pos, field_6_boundaryHeight); pos += 4;
124         LittleEndian.putInt( data, pos, field_7_width); pos += 4;
125         LittleEndian.putInt( data, pos, field_8_height); pos += 4;
126         LittleEndian.putInt( data, pos, field_9_cacheOfSavedSize); pos += 4;
127         data[pos++] = field_10_compressionFlag;
128         data[pos++] = field_11_filter;
129         System.arraycopy(field_12_data, 0, data, pos, field_12_data.length); pos += field_12_data.length;
130
131         listener.afterRecordSerialize(pos, getRecordId(), pos - offset, this);
132         return pos - offset;
133     }
134
135     /**
136      * Returns the number of bytes that are required to serialize this record.
137      *
138      * @return Number of bytes
139      */

140     public int getRecordSize()
141     {
142         return 58 + field_12_data.length;
143     }
144
145     /**
146      * The short name for this record
147      */

148     public String JavaDoc getRecordName()
149     {
150         return "Blip";
151     }
152
153     /**
154      * Retrieve the secondary UID
155      */

156     public byte[] getSecondaryUID()
157     {
158         return field_1_secondaryUID;
159     }
160
161     /**
162      * Set the secondary UID
163      */

164     public void setSecondaryUID( byte[] field_1_secondaryUID )
165     {
166         this.field_1_secondaryUID = field_1_secondaryUID;
167     }
168
169     /**
170      * Retrieve the cache of the metafile size
171      */

172     public int getCacheOfSize()
173     {
174         return field_2_cacheOfSize;
175     }
176
177     /**
178      * Set the cache of the metafile size
179      */

180     public void setCacheOfSize( int field_2_cacheOfSize )
181     {
182         this.field_2_cacheOfSize = field_2_cacheOfSize;
183     }
184
185     /**
186      * Retrieve the top boundary of the metafile drawing commands
187      */

188     public int getBoundaryTop()
189     {
190         return field_3_boundaryTop;
191     }
192
193     /**
194      * Set the top boundary of the metafile drawing commands
195      */

196     public void setBoundaryTop( int field_3_boundaryTop )
197     {
198         this.field_3_boundaryTop = field_3_boundaryTop;
199     }
200
201     /**
202      * Retrieve the left boundary of the metafile drawing commands
203      */

204     public int getBoundaryLeft()
205     {
206         return field_4_boundaryLeft;
207     }
208
209     /**
210      * Set the left boundary of the metafile drawing commands
211      */

212     public void setBoundaryLeft( int field_4_boundaryLeft )
213     {
214         this.field_4_boundaryLeft = field_4_boundaryLeft;
215     }
216
217     /**
218      * Retrieve the boundary width of the metafile drawing commands
219      */

220     public int getBoundaryWidth()
221     {
222         return field_5_boundaryWidth;
223     }
224
225     /**
226      * Set the boundary width of the metafile drawing commands
227      */

228     public void setBoundaryWidth( int field_5_boundaryWidth )
229     {
230         this.field_5_boundaryWidth = field_5_boundaryWidth;
231     }
232
233     /**
234      * Retrieve the boundary height of the metafile drawing commands
235      */

236     public int getBoundaryHeight()
237     {
238         return field_6_boundaryHeight;
239     }
240
241     /**
242      * Set the boundary height of the metafile drawing commands
243      */

244     public void setBoundaryHeight( int field_6_boundaryHeight )
245     {
246         this.field_6_boundaryHeight = field_6_boundaryHeight;
247     }
248
249     /**
250      * Retrieve the width of the metafile in EMU's (English Metric Units).
251      */

252     public int getWidth()
253     {
254         return field_7_width;
255     }
256
257     /**
258      * Set the width of the metafile in EMU's (English Metric Units).
259      */

260     public void setWidth( int width )
261     {
262         this.field_7_width = width;
263     }
264
265     /**
266      * Retrieve the height of the metafile in EMU's (English Metric Units).
267      */

268     public int getHeight()
269     {
270         return field_8_height;
271     }
272
273     /**
274      * Set the height of the metafile in EMU's (English Metric Units).
275      */

276     public void setHeight( int height )
277     {
278         this.field_8_height = height;
279     }
280
281     /**
282      * Retrieve the cache of the saved size
283      */

284     public int getCacheOfSavedSize()
285     {
286         return field_9_cacheOfSavedSize;
287     }
288
289     /**
290      * Set the cache of the saved size
291      */

292     public void setCacheOfSavedSize( int field_9_cacheOfSavedSize )
293     {
294         this.field_9_cacheOfSavedSize = field_9_cacheOfSavedSize;
295     }
296
297     /**
298      * Is the contents of the blip compressed?
299      */

300     public byte getCompressionFlag()
301     {
302         return field_10_compressionFlag;
303     }
304
305     /**
306      * Set whether the contents of the blip is compressed
307      */

308     public void setCompressionFlag( byte field_10_compressionFlag )
309     {
310         this.field_10_compressionFlag = field_10_compressionFlag;
311     }
312
313     /**
314      * Filter should always be 0
315      */

316     public byte getFilter()
317     {
318         return field_11_filter;
319     }
320
321     /**
322      * Filter should always be 0
323      */

324     public void setFilter( byte field_11_filter )
325     {
326         this.field_11_filter = field_11_filter;
327     }
328
329     /**
330      * The BLIP data
331      */

332     public byte[] getData()
333     {
334         return field_12_data;
335     }
336
337     /**
338      * The BLIP data
339      */

340     public void setData( byte[] field_12_data )
341     {
342         this.field_12_data = field_12_data;
343     }
344
345     /**
346      * The string representation of this record.
347      *
348      * @return A string
349      */

350     public String JavaDoc toString()
351     {
352         String JavaDoc nl = System.getProperty( "line.separator" );
353
354         String JavaDoc extraData;
355         ByteArrayOutputStream JavaDoc b = new ByteArrayOutputStream JavaDoc();
356         try
357         {
358             HexDump.dump( this.field_12_data, 0, b, 0 );
359             extraData = b.toString();
360         }
361         catch ( Exception JavaDoc e )
362         {
363             extraData = e.toString();
364         }
365         return getClass().getName() + ":" + nl +
366                 " RecordId: 0x" + HexDump.toHex( getRecordId() ) + nl +
367                 " Options: 0x" + HexDump.toHex( getOptions() ) + nl +
368                 " Secondary UID: " + HexDump.toHex( field_1_secondaryUID ) + nl +
369                 " CacheOfSize: " + field_2_cacheOfSize + nl +
370                 " BoundaryTop: " + field_3_boundaryTop + nl +
371                 " BoundaryLeft: " + field_4_boundaryLeft + nl +
372                 " BoundaryWidth: " + field_5_boundaryWidth + nl +
373                 " BoundaryHeight: " + field_6_boundaryHeight + nl +
374                 " X: " + field_7_width + nl +
375                 " Y: " + field_8_height + nl +
376                 " CacheOfSavedSize: " + field_9_cacheOfSavedSize + nl +
377                 " CompressionFlag: " + field_10_compressionFlag + nl +
378                 " Filter: " + field_11_filter + nl +
379                 " Data:" + nl + extraData;
380     }
381
382     /**
383      * Compress the contents of the provided array
384      *
385      * @param data An uncompressed byte array
386      * @see DeflaterOutputStream#write(int b)
387      */

388     public static byte[] compress( byte[] data )
389     {
390         ByteArrayOutputStream JavaDoc out = new ByteArrayOutputStream JavaDoc();
391         DeflaterOutputStream JavaDoc deflaterOutputStream = new DeflaterOutputStream JavaDoc( out );
392         try
393         {
394             for ( int i = 0; i < data.length; i++ )
395                 deflaterOutputStream.write( data[i] );
396         }
397         catch ( IOException JavaDoc e )
398         {
399             throw new RecordFormatException( e.toString() );
400         }
401
402         return out.toByteArray();
403     }
404
405     /**
406      * Decompresses a byte array.
407      *
408      * @param data The compressed byte array
409      * @param pos The starting position into the byte array
410      * @param length The number of compressed bytes to decompress
411      * @return An uncompressed byte array
412      * @see InflaterInputStream#read
413      */

414     public static byte[] decompress( byte[] data, int pos, int length )
415     {
416         byte[] compressedData = new byte[length];
417         System.arraycopy( data, pos + 50, compressedData, 0, length );
418         InputStream JavaDoc compressedInputStream = new ByteArrayInputStream JavaDoc( compressedData );
419         InflaterInputStream JavaDoc inflaterInputStream = new InflaterInputStream JavaDoc( compressedInputStream );
420         ByteArrayOutputStream JavaDoc out = new ByteArrayOutputStream JavaDoc();
421         int c;
422         try
423         {
424             while ( ( c = inflaterInputStream.read() ) != -1 )
425                 out.write( c );
426         }
427         catch ( IOException JavaDoc e )
428         {
429             throw new RecordFormatException( e.toString() );
430         }
431         return out.toByteArray();
432     }
433
434 }
435
Popular Tags