~hjd/ubuntu/wily/xmlgraphics-commons/debian-merged

« back to all changes in this revision

Viewing changes to src/java/org/apache/xmlgraphics/image/codec/tiff/TIFFDirectory.java

  • Committer: Hans Joachim Desserud
  • Date: 2015-11-11 18:22:53 UTC
  • mfrom: (9.1.5 sid)
  • Revision ID: hans_joachim_desserud-20151111182253-zwi0frfm97j0wddn
  * Merge from Debian unstable.  Remaining changes:
    - d/control: Drop dependencies required for unit testing as they
      include libmockito-java which would pull maven into main, disable unit
      test execution.

Show diffs side-by-side

added added

removed removed

Lines of Context:
15
15
 * limitations under the License.
16
16
 */
17
17
 
18
 
/* $Id: TIFFDirectory.java 1345683 2012-06-03 14:50:33Z gadams $ */
 
18
/* $Id: TIFFDirectory.java 1681698 2015-05-26 07:49:35Z ssteiner $ */
19
19
 
20
20
package org.apache.xmlgraphics.image.codec.tiff;
21
21
 
60
60
 * be removed or changed in future releases of JAI.</b>
61
61
 *
62
62
 * @see TIFFField
63
 
 * @version $Id: TIFFDirectory.java 1345683 2012-06-03 14:50:33Z gadams $
 
63
 * @version $Id: TIFFDirectory.java 1681698 2015-05-26 07:49:35Z ssteiner $
64
64
 */
65
65
public class TIFFDirectory implements Serializable {
66
66
 
 
67
    private static final long serialVersionUID = 2007844835460959003L;
67
68
    /** A boolean storing the endianness of the stream. */
68
69
    boolean isBigEndian;
69
70
 
77
78
    Map fieldIndex = new HashMap();
78
79
 
79
80
    /** The offset of this IFD. */
80
 
    long IFDOffset = 8;
 
81
    long ifdOffset = 8;
81
82
 
82
83
    /** The offset of the next IFD. */
83
 
    long nextIFDOffset = 0;
 
84
    long nextIFDOffset;
84
85
 
85
86
    /** The default constructor. */
86
 
    TIFFDirectory() {}
 
87
    TIFFDirectory() { }
87
88
 
88
89
    private static boolean isValidEndianTag(int endian) {
89
90
        return ((endian == 0x4949) || (endian == 0x4d4d));
102
103
    public TIFFDirectory(SeekableStream stream, int directory)
103
104
        throws IOException {
104
105
 
105
 
        long global_save_offset = stream.getFilePointer();
106
 
        long ifd_offset;
 
106
        long globalSaveOffset = stream.getFilePointer();
 
107
        long ifdOffset;
107
108
 
108
109
        // Read the TIFF header
109
110
        stream.seek(0L);
119
120
        }
120
121
 
121
122
        // Get the initial ifd offset as an unsigned int (using a long)
122
 
        ifd_offset = readUnsignedInt(stream);
 
123
        ifdOffset = readUnsignedInt(stream);
123
124
 
124
125
        for (int i = 0; i < directory; i++) {
125
 
            if (ifd_offset == 0L) {
 
126
            if (ifdOffset == 0L) {
126
127
                throw new IllegalArgumentException(PropertyUtil.getString("TIFFDirectory3"));
127
128
            }
128
129
 
129
 
            stream.seek(ifd_offset);
 
130
            stream.seek(ifdOffset);
130
131
            long entries = readUnsignedShort(stream);
131
 
            stream.skip(12*entries);
 
132
            stream.skip(12 * entries);
132
133
 
133
 
            ifd_offset = readUnsignedInt(stream);
 
134
            ifdOffset = readUnsignedInt(stream);
134
135
        }
135
 
        if (ifd_offset == 0L) {
 
136
        if (ifdOffset == 0L) {
136
137
            throw new IllegalArgumentException(PropertyUtil.getString("TIFFDirectory3"));
137
138
        }
138
139
 
139
 
        stream.seek(ifd_offset);
 
140
        stream.seek(ifdOffset);
140
141
        initialize(stream);
141
 
        stream.seek(global_save_offset);
 
142
        stream.seek(globalSaveOffset);
142
143
    }
143
144
 
144
145
    /**
149
150
     * sequence of IFDs.
150
151
     *
151
152
     * @param stream a SeekableStream to read from.
152
 
     * @param ifd_offset the long byte offset of the directory.
 
153
     * @param ifdOffset the long byte offset of the directory.
153
154
     * @param directory the index of the directory to read beyond the
154
155
     *        one at the current stream offset; zero indicates the IFD
155
156
     *        at the current offset.
156
157
     */
157
 
    public TIFFDirectory(SeekableStream stream, long ifd_offset, int directory)
 
158
    public TIFFDirectory(SeekableStream stream, long ifdOffset, int directory)
158
159
        throws IOException {
159
160
 
160
 
        long global_save_offset = stream.getFilePointer();
 
161
        long globalSaveOffset = stream.getFilePointer();
161
162
        stream.seek(0L);
162
163
        int endian = stream.readUnsignedShort();
163
164
        if (!isValidEndianTag(endian)) {
166
167
        isBigEndian = (endian == 0x4d4d);
167
168
 
168
169
        // Seek to the first IFD.
169
 
        stream.seek(ifd_offset);
 
170
        stream.seek(ifdOffset);
170
171
 
171
172
        // Seek to desired IFD if necessary.
172
173
        int dirNum = 0;
173
 
        while(dirNum < directory) {
 
174
        while (dirNum < directory) {
174
175
            // Get the number of fields in the current IFD.
175
176
            long numEntries = readUnsignedShort(stream);
176
177
 
177
178
            // Skip to the next IFD offset value field.
178
 
            stream.seek(ifd_offset + 12*numEntries);
 
179
            stream.seek(ifdOffset + 12 * numEntries);
179
180
 
180
181
            // Read the offset to the next IFD beyond this one.
181
 
            ifd_offset = readUnsignedInt(stream);
 
182
            ifdOffset = readUnsignedInt(stream);
182
183
 
183
184
            // Seek to the next IFD.
184
 
            stream.seek(ifd_offset);
 
185
            stream.seek(ifdOffset);
185
186
 
186
187
            // Increment the directory.
187
188
            dirNum++;
188
189
        }
189
190
 
190
191
        initialize(stream);
191
 
        stream.seek(global_save_offset);
 
192
        stream.seek(globalSaveOffset);
192
193
    }
193
194
 
194
 
    private static final int[] sizeOfType = {
 
195
    private static final int[] SIZE_OF_TYPE = {
195
196
        0, //  0 = n/a
196
197
        1, //  1 = byte
197
198
        1, //  2 = ascii
209
210
 
210
211
    private void initialize(SeekableStream stream) throws IOException {
211
212
        long nextTagOffset;
212
 
        int i, j;
 
213
        int i;
 
214
        int j;
213
215
 
214
 
        IFDOffset = stream.getFilePointer();
 
216
        ifdOffset = stream.getFilePointer();
215
217
 
216
218
        numEntries = readUnsignedShort(stream);
217
219
        fields = new TIFFField[numEntries];
228
230
            try {
229
231
                // If the tag data can't fit in 4 bytes, the next 4 bytes
230
232
                // contain the starting offset of the data
231
 
                if (count*sizeOfType[type] > 4) {
 
233
                if (count * SIZE_OF_TYPE[type] > 4) {
232
234
                    value = (int)(readUnsignedInt(stream));
233
235
                    stream.seek(value);
234
236
                }
239
241
                continue;
240
242
            }
241
243
 
242
 
            fieldIndex.put(new Integer(tag), new Integer(i));
 
244
            fieldIndex.put(tag, i);
243
245
            Object obj = null;
244
246
 
245
247
            switch (type) {
253
255
                if (type == TIFFField.TIFF_ASCII) {
254
256
 
255
257
                    // Can be multiple strings
256
 
                    int index = 0, prevIndex = 0;
 
258
                    int index = 0;
 
259
                    int prevIndex = 0;
257
260
                    List v = new ArrayList();
258
261
 
259
262
                    while (index < count) {
260
263
 
261
 
                        while ((index < count) && (bvalues[index++] != 0));
 
264
                        while ((index < count) && (bvalues[index++] != 0)) {
 
265
                            // NOP
 
266
                        }
262
267
 
263
268
                        // When we encountered zero, means one string has ended
264
269
                        v.add(new String(bvalues, prevIndex,
265
 
                                         (index - prevIndex)) );
 
270
                                         (index - prevIndex), "UTF-8"));
266
271
                        prevIndex = index;
267
272
                    }
268
273
 
364
369
     * or null if the tag is not present.
365
370
     */
366
371
    public TIFFField getField(int tag) {
367
 
        Integer i = (Integer)fieldIndex.get(new Integer(tag));
 
372
        Integer i = (Integer)fieldIndex.get(tag);
368
373
        if (i == null) {
369
374
            return null;
370
375
        } else {
371
 
            return fields[i.intValue()];
 
376
            return fields[i];
372
377
        }
373
378
    }
374
379
 
376
381
     * Returns true if a tag appears in the directory.
377
382
     */
378
383
    public boolean isTagPresent(int tag) {
379
 
        return fieldIndex.containsKey(new Integer(tag));
 
384
        return fieldIndex.containsKey(tag);
380
385
    }
381
386
 
382
387
    /**
389
394
        int i = 0;
390
395
 
391
396
        while (iter.hasNext()) {
392
 
            tags[i++] = ((Integer)iter.next()).intValue();
 
397
            tags[i++] = (Integer) iter.next();
393
398
        }
394
399
 
395
400
        return tags;
410
415
     * TIFF_UNDEFINED.
411
416
     */
412
417
    public byte getFieldAsByte(int tag, int index) {
413
 
        Integer i = (Integer)fieldIndex.get(new Integer(tag));
414
 
        byte [] b = (fields[i.intValue()]).getAsBytes();
 
418
        Integer i = (Integer)fieldIndex.get(tag);
 
419
        byte [] b = (fields[i]).getAsBytes();
415
420
        return b[index];
416
421
    }
417
422
 
432
437
     * TIFF_SHORT, TIFF_SSHORT, TIFF_SLONG or TIFF_LONG.
433
438
     */
434
439
    public long getFieldAsLong(int tag, int index) {
435
 
        Integer i = (Integer)fieldIndex.get(new Integer(tag));
436
 
        return (fields[i.intValue()]).getAsLong(index);
 
440
        Integer i = (Integer)fieldIndex.get(tag);
 
441
        return (fields[i]).getAsLong(index);
437
442
    }
438
443
 
439
444
    /**
453
458
     * TIFF_ASCII).
454
459
     */
455
460
    public float getFieldAsFloat(int tag, int index) {
456
 
        Integer i = (Integer)fieldIndex.get(new Integer(tag));
457
 
        return fields[i.intValue()].getAsFloat(index);
 
461
        Integer i = (Integer)fieldIndex.get(tag);
 
462
        return fields[i].getAsFloat(index);
458
463
    }
459
464
 
460
465
    /**
473
478
     * TIFF_ASCII).
474
479
     */
475
480
    public double getFieldAsDouble(int tag, int index) {
476
 
        Integer i = (Integer)fieldIndex.get(new Integer(tag));
477
 
        return fields[i.intValue()].getAsDouble(index);
 
481
        Integer i = (Integer)fieldIndex.get(tag);
 
482
        return fields[i].getAsDouble(index);
478
483
    }
479
484
 
480
485
    /**
524
529
        }
525
530
    }
526
531
 
527
 
    private long readLong(SeekableStream stream)
528
 
        throws IOException {
529
 
        if (isBigEndian) {
530
 
            return stream.readLong();
531
 
        } else {
532
 
            return stream.readLongLE();
533
 
        }
534
 
    }
 
532
//    private long readLong(SeekableStream stream)
 
533
//        throws IOException {
 
534
//        if (isBigEndian) {
 
535
//            return stream.readLong();
 
536
//        } else {
 
537
//            return stream.readLongLE();
 
538
//        }
 
539
//    }
535
540
 
536
541
    private float readFloat(SeekableStream stream)
537
542
        throws IOException {
578
583
     * given TIFF file, represented by a <code>SeekableStream</code>.
579
584
     */
580
585
    public static int getNumDirectories(SeekableStream stream)
581
 
        throws IOException{
 
586
        throws IOException {
582
587
        long pointer = stream.getFilePointer(); // Save stream pointer
583
588
 
584
589
        stream.seek(0L);
601
606
 
602
607
            stream.seek(offset);
603
608
            long entries = readUnsignedShort(stream, isBigEndian);
604
 
            stream.skip(12*entries);
 
609
            stream.skip(12 * entries);
605
610
            offset = readUnsignedInt(stream, isBigEndian);
606
611
        }
607
612
 
623
628
     * <code>TIFFDirectory</code>.
624
629
     */
625
630
    public long getIFDOffset() {
626
 
        return IFDOffset;
 
631
        return ifdOffset;
627
632
    }
628
633
 
629
634
    /**