Skip to content

Commit

Permalink
Merge pull request #801 from tledoux/newGpsTags
Browse files Browse the repository at this point in the history
Add new GPSHPositioningError tag
  • Loading branch information
carlwilson authored Jan 10, 2023
2 parents 9beaf49 + 6894c72 commit 48cc789
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.util.logging.Logger;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
* Encapsulation of the NISO Z39.87-2002 / AIIM 20-2002 Data Dictionary --
Expand Down Expand Up @@ -1466,9 +1467,9 @@ public void setCompressionScheme (int scheme)
* TIFF dates get converted to ISO 8601 format.
* @param date Date/time created
*/
public void setDateTimeCreated (String date)
public void setDateTimeCreated(String date)
{
_dateTimeCreated = make8601Valid (date);
_dateTimeCreated = make8601Valid(date);
}

/** Set 9.1.1 DateTimeProcessed.
Expand All @@ -1477,7 +1478,7 @@ public void setDateTimeCreated (String date)
*/
public void setDateTimeProcessed (String date)
{
_dateTimeProcessed = make8601Valid (date);
_dateTimeProcessed = make8601Valid(date);
}

/** Set 7.5 Device source.
Expand Down Expand Up @@ -2229,32 +2230,26 @@ public void setViewerData (Property viewerData)
_viewerData = viewerData;
}

/* Canonicizes (canonizes? whatever) a date to ISO
/* Normalizes a date to ISO
* 8601 format. Returns null if it can't make sense of
* it. Returns the date unchanged if it's already
* canonical. Initially this converts TIFF dates to ISO.
*/
private String make8601Valid (String date)
{
try {
if (date.charAt (4) == ':') {
// It's a TIFF date, or a good imitation of one.
// TIFF dates have exact offsets, making things easy.
String yr = date.substring (0, 4);
String mo = date.substring (5, 7);
String da = date.substring (8, 10);
String hr = date.substring (11, 13);
String mi = date.substring (14, 16);
String se = date.substring (17, 19);
return yr + "-" + mo + "-" + da + "T" +
hr + TIME_SEP + mi + TIME_SEP + se;
}
return date; // default
* in ISO format. Initially this converts TIFF dates to ISO.
*/
protected static String make8601Valid(String date) {
final Pattern pIsoDate = Pattern.compile("(\\d{4})\\-([01]\\d)\\-([0-3]\\d)T([0-2]\\d):([0-5]\\d):([0-5]\\d)");
final Pattern pTiffDate = Pattern.compile("(\\d{4}).([01]\\d).([0-3]\\d).([0-2]\\d).([0-5]\\d).([0-5]\\d)");
if (pIsoDate.matcher(date).matches()) {
return date;
}
catch (Exception e) {
// Malformed date
return null;
Matcher m = pTiffDate.matcher(date);
if (m.matches()) {
String isoDate = String.format("%s-%s-%sT%s:%s:%s",
m.group(1), m.group(2), m.group(3), m.group(4), m.group(5), m.group(6));
if (pIsoDate.matcher(isoDate).matches()) {
return isoDate;
}
}
return null;
}

public static String extractIccProfileDescription(byte[] data) throws IllegalArgumentException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,15 @@
public class NisoImageMetadataTest {
private final static String ERROR_TEST = "Not a icc profile ";

@Test
public void testMake8601Valid() {
assertEquals("2020-10-20T23:58:45", NisoImageMetadata.make8601Valid("2020-10-20T23:58:45"));
assertEquals("2020-10-20T23:58:45", NisoImageMetadata.make8601Valid("2020:10:20 23:58:45"));
assertEquals("2020-10-20T23:58:45", NisoImageMetadata.make8601Valid("2020.10.20 23.58.45"));
assertNull(NisoImageMetadata.make8601Valid("2020:10:20 23:58:73"));
assertNull(NisoImageMetadata.make8601Valid("2020:10:20"));
}

@Test
public void testExtractIccProfileDescriptionBad() {
final byte ANY_BYTE_1 = (byte) 0xFF;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

/**
* Encapsulation of a GPSInfo IFD (for TIFF/EP and Exif).
* See https://exiftool.org/TagNames/GPS.html
*/
public class GPSInfoIFD extends IFD {
/******************************************************************
Expand Down Expand Up @@ -83,6 +84,8 @@ public class GPSInfoIFD extends IFD {
private static final int GPSDATESTAMP = 29;
/** GPSDifferential tag. */
private static final int GPSDIFFERENTIAL = 30;
/** GPSHPositioningError tag. */
private static final int GPSHPOSITIONINGERROR = 31;

/******************************************************************
* PRIVATE INSTANCE FIELDS.
Expand Down Expand Up @@ -153,6 +156,8 @@ public class GPSInfoIFD extends IFD {
private String _gpsDateStamp;
/** GPSDifferential (30). */
private int _gpsDifferential;
/** GPSHPositioningError (31). */
private Rational _gpsHPositioningError;

/******************************************************************
* CLASS CONSTRUCTOR.
Expand Down Expand Up @@ -256,6 +261,11 @@ public Rational getGPSDOP() {
return _gpsDOP;
}

/** Get the GPSHPositioningError (31). */
public Rational getGPSHPositioningError() {
return _gpsHPositioningError;
}

/** Get the GPSImgDirection (17). */
public Rational getGPSImgDirection() {
return _gpsImgDirection;
Expand Down Expand Up @@ -461,6 +471,11 @@ public Property getProperty(boolean rawOutput) {
entries.add(new Property("GPSDifferential", PropertyType.INTEGER,
new Integer(_gpsDifferential)));

if (_gpsHPositioningError != null) {
entries.add(new Property("GPSHPositioningError", PropertyType.RATIONAL,
_gpsHPositioningError));
}

return propertyHeader("GPSInfo", entries);
}

Expand Down Expand Up @@ -520,6 +535,10 @@ public void lookupTag(int tag, int type, long count, long value)
checkType(tag, type, RATIONAL);
checkCount(tag, count, 1);
_gpsDOP = readRational(count, value);
} else if (tag == GPSHPOSITIONINGERROR) {
checkType(tag, type, RATIONAL);
checkCount(tag, count, 1);
_gpsHPositioningError = readRational(count, value);
} else if (tag == GPSIMGDIRECTION) {
checkType(tag, type, RATIONAL);
checkCount(tag, count, 1);
Expand Down

0 comments on commit 48cc789

Please sign in to comment.