Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

4/4 Support GeoTIFF data in TIFF #586

Open
wants to merge 13 commits into
base: main
Choose a base branch
from
4 changes: 3 additions & 1 deletion Source/com/drew/imaging/FileTypeDetector.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 Drew Noakes and contributors
* Copyright 2002-2022 Drew Noakes and contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -54,6 +54,8 @@ public class FileTypeDetector
_root.addPath(FileType.Jpeg, new byte[]{(byte)0xff, (byte)0xd8});
_root.addPath(FileType.Tiff, "II".getBytes(), new byte[]{0x2a, 0x00});
_root.addPath(FileType.Tiff, "MM".getBytes(), new byte[]{0x00, 0x2a});
_root.addPath(FileType.Tiff, "II".getBytes(), new byte[]{0x2b, 0x00}); // BigTIFF
_root.addPath(FileType.Tiff, "MM".getBytes(), new byte[]{0x00, 0x2b}); // BigTIFF
_root.addPath(FileType.Psd, "8BPS".getBytes());
_root.addPath(FileType.Png, new byte[]{(byte)0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A, 0x00, 0x00, 0x00, 0x0D, 0x49, 0x48, 0x44, 0x52});
_root.addPath(FileType.Bmp, "BM".getBytes()); // Standard Bitmap Windows and OS/2
Expand Down
4 changes: 2 additions & 2 deletions Source/com/drew/imaging/jpeg/JpegMetadataReader.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 Drew Noakes and contributors
* Copyright 2002-2022 Drew Noakes and contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -126,7 +126,7 @@ public static void process(@NotNull Metadata metadata, @NotNull InputStream inpu
processJpegSegmentData(metadata, readers, segmentData);
}

public static void processJpegSegmentData(Metadata metadata, Iterable<JpegSegmentMetadataReader> readers, JpegSegmentData segmentData)
public static void processJpegSegmentData(Metadata metadata, Iterable<JpegSegmentMetadataReader> readers, JpegSegmentData segmentData) throws IOException
{
// Pass the appropriate byte arrays to each reader.
for (JpegSegmentMetadataReader reader : readers) {
Expand Down
25 changes: 24 additions & 1 deletion Source/com/drew/imaging/jpeg/JpegSegmentMetadataReader.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,27 @@
/*
* Copyright 2002-2022 Drew Noakes and contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* More information about this project is available at:
*
* https://drewnoakes.com/code/exif/
* https://github.com/drewnoakes/metadata-extractor
*/
package com.drew.imaging.jpeg;

import java.io.IOException;

import com.drew.lang.annotations.NotNull;
import com.drew.metadata.Metadata;

Expand All @@ -21,6 +43,7 @@ public interface JpegSegmentMetadataReader
* encountered in the original file.
* @param metadata The {@link Metadata} object into which extracted values should be merged.
* @param segmentType The {@link JpegSegmentType} being read.
* @throws IOException an error occurred while accessing the required data
*/
void readJpegSegments(@NotNull final Iterable<byte[]> segments, @NotNull final Metadata metadata, @NotNull final JpegSegmentType segmentType);
void readJpegSegments(@NotNull final Iterable<byte[]> segments, @NotNull final Metadata metadata, @NotNull final JpegSegmentType segmentType) throws IOException;
}
4 changes: 2 additions & 2 deletions Source/com/drew/imaging/png/PngMetadataReader.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 Drew Noakes and contributors
* Copyright 2002-2022 Drew Noakes and contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -331,7 +331,7 @@ private static void processChunk(@NotNull Metadata metadata, @NotNull PngChunk c
} else if (chunkType.equals(PngChunkType.eXIf)) {
try {
ExifTiffHandler handler = new ExifTiffHandler(metadata, null, 0);
new TiffReader().processTiff(new ByteArrayReader(bytes), handler, 0);
new TiffReader().processTiff(new ByteArrayReader(bytes), handler);
} catch (TiffProcessingException ex) {
PngDirectory directory = new PngDirectory(PngChunkType.eXIf);
directory.addError(ex.getMessage());
Expand Down
16 changes: 14 additions & 2 deletions Source/com/drew/imaging/tiff/TiffDataFormat.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 Drew Noakes and contributors
* Copyright 2002-2022 Drew Noakes and contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -42,6 +42,10 @@ public class TiffDataFormat
public static final int CODE_RATIONAL_S = 10;
public static final int CODE_SINGLE = 11;
public static final int CODE_DOUBLE = 12;
// From BigTIFF
public static final int CODE_INT64_U = 16;
public static final int CODE_INT64_S = 17;
public static final int CODE_IFD8 = 18;

@NotNull public static final TiffDataFormat INT8_U = new TiffDataFormat("BYTE", CODE_INT8_U, 1);
@NotNull public static final TiffDataFormat STRING = new TiffDataFormat("STRING", CODE_STRING, 1);
Expand All @@ -55,14 +59,18 @@ public class TiffDataFormat
@NotNull public static final TiffDataFormat RATIONAL_S = new TiffDataFormat("SRATIONAL", CODE_RATIONAL_S, 8);
@NotNull public static final TiffDataFormat SINGLE = new TiffDataFormat("SINGLE", CODE_SINGLE, 4);
@NotNull public static final TiffDataFormat DOUBLE = new TiffDataFormat("DOUBLE", CODE_DOUBLE, 8);
// From BigTIFF
@NotNull public static final TiffDataFormat INT64_U = new TiffDataFormat("ULONG8", CODE_INT64_U, 8);
@NotNull public static final TiffDataFormat INT64_S = new TiffDataFormat("SLONG8", CODE_INT64_S, 8);
@NotNull public static final TiffDataFormat IFD8 = new TiffDataFormat("IFD8", CODE_IFD8, 8);

@NotNull
private final String _name;
private final int _tiffFormatCode;
private final int _componentSizeBytes;

@Nullable
public static TiffDataFormat fromTiffFormatCode(int tiffFormatCode)
public static TiffDataFormat fromTiffFormatCode(int tiffFormatCode, boolean isBigTiff)
{
switch (tiffFormatCode) {
case 1: return INT8_U;
Expand All @@ -77,6 +85,10 @@ public static TiffDataFormat fromTiffFormatCode(int tiffFormatCode)
case 10: return RATIONAL_S;
case 11: return SINGLE;
case 12: return DOUBLE;
// From BigTIFF
case 16: return isBigTiff ? INT64_U : null;
case 17: return isBigTiff ? INT64_S : null;
case 18: return isBigTiff ? IFD8 : null;
}
return null;
}
Expand Down
29 changes: 20 additions & 9 deletions Source/com/drew/imaging/tiff/TiffHandler.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 Drew Noakes and contributors
* Copyright 2002-2022 Drew Noakes and contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -20,14 +20,12 @@
*/
package com.drew.imaging.tiff;

import com.drew.lang.RandomAccessReader;
import com.drew.lang.Rational;
import com.drew.lang.annotations.NotNull;
import com.drew.lang.annotations.Nullable;
import com.drew.metadata.StringValue;

import java.io.IOException;
import java.util.Set;

/**
* Interface of an class capable of handling events raised during the reading of a TIFF file
Expand All @@ -44,22 +42,31 @@ public interface TiffHandler
* validation or perhaps differentiating the type of mapping to use for observed tags and IFDs.
*
* @param marker the 2-byte value found at position 2 of the TIFF header
* @return The TIFF standard via which to interpret the data stream.
*/
void setTiffMarker(int marker) throws TiffProcessingException;
TiffStandard processTiffMarker(short marker) throws TiffProcessingException;

boolean tryEnterSubIfd(int tagId);
boolean hasFollowerIfd();

void endingIFD();
void endingIFD(TiffReaderContext context);

@Nullable
Long tryCustomProcessFormat(int tagId, int formatCode, long componentCount);

boolean customProcessTag(int tagOffset,
@NotNull Set<Integer> processedIfdOffsets,
int tiffHeaderOffset,
@NotNull RandomAccessReader reader,
/**
* Allows handlers to provide custom logic for a given tag.
*
* @param context Context for the TIFF read operation.
* @param tagId The ID of the tag being processed.
* @param valueOffset The offset into the data stream at which the tag's value starts.
* @param byteCount The number of bytes that the tag's value spans.
* @return {@code true} if processing was successful and default processing should be suppressed, otherwise {@code false}
* @throws IOException if any I/O error occurs
*/
boolean customProcessTag(TiffReaderContext context,
int tagId,
int valueOffset,
int byteCount) throws IOException;

void warn(@NotNull String message);
Expand All @@ -85,4 +92,8 @@ boolean customProcessTag(int tagOffset,
void setInt32sArray(int tagId, @NotNull int[] array);
void setInt32u(int tagId, long int32u);
void setInt32uArray(int tagId, @NotNull long[] array);
void setInt64S(int tagId, long int64S);
void setInt64SArray(int tagId, @NotNull long[] array);
void setInt64U(int tagId, long int64U);
void setInt64UArray(int tagId, @NotNull long[] array);
}
4 changes: 2 additions & 2 deletions Source/com/drew/imaging/tiff/TiffMetadataReader.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 Drew Noakes and contributors
* Copyright 2002-2022 Drew Noakes and contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -68,7 +68,7 @@ public static Metadata readMetadata(@NotNull RandomAccessReader reader) throws I
{
Metadata metadata = new Metadata();
ExifTiffHandler handler = new ExifTiffHandler(metadata, null, 0);
new TiffReader().processTiff(reader, handler, 0);
new TiffReader().processTiff(reader, handler);
return metadata;
}
}
Loading
Loading