in src/main/java/org/apache/commons/imaging/formats/tiff/write/AbstractTiffImageWriter.java [201:356]
protected TiffOutputSummary validateDirectories(final TiffOutputSet outputSet) throws ImagingException {
if (outputSet.isEmpty()) {
throw new ImagingException("No directories.");
}
TiffOutputDirectory exifDirectory = null;
TiffOutputDirectory gpsDirectory = null;
TiffOutputDirectory interoperabilityDirectory = null;
TiffOutputField exifDirectoryOffsetField = null;
TiffOutputField gpsDirectoryOffsetField = null;
TiffOutputField interoperabilityDirectoryOffsetField = null;
final List<Integer> directoryIndices = new ArrayList<>();
final Map<Integer, TiffOutputDirectory> directoryTypeMap = new HashMap<>();
for (final TiffOutputDirectory directory : outputSet) {
final int dirType = directory.getType();
directoryTypeMap.put(dirType, directory);
// Debug.debug("validating dirType", dirType + " ("
// + directory.getFields().size() + " fields)");
if (dirType < 0) {
switch (dirType) {
case TiffDirectoryConstants.DIRECTORY_TYPE_EXIF:
if (exifDirectory != null) {
throw new ImagingException("More than one EXIF directory.");
}
exifDirectory = directory;
break;
case TiffDirectoryConstants.DIRECTORY_TYPE_GPS:
if (gpsDirectory != null) {
throw new ImagingException("More than one GPS directory.");
}
gpsDirectory = directory;
break;
case TiffDirectoryConstants.DIRECTORY_TYPE_INTEROPERABILITY:
if (interoperabilityDirectory != null) {
throw new ImagingException("More than one Interoperability directory.");
}
interoperabilityDirectory = directory;
break;
default:
throw new ImagingException("Unknown directory: " + dirType);
}
} else {
if (directoryIndices.contains(dirType)) {
throw new ImagingException("More than one directory with index: " + dirType + ".");
}
directoryIndices.add(dirType);
// dirMap.put(arg0, arg1)
}
final HashSet<Integer> fieldTags = new HashSet<>();
for (final TiffOutputField field : directory) {
if (fieldTags.contains(field.tag)) {
throw new ImagingException("Tag (" + field.tagInfo.getDescription() + ") appears twice in directory.");
}
fieldTags.add(field.tag);
if (field.tag == ExifTagConstants.EXIF_TAG_EXIF_OFFSET.tag) {
if (exifDirectoryOffsetField != null) {
throw new ImagingException("More than one Exif directory offset field.");
}
exifDirectoryOffsetField = field;
} else if (field.tag == ExifTagConstants.EXIF_TAG_INTEROP_OFFSET.tag) {
if (interoperabilityDirectoryOffsetField != null) {
throw new ImagingException("More than one Interoperability directory offset field.");
}
interoperabilityDirectoryOffsetField = field;
} else if (field.tag == ExifTagConstants.EXIF_TAG_GPSINFO.tag) {
if (gpsDirectoryOffsetField != null) {
throw new ImagingException("More than one GPS directory offset field.");
}
gpsDirectoryOffsetField = field;
}
}
// directory.
}
if (directoryIndices.isEmpty()) {
throw new ImagingException("Missing root directory.");
}
// "normal" TIFF directories should have continous indices starting with
// 0, ie. 0, 1, 2...
Collections.sort(directoryIndices);
TiffOutputDirectory previousDirectory = null;
for (int i = 0; i < directoryIndices.size(); i++) {
final Integer index = directoryIndices.get(i);
if (index != i) {
throw new ImagingException("Missing directory: " + i + ".");
}
// set up chain of directory references for "normal" directories.
final TiffOutputDirectory directory = directoryTypeMap.get(index);
if (null != previousDirectory) {
previousDirectory.setNextDirectory(directory);
}
previousDirectory = directory;
}
final TiffOutputDirectory rootDirectory = directoryTypeMap.get(TiffDirectoryConstants.DIRECTORY_TYPE_ROOT);
// prepare results
final TiffOutputSummary result = new TiffOutputSummary(byteOrder, rootDirectory, directoryTypeMap);
if (interoperabilityDirectory == null && interoperabilityDirectoryOffsetField != null) {
// perhaps we should just discard field?
throw new ImagingException("Output set has Interoperability Directory Offset field, but no Interoperability Directory");
}
if (interoperabilityDirectory != null) {
if (exifDirectory == null) {
exifDirectory = outputSet.addExifDirectory();
}
if (interoperabilityDirectoryOffsetField == null) {
interoperabilityDirectoryOffsetField = TiffOutputField.createOffsetField(ExifTagConstants.EXIF_TAG_INTEROP_OFFSET, byteOrder);
exifDirectory.add(interoperabilityDirectoryOffsetField);
}
result.add(interoperabilityDirectory, interoperabilityDirectoryOffsetField);
}
// make sure offset fields and offset'd directories correspond.
if (exifDirectory == null && exifDirectoryOffsetField != null) {
// perhaps we should just discard field?
throw new ImagingException("Output set has Exif Directory Offset field, but no Exif Directory");
}
if (exifDirectory != null) {
if (exifDirectoryOffsetField == null) {
exifDirectoryOffsetField = TiffOutputField.createOffsetField(ExifTagConstants.EXIF_TAG_EXIF_OFFSET, byteOrder);
rootDirectory.add(exifDirectoryOffsetField);
}
result.add(exifDirectory, exifDirectoryOffsetField);
}
if (gpsDirectory == null && gpsDirectoryOffsetField != null) {
// perhaps we should just discard field?
throw new ImagingException("Output set has GPS Directory Offset field, but no GPS Directory");
}
if (gpsDirectory != null) {
if (gpsDirectoryOffsetField == null) {
gpsDirectoryOffsetField = TiffOutputField.createOffsetField(ExifTagConstants.EXIF_TAG_GPSINFO, byteOrder);
rootDirectory.add(gpsDirectoryOffsetField);
}
result.add(gpsDirectory, gpsDirectoryOffsetField);
}
return result;
// Debug.debug();
}