KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > lowagie > text > pdf > codec > TiffImage


1 /*
2  * Copyright 2003-2005 by Paulo Soares.
3  *
4  * The contents of this file are subject to the Mozilla Public License Version 1.1
5  * (the "License"); you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at http://www.mozilla.org/MPL/
7  *
8  * Software distributed under the License is distributed on an "AS IS" basis,
9  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
10  * for the specific language governing rights and limitations under the License.
11  *
12  * The Original Code is 'iText, a free JAVA-PDF library'.
13  *
14  * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
15  * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
16  * All Rights Reserved.
17  * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
18  * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
19  *
20  * Contributor(s): all the names of the contributors are added in the source code
21  * where applicable.
22  *
23  * Alternatively, the contents of this file may be used under the terms of the
24  * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
25  * provisions of LGPL are applicable instead of those above. If you wish to
26  * allow use of your version of this file only under the terms of the LGPL
27  * License and not to allow others to use your version of this file under
28  * the MPL, indicate your decision by deleting the provisions above and
29  * replace them with the notice and other provisions required by the LGPL.
30  * If you do not delete the provisions above, a recipient may use your version
31  * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
32  *
33  * This library is free software; you can redistribute it and/or modify it
34  * under the terms of the MPL as stated above or under the terms of the GNU
35  * Library General Public License as published by the Free Software Foundation;
36  * either version 2 of the License, or any later version.
37  *
38  * This library is distributed in the hope that it will be useful, but WITHOUT
39  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
40  * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
41  * details.
42  *
43  * If you didn't download this code from the following link, you should check if
44  * you aren't using an obsolete version:
45  * http://www.lowagie.com/iText/
46  */

47 package com.lowagie.text.pdf.codec;
48 import java.awt.color.ICC_Profile JavaDoc;
49 import java.io.ByteArrayOutputStream JavaDoc;
50 import java.io.IOException JavaDoc;
51 import java.util.zip.DataFormatException JavaDoc;
52 import java.util.zip.DeflaterOutputStream JavaDoc;
53 import java.util.zip.Inflater JavaDoc;
54
55 import com.lowagie.text.ExceptionConverter;
56 import com.lowagie.text.Image;
57 import com.lowagie.text.Jpeg;
58 import com.lowagie.text.pdf.PdfArray;
59 import com.lowagie.text.pdf.PdfDictionary;
60 import com.lowagie.text.pdf.PdfName;
61 import com.lowagie.text.pdf.PdfNumber;
62 import com.lowagie.text.pdf.PdfString;
63 import com.lowagie.text.pdf.RandomAccessFileOrArray;
64
65 /** Reads TIFF images
66  * @author Paulo Soares (psoares@consiste.pt)
67  */

68 public class TiffImage {
69     
70     /** Gets the number of pages the TIFF document has.
71      * @param s the file source
72      * @return the number of pages
73      */

74     public static int getNumberOfPages(RandomAccessFileOrArray s) {
75         try {
76             return TIFFDirectory.getNumDirectories(s);
77         }
78         catch (Exception JavaDoc e) {
79             throw new ExceptionConverter(e);
80         }
81     }
82
83     static int getDpi(TIFFField fd, int resolutionUnit) {
84         if (fd == null)
85             return 0;
86         long res[] = fd.getAsRational(0);
87         float frac = (float)res[0] / (float)res[1];
88         int dpi = 0;
89         switch (resolutionUnit) {
90             case TIFFConstants.RESUNIT_INCH:
91             case TIFFConstants.RESUNIT_NONE:
92                 dpi = (int)frac;
93                 break;
94             case TIFFConstants.RESUNIT_CENTIMETER:
95                 dpi = (int)(frac * 2.54);
96                 break;
97         }
98         return dpi;
99     }
100     
101     /** Reads a page from a TIFF image. Direct mode is not used.
102      * @param s the file source
103      * @param page the page to get. The first page is 1
104      * @return the <CODE>Image</CODE>
105      */

106     public static Image getTiffImage(RandomAccessFileOrArray s, int page) {
107         return getTiffImage(s, page, false);
108     }
109     
110     /** Reads a page from a TIFF image.
111      * @param s the file source
112      * @param page the page to get. The first page is 1
113      * @param direct for single strip, CCITT images, generate the image
114      * by direct byte copying. It's faster but may not work
115      * every time
116      * @return the <CODE>Image</CODE>
117      */

118     public static Image getTiffImage(RandomAccessFileOrArray s, int page, boolean direct) {
119         if (page < 1)
120             throw new IllegalArgumentException JavaDoc("The page number must be >= 1.");
121         try {
122             TIFFDirectory dir = new TIFFDirectory(s, page - 1);
123             if (dir.isTagPresent(TIFFConstants.TIFFTAG_TILEWIDTH))
124                 throw new IllegalArgumentException JavaDoc("Tiles are not supported.");
125             int compression = (int)dir.getFieldAsLong(TIFFConstants.TIFFTAG_COMPRESSION);
126             switch (compression) {
127                 case TIFFConstants.COMPRESSION_CCITTRLEW:
128                 case TIFFConstants.COMPRESSION_CCITTRLE:
129                 case TIFFConstants.COMPRESSION_CCITTFAX3:
130                 case TIFFConstants.COMPRESSION_CCITTFAX4:
131                     break;
132                 default:
133                     return getTiffImageColor(dir, s);
134             }
135             float rotation = 0;
136             if (dir.isTagPresent(TIFFConstants.TIFFTAG_ORIENTATION)) {
137                 int rot = (int)dir.getFieldAsLong(TIFFConstants.TIFFTAG_ORIENTATION);
138                 if (rot == TIFFConstants.ORIENTATION_BOTRIGHT || rot == TIFFConstants.ORIENTATION_BOTLEFT)
139                     rotation = (float)Math.PI;
140                 else if (rot == TIFFConstants.ORIENTATION_LEFTTOP || rot == TIFFConstants.ORIENTATION_LEFTBOT)
141                     rotation = (float)(Math.PI / 2.0);
142                 else if (rot == TIFFConstants.ORIENTATION_RIGHTTOP || rot == TIFFConstants.ORIENTATION_RIGHTBOT)
143                     rotation = -(float)(Math.PI / 2.0);
144             }
145
146             Image img = null;
147             long tiffT4Options = 0;
148             long tiffT6Options = 0;
149             int fillOrder = 1;
150             int h = (int)dir.getFieldAsLong(TIFFConstants.TIFFTAG_IMAGELENGTH);
151             int w = (int)dir.getFieldAsLong(TIFFConstants.TIFFTAG_IMAGEWIDTH);
152             int dpiX = 0;
153             int dpiY = 0;
154             float XYRatio = 0;
155             int resolutionUnit = TIFFConstants.RESUNIT_INCH;
156             if (dir.isTagPresent(TIFFConstants.TIFFTAG_RESOLUTIONUNIT))
157                 resolutionUnit = (int)dir.getFieldAsLong(TIFFConstants.TIFFTAG_RESOLUTIONUNIT);
158             dpiX = getDpi(dir.getField(TIFFConstants.TIFFTAG_XRESOLUTION), resolutionUnit);
159             dpiY = getDpi(dir.getField(TIFFConstants.TIFFTAG_YRESOLUTION), resolutionUnit);
160             if (resolutionUnit == TIFFConstants.RESUNIT_NONE) {
161                 if (dpiY != 0)
162                     XYRatio = (float)dpiX / (float)dpiY;
163                 dpiX = 0;
164                 dpiY = 0;
165             }
166             long tstrip = 0xFFFFFFFFL;
167             if (dir.isTagPresent(TIFFConstants.TIFFTAG_ROWSPERSTRIP))
168                 tstrip = dir.getFieldAsLong(TIFFConstants.TIFFTAG_ROWSPERSTRIP);
169             int rowsStrip = (int)Math.min(h, tstrip);
170             long offset[] = getArrayLongShort(dir, TIFFConstants.TIFFTAG_STRIPOFFSETS);
171             long size[] = getArrayLongShort(dir, TIFFConstants.TIFFTAG_STRIPBYTECOUNTS);
172             if ((size == null || (size.length == 1 && size[0] == 0)) && h == rowsStrip) { // some TIFF producers are really lousy, so...
173
size = new long[]{s.length() - (int)offset[0]};
174             }
175             boolean reverse = false;
176             TIFFField fillOrderField = dir.getField(TIFFConstants.TIFFTAG_FILLORDER);
177             if (fillOrderField != null)
178                 fillOrder = fillOrderField.getAsInt(0);
179             reverse = (fillOrder == TIFFConstants.FILLORDER_LSB2MSB);
180             int params = 0;
181             if (dir.isTagPresent(TIFFConstants.TIFFTAG_PHOTOMETRIC)) {
182                 long photo = dir.getFieldAsLong(TIFFConstants.TIFFTAG_PHOTOMETRIC);
183                 if (photo == TIFFConstants.PHOTOMETRIC_MINISBLACK)
184                     params |= Image.CCITT_BLACKIS1;
185             }
186             int imagecomp = 0;
187             switch (compression) {
188                 case TIFFConstants.COMPRESSION_CCITTRLEW:
189                 case TIFFConstants.COMPRESSION_CCITTRLE:
190                     imagecomp = Image.CCITTG3_1D;
191                     params |= Image.CCITT_ENCODEDBYTEALIGN | Image.CCITT_ENDOFBLOCK;
192                     break;
193                 case TIFFConstants.COMPRESSION_CCITTFAX3:
194                     imagecomp = Image.CCITTG3_1D;
195                     params |= Image.CCITT_ENDOFLINE | Image.CCITT_ENDOFBLOCK;
196                     TIFFField t4OptionsField = dir.getField(TIFFConstants.TIFFTAG_GROUP3OPTIONS);
197                     if (t4OptionsField != null) {
198                         tiffT4Options = t4OptionsField.getAsLong(0);
199                     if ((tiffT4Options & TIFFConstants.GROUP3OPT_2DENCODING) != 0)
200                         imagecomp = Image.CCITTG3_2D;
201                     if ((tiffT4Options & TIFFConstants.GROUP3OPT_FILLBITS) != 0)
202                         params |= Image.CCITT_ENCODEDBYTEALIGN;
203                     }
204                     break;
205                 case TIFFConstants.COMPRESSION_CCITTFAX4:
206                     imagecomp = Image.CCITTG4;
207                     TIFFField t6OptionsField = dir.getField(TIFFConstants.TIFFTAG_GROUP4OPTIONS);
208                     if (t6OptionsField != null)
209                         tiffT6Options = t6OptionsField.getAsLong(0);
210                     break;
211             }
212             if (direct && rowsStrip == h) { //single strip, direct
213
byte im[] = new byte[(int)size[0]];
214                 s.seek(offset[0]);
215                 s.readFully(im);
216                 img = Image.getInstance(w, h, reverse, imagecomp, params, im);
217                 img.setInverted(true);
218             }
219             else {
220                 int rowsLeft = h;
221                 CCITTG4Encoder g4 = new CCITTG4Encoder(w);
222                 for (int k = 0; k < offset.length; ++k) {
223                     byte im[] = new byte[(int)size[k]];
224                     s.seek(offset[k]);
225                     s.readFully(im);
226                     int height = Math.min(rowsStrip, rowsLeft);
227                     TIFFFaxDecoder decoder = new TIFFFaxDecoder(fillOrder, w, height);
228                     byte outBuf[] = new byte[(w + 7) / 8 * height];
229                     switch (compression) {
230                         case TIFFConstants.COMPRESSION_CCITTRLEW:
231                         case TIFFConstants.COMPRESSION_CCITTRLE:
232                             decoder.decode1D(outBuf, im, 0, height);
233                             g4.fax4Encode(outBuf,height);
234                             break;
235                         case TIFFConstants.COMPRESSION_CCITTFAX3:
236                             try {
237                                 decoder.decode2D(outBuf, im, 0, height, tiffT4Options);
238                             }
239                             catch (RuntimeException JavaDoc e) {
240                                 // let's flip the fill bits and try again...
241
tiffT4Options ^= TIFFConstants.GROUP3OPT_FILLBITS;
242                                 try {
243                                     decoder.decode2D(outBuf, im, 0, height, tiffT4Options);
244                                 }
245                                 catch (RuntimeException JavaDoc e2) {
246                                     throw e;
247                                 }
248                             }
249                             g4.fax4Encode(outBuf, height);
250                             break;
251                         case TIFFConstants.COMPRESSION_CCITTFAX4:
252                             decoder.decodeT6(outBuf, im, 0, height, tiffT6Options);
253                             g4.fax4Encode(outBuf, height);
254                             break;
255                     }
256                     rowsLeft -= rowsStrip;
257                 }
258                 byte g4pic[] = g4.close();
259                 img = Image.getInstance(w, h, false, Image.CCITTG4, params & Image.CCITT_BLACKIS1, g4pic);
260             }
261             img.setDpi(dpiX, dpiY);
262             img.setXYRatio(XYRatio);
263             if (dir.isTagPresent(TIFFConstants.TIFFTAG_ICCPROFILE)) {
264                 try {
265                     TIFFField fd = dir.getField(TIFFConstants.TIFFTAG_ICCPROFILE);
266                     ICC_Profile JavaDoc icc_prof = ICC_Profile.getInstance(fd.getAsBytes());
267                     if (icc_prof.getNumComponents() == 1)
268                         img.tagICC(icc_prof);
269                 }
270                 catch (RuntimeException JavaDoc e) {
271                     //empty
272
}
273             }
274             img.setOriginalType(Image.ORIGINAL_TIFF);
275             if (rotation != 0)
276                 img.setInitialRotation(rotation);
277             return img;
278         }
279         catch (Exception JavaDoc e) {
280             throw new ExceptionConverter(e);
281         }
282     }
283     
284     protected static Image getTiffImageColor(TIFFDirectory dir, RandomAccessFileOrArray s) {
285         try {
286             int compression = (int)dir.getFieldAsLong(TIFFConstants.TIFFTAG_COMPRESSION);
287             int predictor = 1;
288             TIFFLZWDecoder lzwDecoder = null;
289             switch (compression) {
290                 case TIFFConstants.COMPRESSION_NONE:
291                 case TIFFConstants.COMPRESSION_LZW:
292                 case TIFFConstants.COMPRESSION_PACKBITS:
293                 case TIFFConstants.COMPRESSION_DEFLATE:
294                 case TIFFConstants.COMPRESSION_OJPEG:
295                 case TIFFConstants.COMPRESSION_JPEG:
296                     break;
297                 default:
298                     throw new IllegalArgumentException JavaDoc("The compression " + compression + " is not supported.");
299             }
300             int photometric = (int)dir.getFieldAsLong(TIFFConstants.TIFFTAG_PHOTOMETRIC);
301             switch (photometric) {
302                 case TIFFConstants.PHOTOMETRIC_MINISWHITE:
303                 case TIFFConstants.PHOTOMETRIC_MINISBLACK:
304                 case TIFFConstants.PHOTOMETRIC_RGB:
305                 case TIFFConstants.PHOTOMETRIC_SEPARATED:
306                 case TIFFConstants.PHOTOMETRIC_PALETTE:
307                     break;
308                 default:
309                     if (compression != TIFFConstants.COMPRESSION_OJPEG && compression != TIFFConstants.COMPRESSION_JPEG)
310                         throw new IllegalArgumentException JavaDoc("The photometric " + photometric + " is not supported.");
311             }
312             float rotation = 0;
313             if (dir.isTagPresent(TIFFConstants.TIFFTAG_ORIENTATION)) {
314                 int rot = (int)dir.getFieldAsLong(TIFFConstants.TIFFTAG_ORIENTATION);
315                 if (rot == TIFFConstants.ORIENTATION_BOTRIGHT || rot == TIFFConstants.ORIENTATION_BOTLEFT)
316                     rotation = (float)Math.PI;
317                 else if (rot == TIFFConstants.ORIENTATION_LEFTTOP || rot == TIFFConstants.ORIENTATION_LEFTBOT)
318                     rotation = (float)(Math.PI / 2.0);
319                 else if (rot == TIFFConstants.ORIENTATION_RIGHTTOP || rot == TIFFConstants.ORIENTATION_RIGHTBOT)
320                     rotation = -(float)(Math.PI / 2.0);
321             }
322             if (dir.isTagPresent(TIFFConstants.TIFFTAG_PLANARCONFIG)
323                 && dir.getFieldAsLong(TIFFConstants.TIFFTAG_PLANARCONFIG) == TIFFConstants.PLANARCONFIG_SEPARATE)
324                 throw new IllegalArgumentException JavaDoc("Planar images are not supported.");
325             if (dir.isTagPresent(TIFFConstants.TIFFTAG_EXTRASAMPLES))
326                 throw new IllegalArgumentException JavaDoc("Extra samples are not supported.");
327             int samplePerPixel = 1;
328             if (dir.isTagPresent(TIFFConstants.TIFFTAG_SAMPLESPERPIXEL)) // 1,3,4
329
samplePerPixel = (int)dir.getFieldAsLong(TIFFConstants.TIFFTAG_SAMPLESPERPIXEL);
330             int bitsPerSample = 1;
331             if (dir.isTagPresent(TIFFConstants.TIFFTAG_BITSPERSAMPLE))
332                 bitsPerSample = (int)dir.getFieldAsLong(TIFFConstants.TIFFTAG_BITSPERSAMPLE);
333             switch (bitsPerSample) {
334                 case 1:
335                 case 2:
336                 case 4:
337                 case 8:
338                     break;
339                 default:
340                     throw new IllegalArgumentException JavaDoc("Bits per sample " + bitsPerSample + " is not supported.");
341             }
342             Image img = null;
343
344             int h = (int)dir.getFieldAsLong(TIFFConstants.TIFFTAG_IMAGELENGTH);
345             int w = (int)dir.getFieldAsLong(TIFFConstants.TIFFTAG_IMAGEWIDTH);
346             int dpiX = 0;
347             int dpiY = 0;
348             int resolutionUnit = TIFFConstants.RESUNIT_INCH;
349             if (dir.isTagPresent(TIFFConstants.TIFFTAG_RESOLUTIONUNIT))
350                 resolutionUnit = (int)dir.getFieldAsLong(TIFFConstants.TIFFTAG_RESOLUTIONUNIT);
351             dpiX = getDpi(dir.getField(TIFFConstants.TIFFTAG_XRESOLUTION), resolutionUnit);
352             dpiY = getDpi(dir.getField(TIFFConstants.TIFFTAG_YRESOLUTION), resolutionUnit);
353             int rowsStrip = h;
354             if (dir.isTagPresent(TIFFConstants.TIFFTAG_ROWSPERSTRIP)) //another hack for broken tiffs
355
rowsStrip = (int)dir.getFieldAsLong(TIFFConstants.TIFFTAG_ROWSPERSTRIP);
356             long offset[] = getArrayLongShort(dir, TIFFConstants.TIFFTAG_STRIPOFFSETS);
357             long size[] = getArrayLongShort(dir, TIFFConstants.TIFFTAG_STRIPBYTECOUNTS);
358             if ((size == null || (size.length == 1 && size[0] == 0)) && h == rowsStrip) { // some TIFF producers are really lousy, so...
359
size = new long[]{s.length() - (int)offset[0]};
360             }
361             if (compression == TIFFConstants.COMPRESSION_LZW) {
362                 TIFFField predictorField = dir.getField(TIFFConstants.TIFFTAG_PREDICTOR);
363                 if (predictorField != null) {
364                     predictor = predictorField.getAsInt(0);
365                     if (predictor != 1 && predictor != 2) {
366                         throw new RuntimeException JavaDoc("Illegal value for Predictor in TIFF file.");
367                     }
368                     if (predictor == 2 && bitsPerSample != 8) {
369                         throw new RuntimeException JavaDoc(bitsPerSample + "-bit samples are not supported for Horizontal differencing Predictor.");
370                     }
371                 }
372                 lzwDecoder = new TIFFLZWDecoder(w, predictor,
373                                                 samplePerPixel);
374             }
375             int rowsLeft = h;
376             ByteArrayOutputStream JavaDoc stream = null;
377             DeflaterOutputStream JavaDoc zip = null;
378             CCITTG4Encoder g4 = null;
379             if (bitsPerSample == 1 && samplePerPixel == 1) {
380                 g4 = new CCITTG4Encoder(w);
381             }
382             else {
383                 stream = new ByteArrayOutputStream JavaDoc();
384                 if (compression != TIFFConstants.COMPRESSION_OJPEG && compression != TIFFConstants.COMPRESSION_JPEG)
385                     zip = new DeflaterOutputStream JavaDoc(stream);
386             }
387             if (compression == TIFFConstants.COMPRESSION_OJPEG) {
388                 if ((!dir.isTagPresent(TIFFConstants.TIFFTAG_JPEGIFOFFSET))
389                 || (!dir.isTagPresent(TIFFConstants.TIFFTAG_JPEGIFBYTECOUNT))) {
390                     throw new RuntimeException JavaDoc("Missing tag(s) for OJPEG compression.");
391                 }
392                 int jpegOffset = (int)dir.getFieldAsLong(TIFFConstants.TIFFTAG_JPEGIFOFFSET);
393                 int jpegLength = (int)dir.getFieldAsLong(TIFFConstants.TIFFTAG_JPEGIFBYTECOUNT) +
394                         (int)size[0];
395
396                 byte[] jpeg = new byte[Math.min(jpegLength, s.length() - jpegOffset)];
397
398                 int posFilePointer = s.getFilePointer();
399                 posFilePointer += jpegOffset;
400                 s.seek(posFilePointer);
401                 s.readFully(jpeg);
402                 img = new Jpeg(jpeg);
403             }
404             else if (compression == TIFFConstants.COMPRESSION_JPEG) {
405                 if (size.length > 1)
406                     throw new IOException JavaDoc("Compression JPEG is only supported with a single strip. This image has " + size.length + " strips.");
407                 byte[] jpeg = new byte[(int)size[0]];
408                 s.seek(offset[0]);
409                 s.readFully(jpeg);
410                 img = new Jpeg(jpeg);
411             }
412             else {
413                 for (int k = 0; k < offset.length; ++k) {
414                     byte im[] = new byte[(int)size[k]];
415                     s.seek(offset[k]);
416                     s.readFully(im);
417                     int height = Math.min(rowsStrip, rowsLeft);
418                     byte outBuf[] = null;
419                     if (compression != TIFFConstants.COMPRESSION_NONE)
420                         outBuf = new byte[(w * bitsPerSample * samplePerPixel + 7) / 8 * height];
421                     switch (compression) {
422                         case TIFFConstants.COMPRESSION_DEFLATE:
423                             inflate(im, outBuf);
424                             break;
425                         case TIFFConstants.COMPRESSION_NONE:
426                             outBuf = im;
427                             break;
428                         case TIFFConstants.COMPRESSION_PACKBITS:
429                             decodePackbits(im, outBuf);
430                             break;
431                         case TIFFConstants.COMPRESSION_LZW:
432                             lzwDecoder.decode(im, outBuf, height);
433                             break;
434                     }
435                     if (bitsPerSample == 1 && samplePerPixel == 1) {
436                         g4.fax4Encode(outBuf, height);
437                     }
438                     else {
439                         zip.write(outBuf);
440                     }
441                     rowsLeft -= rowsStrip;
442                 }
443                 if (bitsPerSample == 1 && samplePerPixel == 1) {
444                     img = Image.getInstance(w, h, false, Image.CCITTG4,
445                         photometric == TIFFConstants.PHOTOMETRIC_MINISBLACK ? Image.CCITT_BLACKIS1 : 0, g4.close());
446                 }
447                 else {
448                     zip.close();
449                     img = Image.getInstance(w, h, samplePerPixel, bitsPerSample, stream.toByteArray());
450                     img.setDeflated(true);
451                 }
452             }
453             img.setDpi(dpiX, dpiY);
454             if (compression != TIFFConstants.COMPRESSION_OJPEG && compression != TIFFConstants.COMPRESSION_JPEG) {
455                 if (dir.isTagPresent(TIFFConstants.TIFFTAG_ICCPROFILE)) {
456                     try {
457                         TIFFField fd = dir.getField(TIFFConstants.TIFFTAG_ICCPROFILE);
458                         ICC_Profile JavaDoc icc_prof = ICC_Profile.getInstance(fd.getAsBytes());
459                         if (samplePerPixel == icc_prof.getNumComponents())
460                             img.tagICC(icc_prof);
461                     }
462                     catch (RuntimeException JavaDoc e) {
463                         //empty
464
}
465                 }
466                 if (dir.isTagPresent(TIFFConstants.TIFFTAG_COLORMAP)) {
467                     TIFFField fd = dir.getField(TIFFConstants.TIFFTAG_COLORMAP);
468                     char rgb[] = fd.getAsChars();
469                     byte palette[] = new byte[rgb.length];
470                     int gColor = rgb.length / 3;
471                     int bColor = gColor * 2;
472                     for (int k = 0; k < gColor; ++k) {
473                         palette[k * 3] = (byte)(rgb[k] >>> 8);
474                         palette[k * 3 + 1] = (byte)(rgb[k + gColor] >>> 8);
475                         palette[k * 3 + 2] = (byte)(rgb[k + bColor] >>> 8);
476                     }
477                     PdfArray indexed = new PdfArray();
478                     indexed.add(PdfName.INDEXED);
479                     indexed.add(PdfName.DEVICERGB);
480                     indexed.add(new PdfNumber(gColor - 1));
481                     indexed.add(new PdfString(palette));
482                     PdfDictionary additional = new PdfDictionary();
483                     additional.put(PdfName.COLORSPACE, indexed);
484                     img.setAdditional(additional);
485                 }
486                 img.setOriginalType(Image.ORIGINAL_TIFF);
487             }
488             if (photometric == TIFFConstants.PHOTOMETRIC_MINISWHITE)
489                 img.setInverted(true);
490             if (rotation != 0)
491                 img.setInitialRotation(rotation);
492             return img;
493         }
494         catch (Exception JavaDoc e) {
495             throw new ExceptionConverter(e);
496         }
497     }
498     
499     static long[] getArrayLongShort(TIFFDirectory dir, int tag) {
500         TIFFField field = dir.getField(tag);
501         if (field == null)
502             return null;
503         long offset[];
504         if (field.getType() == TIFFField.TIFF_LONG)
505             offset = field.getAsLongs();
506         else { // must be short
507
char temp[] = field.getAsChars();
508             offset = new long[temp.length];
509             for (int k = 0; k < temp.length; ++k)
510                 offset[k] = temp[k];
511         }
512         return offset;
513     }
514     
515     // Uncompress packbits compressed image data.
516
public static void decodePackbits(byte data[], byte[] dst) {
517         int srcCount = 0, dstCount = 0;
518         byte repeat, b;
519         
520         while (dstCount < dst.length) {
521             b = data[srcCount++];
522             if (b >= 0 && b <= 127) {
523                 // literal run packet
524
for (int i=0; i<(b + 1); i++) {
525                     dst[dstCount++] = data[srcCount++];
526                 }
527
528             } else if (b <= -1 && b >= -127) {
529                 // 2 byte encoded run packet
530
repeat = data[srcCount++];
531                 for (int i=0; i<(-b + 1); i++) {
532                     dst[dstCount++] = repeat;
533                 }
534             } else {
535                 // no-op packet. Do nothing
536
srcCount++;
537             }
538         }
539     }
540
541     public static void inflate(byte[] deflated, byte[] inflated) {
542         Inflater JavaDoc inflater = new Inflater JavaDoc();
543         inflater.setInput(deflated);
544         try {
545             inflater.inflate(inflated);
546         }
547         catch(DataFormatException JavaDoc dfe) {
548             throw new ExceptionConverter(dfe);
549         }
550     }
551
552 }
553
Popular Tags