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>Class to manipulate data in the Clipboard Variant ({@link 60 * Variant#VT_CF VT_CF}) format.</p> 61 * 62 * @author Drew Varner (Drew.Varner inOrAround sc.edu) 63 * @see SummaryInformation#getThumbnail() 64 * @version $Id: Thumbnail.java,v 1.5 2003/02/01 13:28:28 klute Exp $ 65 * @since 2002-04-29 66 */ 67 public class Thumbnail 68 { 69 70 /** 71 * <p>Offset in bytes where the Clipboard Format Tag starts in the 72 * <code>byte[]</code> returned by {@link 73 * SummaryInformation#getThumbnail()}</p> 74 */ 75 public static int OFFSET_CFTAG = 4; 76 77 /** 78 * <p>Offset in bytes where the Clipboard Format starts in the 79 * <code>byte[]</code> returned by {@link 80 * SummaryInformation#getThumbnail()}</p> 81 * 82 * <p>This is only valid if the Clipboard Format Tag is {@link 83 * #CFTAG_WINDOWS}</p> 84 */ 85 public static int OFFSET_CF = 8; 86 87 /** 88 * <p>Offset in bytes where the Windows Metafile (WMF) image data 89 * starts in the <code>byte[]</code> returned by {@link 90 * SummaryInformation#getThumbnail()}</p> 91 * 92 * <p>There is only WMF data at this point in the 93 * <code>byte[]</code> if the Clipboard Format Tag is {@link 94 * #CFTAG_WINDOWS} and the Clipboard Format is {@link 95 * #CF_METAFILEPICT}.</p> 96 * 97 * <p>Note: The <code>byte[]</code> that starts at 98 * <code>OFFSET_WMFDATA</code> and ends at 99 * <code>getThumbnail().length - 1</code> forms a complete WMF 100 * image. It can be saved to disk with a <code>.wmf</code> file 101 * type and read using a WMF-capable image viewer.</p> 102 */ 103 public static int OFFSET_WMFDATA = 20; 104 105 /** 106 * <p>Clipboard Format Tag - Windows clipboard format</p> 107 * 108 * <p>A <code>DWORD</code> indicating a built-in Windows clipboard 109 * format value</p> 110 * 111 * <p>See: <a 112 * href="http://msdn.microsoft.com/library/en-us/dnolegen/html/msdn_propset.asp" 113 * target="_blank">http://msdn.microsoft.com/library/en-us/dnolegen/html/msdn_propset.asp</a>.</p> 114 */ 115 public static int CFTAG_WINDOWS = -1; 116 117 /** 118 * <p>Clipboard Format Tag - Macintosh clipboard format</p> 119 * 120 * <p>A <code>DWORD</code> indicating a Macintosh clipboard format 121 * value</p> 122 * 123 * <p>See: <a 124 * href="http://msdn.microsoft.com/library/en-us/dnolegen/html/msdn_propset.asp" 125 * target="_blank">http://msdn.microsoft.com/library/en-us/dnolegen/html/msdn_propset.asp</a>.</p> 126 */ 127 public static int CFTAG_MACINTOSH = -2; 128 129 /** 130 * <p>Clipboard Format Tag - Format ID</p> 131 * 132 * <p>A GUID containing a format identifier (FMTID). This is 133 * rarely used.</p> 134 * 135 * <p>See: <a 136 * href="http://msdn.microsoft.com/library/en-us/dnolegen/html/msdn_propset.asp" 137 * target="_blank">http://msdn.microsoft.com/library/en-us/dnolegen/html/msdn_propset.asp</a>.</p> 138 */ 139 public static int CFTAG_FMTID = -3; 140 141 /** 142 * <p>Clipboard Format Tag - No Data</p> 143 * 144 * <p>A <code>DWORD</code> indicating No data. This is rarely 145 * used.</p> 146 * 147 * <p>See: <a 148 * href="http://msdn.microsoft.com/library/en-us/dnolegen/html/msdn_propset.asp" 149 * target="_blank"> 150 * http://msdn.microsoft.com/library/en-us/dnolegen/html/msdn_propset.asp</a>.</p> 151 */ 152 public static int CFTAG_NODATA = 0; 153 154 /** 155 * <p>Clipboard Format - Windows metafile format. This is the 156 * recommended way to store thumbnails in Property Streams.</p> 157 * 158 * <p><strong>Note:</strong> This is not the same format used in 159 * regular WMF images. The clipboard version of this format has an 160 * extra clipboard-specific header.</p> 161 */ 162 public static int CF_METAFILEPICT = 3; 163 164 /** 165 * <p>Clipboard Format - Device Independent Bitmap</p> 166 */ 167 public static int CF_DIB = 8; 168 169 /** 170 * <p>Clipboard Format - Enhanced Windows metafile format</p> 171 */ 172 public static int CF_ENHMETAFILE = 14; 173 174 /** 175 * <p>Clipboard Format - Bitmap</p> 176 * 177 * <p>Obsolete, see <a 178 * href="msdn.microsoft.com/library/en-us/dnw98bk/html/clipboardoperations.asp 179 * target="_blank">msdn.microsoft.com/library/en-us/dnw98bk/html/clipboardoperations.asp</a>.</p> 180 */ 181 public static int CF_BITMAP = 2; 182 183 /** 184 * <p>A <code>byte[]</code> to hold a thumbnail image in ({@link 185 * Variant#VT_CF VT_CF}) format.</p> 186 */ 187 private byte[] thumbnailData = null; 188 189 190 191 /** 192 * <p>Default Constructor. If you use it then one you'll have to add 193 * the thumbnail <code>byte[]</code> from {@link 194 * SummaryInformation#getThumbnail()} to do any useful 195 * manipulations, otherwise you'll get a 196 * <code>NullPointerException</code>.</p> 197 */ 198 public Thumbnail() 199 { 200 super(); 201 } 202 203 204 205 /** 206 * <p>Creates a <code>Thumbnail</code> instance and initializes 207 * with the specified image bytes.</p> 208 * 209 * @param thumbnailData The thumbnail data 210 */ 211 public Thumbnail(byte[] thumbnailData) 212 { 213 this.thumbnailData = thumbnailData; 214 } 215 216 217 218 /** 219 * <p>Returns the thumbnail as a <code>byte[]</code> in {@link 220 * Variant#VT_CF VT_CF} format.</p> 221 * 222 * @return The thumbnail value 223 * @see SummaryInformation#getThumbnail() 224 */ 225 public byte[] getThumbnail() 226 { 227 return thumbnailData; 228 } 229 230 231 232 /** 233 * <p>Sets the Thumbnail's underlying <code>byte[]</code> in 234 * {@link Variant#VT_CF VT_CF} format.</p> 235 * 236 * @param thumbnail The new thumbnail value 237 * @see SummaryInformation#getThumbnail() 238 */ 239 public void setThumbnail(byte[] thumbnail) 240 { 241 this.thumbnailData = thumbnail; 242 } 243 244 245 246 /** 247 * <p>Returns an <code>int</code> representing the Clipboard 248 * Format Tag</p> 249 * 250 * <p>Possible return values are:</p> 251 * <ul> 252 * <li>{@link #CFTAG_WINDOWS CFTAG_WINDOWS}</li> 253 * <li>{@link #CFTAG_MACINTOSH CFTAG_MACINTOSH}</li> 254 * <li>{@link #CFTAG_FMTID CFTAG_FMTID}</li> 255 * <li>{@link #CFTAG_NODATA CFTAG_NODATA}</li> 256 * </ul> 257 * 258 * @return A flag indicating the Clipboard Format Tag 259 */ 260 public long getClipboardFormatTag() 261 { 262 long clipboardFormatTag = LittleEndian.getUInt(getThumbnail(), 263 OFFSET_CFTAG); 264 return clipboardFormatTag; 265 } 266 267 268 269 /** 270 * <p>Returns an <code>int</code> representing the Clipboard 271 * Format</p> 272 * 273 * <p>Will throw an exception if the Thumbnail's Clipboard Format 274 * Tag is not {@link Thumbnail#CFTAG_WINDOWS CFTAG_WINDOWS}.</p> 275 * 276 * <p>Possible return values are:</p> 277 * 278 * <ul> 279 * <li>{@link #CF_METAFILEPICT CF_METAFILEPICT}</li> 280 * <li>{@link #CF_DIB CF_DIB}</li> 281 * <li>{@link #CF_ENHMETAFILE CF_ENHMETAFILE}</li> 282 * <li>{@link #CF_BITMAP CF_BITMAP}</li> 283 * </ul> 284 * 285 * @return a flag indicating the Clipboard Format 286 * @throws HPSFException if the Thumbnail isn't CFTAG_WINDOWS 287 */ 288 public long getClipboardFormat() throws HPSFException 289 { 290 if (!(getClipboardFormatTag() == CFTAG_WINDOWS)) 291 throw new HPSFException("Clipboard Format Tag of Thumbnail must " + 292 "be CFTAG_WINDOWS."); 293 294 return LittleEndian.getUInt(getThumbnail(), OFFSET_CF); 295 } 296 297 298 299 /** 300 * <p>Returns the Thumbnail as a <code>byte[]</code> of WMF data 301 * if the Thumbnail's Clipboard Format Tag is {@link 302 * #CFTAG_WINDOWS CFTAG_WINDOWS} and its Clipboard Format is 303 * {@link #CF_METAFILEPICT CF_METAFILEPICT}</p> <p>This 304 * <code>byte[]</code> is in the traditional WMF file, not the 305 * clipboard-specific version with special headers.</p> 306 * 307 * <p>See <a href="http://www.wvware.com/caolan/ora-wmf.html" 308 * target="_blank">http://www.wvware.com/caolan/ora-wmf.html</a> 309 * for more information on the WMF image format.</p> 310 * 311 * @return A WMF image of the Thumbnail 312 * @throws HPSFException if the Thumbnail isn't CFTAG_WINDOWS and 313 * CF_METAFILEPICT 314 */ 315 public byte[] getThumbnailAsWMF() throws HPSFException 316 { 317 if (!(getClipboardFormatTag() == CFTAG_WINDOWS)) 318 throw new HPSFException("Clipboard Format Tag of Thumbnail must " + 319 "be CFTAG_WINDOWS."); 320 if (!(getClipboardFormat() == CF_METAFILEPICT)) 321 throw new HPSFException("Clipboard Format of Thumbnail must " + 322 "be CF_METAFILEPICT."); 323 else 324 { 325 byte[] thumbnail = getThumbnail(); 326 int wmfImageLength = thumbnail.length - OFFSET_WMFDATA; 327 byte[] wmfImage = new byte[wmfImageLength]; 328 System.arraycopy(thumbnail, 329 OFFSET_WMFDATA, 330 wmfImage, 331 0, 332 wmfImageLength); 333 return wmfImage; 334 } 335 } 336 337 } 338