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