1    /*
2     *  ====================================================================
3     *  The Apache Software License, Version 1.1
4     *
5     *  Copyright (c) 2000 The Apache Software Foundation.  All rights
6     *  reserved.
7     *
8     *  Redistribution and use in source and binary forms, with or without
9     *  modification, are permitted provided that the following conditions
10    *  are met:
11    *
12    *  1. Redistributions of source code must retain the above copyright
13    *  notice, this list of conditions and the following disclaimer.
14    *
15    *  2. Redistributions in binary form must reproduce the above copyright
16    *  notice, this list of conditions and the following disclaimer in
17    *  the documentation and/or other materials provided with the
18    *  distribution.
19    *
20    *  3. The end-user documentation included with the redistribution,
21    *  if any, must include the following acknowledgment:
22    *  "This product includes software developed by the
23    *  Apache Software Foundation (http://www.apache.org/)."
24    *  Alternately, this acknowledgment may appear in the software itself,
25    *  if and wherever such third-party acknowledgments normally appear.
26    *
27    *  4. The names "Apache" and "Apache Software Foundation" must
28    *  not be used to endorse or promote products derived from this
29    *  software without prior written permission. For written
30    *  permission, please contact apache@apache.org.
31    *
32    *  5. Products derived from this software may not be called "Apache",
33    *  nor may "Apache" appear in their name, without prior written
34    *  permission of the Apache Software Foundation.
35    *
36    *  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37    *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38    *  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39    *  DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
40    *  ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41    *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42    *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43    *  USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44    *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45    *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46    *  OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47    *  SUCH DAMAGE.
48    *  ====================================================================
49    *
50    *  This software consists of voluntary contributions made by many
51    *  individuals on behalf of the Apache Software Foundation.  For more
52    *  information on the Apache Software Foundation, please see
53    *  <http://www.apache.org/>.
54    */
55   package org.apache.poi.hpsf;
56   
57   import org.apache.poi.util.LittleEndian;
58   /**
59    *  <p>
60    *
61    *  Class to manipulate data in the Clipboard Variant ({@link Variant#VT_CF
62    *  VT_CF}) format.</p>
63    *
64    *@author     Drew Varner (Drew.Varner inOrAround sc.edu)
65    *@created    May 10, 2002
66    *@see        SummaryInformation#getThumbnail()
67    *@version    $Id: Thumbnail.java,v 1.3 2002/05/19 18:09:26 acoliver Exp $
68    *@since      2002-04-29
69    */
70   public class Thumbnail {
71   
72       /**
73        *  <p>
74        *
75        *  Offset in bytes where the Clipboard Format Tag starts in the <code>byte[]</code>
76        *  returned by {@link SummaryInformation#getThumbnail()}</p>
77        */
78       public static int OFFSET_CFTAG = 4;
79   
80       /**
81        *  <p>
82        *
83        *  Offset in bytes where the Clipboard Format starts in the <code>byte[]</code>
84        *  returned by {@link SummaryInformation#getThumbnail()}</p> <p>
85        *
86        *  This is only valid if the Clipboard Format Tag is {@link #CFTAG_WINDOWS}
87        *  </p>
88        */
89       public static int OFFSET_CF = 8;
90   
91       /**
92        *  <p>
93        *
94        *  Offset in bytes where the Windows Metafile (WMF) image data starts in
95        *  the <code>byte[]</code> returned by {@link
96        *  SummaryInformation#getThumbnail()}</p> <p>
97        *
98        *  There is only WMF data at this point in the <code>byte[]</code> if the
99        *  Clipboard Format Tag is {@link #CFTAG_WINDOWS} and the Clipboard Format
100       *  is {@link #CF_METAFILEPICT}.</p> <p>
101       *
102       *  Note: The <code>byte[]</code> that starts at <code>OFFSET_WMFDATA</code>
103       *  and ends at <code>getThumbnail().length - 1</code> forms a complete WMF
104       *  image. It can be saved to disk with a <code>.wmf</code> file type and
105       *  read using a WMF-capable image viewer.</p>
106       */
107      public static int OFFSET_WMFDATA = 20;
108  
109      /**
110       *  <p>
111       *
112       *  Clipboard Format Tag - Windows clipboard format</p> <p>
113       *
114       *  A <code>DWORD</code> indicating a built-in Windows clipboard format
115       *  value</p> <p>
116       *
117       *  See: <a href="http://msdn.microsoft.com/library/en-us/dnolegen/html/msdn_propset.asp"
118       *  target="_blank"> http://msdn.microsoft.com/library/en-us/dnolegen/html/msdn_propset.asp
119       *  </a>
120       */
121      public static int CFTAG_WINDOWS = -1;
122  
123      /**
124       *  <p>
125       *
126       *  Clipboard Format Tag - Macintosh clipboard format</p> <p>
127       *
128       *  A <code>DWORD</code> indicating a Macintosh clipboard format value</p>
129       *  <p>
130       *
131       *  See: <a href="http://msdn.microsoft.com/library/en-us/dnolegen/html/msdn_propset.asp"
132       *  target="_blank"> http://msdn.microsoft.com/library/en-us/dnolegen/html/msdn_propset.asp
133       *  </a>
134       */
135      public static int CFTAG_MACINTOSH = -2;
136  
137      /**
138       *  <p>
139       *
140       *  Clipboard Format Tag - Format ID</p> <p>
141       *
142       *  A GUID containing a format identifier (FMTID). This is rarely used.</p>
143       *  <p>
144       *
145       *  See: <a href="http://msdn.microsoft.com/library/en-us/dnolegen/html/msdn_propset.asp"
146       *  target="_blank"> http://msdn.microsoft.com/library/en-us/dnolegen/html/msdn_propset.asp
147       *  </a>
148       */
149      public static int CFTAG_FMTID = -3;
150  
151      /**
152       *  <p>
153       *
154       *  Clipboard Format Tag - No Data</p> <p>
155       *
156       *  a <code>DWORD</code> indicating No data. This is rarely used.</p> <p>
157       *
158       *  See: <a href="http://msdn.microsoft.com/library/en-us/dnolegen/html/msdn_propset.asp"
159       *  target="_blank"> http://msdn.microsoft.com/library/en-us/dnolegen/html/msdn_propset.asp
160       *  </a>
161       */
162      public static int CFTAG_NODATA = 0;
163  
164      /**
165       *  <p>
166       *
167       *  Clipboard Format - Windows metafile format. This is the recommended way
168       *  to store thumbnails in Property Streams.</p> <p>
169       *
170       *  <strong>Note:</strong> this is not the same format used in regular WMF
171       *  images. The clipboard version of this format has an extra
172       *  clipboard-specific header</p>
173       */
174      public static int CF_METAFILEPICT = 3;
175  
176      /**
177       *  <p>
178       *
179       *  Clipboard Format - Device Independent Bitmap</p>
180       */
181      public static int CF_DIB = 8;
182  
183      /**
184       *  <p>
185       *
186       *  Clipboard Format - Enhanced Windows metafile format</p>
187       */
188      public static int CF_ENHMETAFILE = 14;
189  
190      /**
191       *  <p>
192       *
193       *  Clipboard Format - Bitmap</p> <p>
194       *
195       *  Obsolete, See: <a href="msdn.microsoft.com/library/en-us/dnw98bk/html/clipboardoperations.asp
196       *  target="_blank"> msdn.microsoft.com/library/en-us/dnw98bk/html/clipboardoperations.asp
197       *  </a> </p>
198       */
199      public static int CF_BITMAP = 2;
200  
201      /**
202       *  <p>
203       *
204       *  A <code>byte[]</code> to hold a thumbnail image in ({@link Variant#VT_CF
205       *  VT_CF}) format. </p>
206       */
207      private byte[] thumbnailData = null;
208  
209  
210  
211      /**
212       *  <p>
213       *
214       *  Default Constructor. If you use then one you'll have to add the
215       *  thumbnail <code>byte[]</code> from {@link
216       *  SummaryInformation#getThumbnail()} to do any useful manipulations,
217       *  otherwise you'll get a <code>NullPointerException</code>.</p>
218       */
219      public Thumbnail() {
220          super();
221      }
222  
223  
224  
225      /**
226       *  <p>
227       *
228       *  </p>
229       *
230       *@param  thumbnailData  Description of the Parameter
231       */
232      public Thumbnail(byte[] thumbnailData) {
233          this.thumbnailData = thumbnailData;
234      }
235  
236  
237  
238      /**
239       *  <p>
240       *
241       *  Returns the thumbnail as a <code>byte[]</code> in {@link Variant#VT_CF
242       *  VT_CF} format.</p>
243       *
244       *@return    The thumbnail value
245       *@see       SummaryInformation#getThumbnail()
246       */
247      public byte[] getThumbnail() {
248          return thumbnailData;
249      }
250  
251  
252  
253      /**
254       *  <p>
255       *
256       *  Sets the Thumbnail's underlying <code>byte[]</code> in {@link
257       *  Variant#VT_CF VT_CF} format.</p>
258       *
259       *@param  thumbnail  The new thumbnail value
260       *@see               SummaryInformation#getThumbnail()
261       */
262      public void setThumbnail(byte[] thumbnail) {
263          this.thumbnailData = thumbnail;
264      }
265  
266  
267  
268      /**
269       *  <p>
270       *
271       *  Returns an <code>int</code> representing the Clipboard Format Tag</p>
272       *  <p>
273       *
274       *  Possible return values are:
275       *  <ul>
276       *    <li> {@link #CFTAG_WINDOWS CFTAG_WINDOWS}</li>
277       *    <li> {@link #CFTAG_MACINTOSH CFTAG_MACINTOSH}</li>
278       *    <li> {@link #CFTAG_FMTID CFTAG_FMTID}</li>
279       *    <li> {@link #CFTAG_NODATA CFTAG_NODATA}</li>
280       *  </ul>
281       *  </p>
282       *
283       *@return    a flag indicating the Clipboard Format Tag
284       */
285      public long getClipboardFormatTag() {
286          long clipboardFormatTag = LittleEndian.getUInt(getThumbnail(), OFFSET_CFTAG);
287          return clipboardFormatTag;
288      }
289  
290  
291  
292      /**
293       *  <p>
294       *
295       *  Returns an <code>int</code> representing the Clipboard Format</p> <p>
296       *
297       *  Will throw an exceptionif the Thumbnail's Clipboard Format Tag is not
298       *  {@link Thumbnail#CFTAG_WINDOWS CFTAG_WINDOWS} </p> <p>
299       *
300       *  Possible return values are:
301       *  <ul>
302       *    <li> {@link #CF_METAFILEPICT CF_METAFILEPICT}</li>
303       *    <li> {@link #CF_DIB CF_DIB}</li>
304       *    <li> {@link #CF_ENHMETAFILE CF_ENHMETAFILE}</li>
305       *    <li> {@link #CF_BITMAP CF_BITMAP}</li>
306       *  </ul>
307       *  </p>
308       *
309       *@return                 a flag indicating the Clipboard Format
310       *@throws  HPSFException  if the Thumbnail isn't CFTAG_WINDOWS
311       */
312      public long getClipboardFormat() throws HPSFException {
313          if (!(getClipboardFormatTag() == CFTAG_WINDOWS)) {
314              throw new HPSFException("Clipboard Format Tag of Thumbnail must " +
315                      "be CFTAG_WINDOWS.");
316          }
317  
318          long clipboardFormat = LittleEndian.getUInt(getThumbnail(), OFFSET_CF);
319          return clipboardFormat;
320      }
321  
322  
323  
324      /**
325       *  <p>
326       *
327       *  Returns the Thumbnail as a <code>byte[]</code> of WMF data if the
328       *  Thumbnail's Clipboard Format Tag is {@link #CFTAG_WINDOWS CFTAG_WINDOWS}
329       *  and its Clipboard Format is {@link #CF_METAFILEPICT CF_METAFILEPICT}</p>
330       *  <p>
331       *
332       *  This <code>byte[]</code> is in the traditional WMF file, not the
333       *  clipboard-specific version with special headers.</p> <p>
334       *
335       *  See <a href="http://www.wvware.com/caolan/ora-wmf.html" target="_blank">
336       *  http://www.wvware.com/caolan/ora-wmf.html</a> for more information on
337       *  the WMF image format.</p>
338       *
339       *@return                 a WMF image of the Thumbnail
340       *@throws  HPSFException  if the Thumbnail isn't CFTAG_WINDOWS and
341       *      CF_METAFILEPICT
342       */
343      public byte[] getThumbnailAsWMF() throws HPSFException {
344          if (!(getClipboardFormatTag() == CFTAG_WINDOWS)) {
345              throw new HPSFException("Clipboard Format Tag of Thumbnail must " +
346                      "be CFTAG_WINDOWS.");
347          }
348          if (!(getClipboardFormat() == CF_METAFILEPICT)) {
349              throw new HPSFException("Clipboard Format of Thumbnail must " +
350                      "be CF_METAFILEPICT.");
351          } else {
352              byte[] thumbnail = getThumbnail();
353              int wmfImageLength = thumbnail.length - OFFSET_WMFDATA;
354              byte[] wmfImage = new byte[wmfImageLength];
355              System.arraycopy(thumbnail,
356                      OFFSET_WMFDATA,
357                      wmfImage,
358                      0,
359                      wmfImageLength);
360              return wmfImage;
361          }
362      }
363  
364  }
365