1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.imaging.formats.tiff.write;
18
19 import static org.apache.commons.imaging.formats.tiff.constants.TiffConstants.DEFAULT_TIFF_BYTE_ORDER;
20
21 import java.nio.ByteOrder;
22 import java.util.ArrayList;
23 import java.util.Iterator;
24 import java.util.List;
25
26 import org.apache.commons.imaging.ImagingException;
27 import org.apache.commons.imaging.common.RationalNumber;
28 import org.apache.commons.imaging.formats.tiff.constants.GpsTagConstants;
29 import org.apache.commons.imaging.formats.tiff.constants.TiffDirectoryConstants;
30 import org.apache.commons.imaging.formats.tiff.taginfos.TagInfo;
31 import org.apache.commons.imaging.internal.Debug;
32
33 public final class TiffOutputSet implements Iterable<TiffOutputDirectory> {
34
35 private static final String NEWLINE = System.lineSeparator();
36 public final ByteOrder byteOrder;
37 private final List<TiffOutputDirectory> directories = new ArrayList<>();
38
39 public TiffOutputSet() {
40 this(DEFAULT_TIFF_BYTE_ORDER);
41 }
42
43 public TiffOutputSet(final ByteOrder byteOrder) {
44 this.byteOrder = byteOrder;
45 }
46
47 public void addDirectory(final TiffOutputDirectory directory) throws ImagingException {
48 if (null != findDirectory(directory.getType())) {
49 throw new ImagingException("Output set already contains a directory of that type.");
50 }
51 directories.add(directory);
52 }
53
54 public TiffOutputDirectory addExifDirectory() throws ImagingException {
55 final TiffOutputDirectory result = new TiffOutputDirectory(TiffDirectoryConstants.DIRECTORY_TYPE_EXIF, byteOrder);
56 addDirectory(result);
57 return result;
58 }
59
60 public TiffOutputDirectory addGpsDirectory() throws ImagingException {
61 final TiffOutputDirectory result = new TiffOutputDirectory(TiffDirectoryConstants.DIRECTORY_TYPE_GPS, byteOrder);
62 addDirectory(result);
63 return result;
64 }
65
66 public TiffOutputDirectory addInteroperabilityDirectory() throws ImagingException {
67 getOrCreateExifDirectory();
68
69 final TiffOutputDirectory result = new TiffOutputDirectory(TiffDirectoryConstants.DIRECTORY_TYPE_INTEROPERABILITY, byteOrder);
70 addDirectory(result);
71 return result;
72 }
73
74 public TiffOutputDirectory addRootDirectory() throws ImagingException {
75 final TiffOutputDirectory result = new TiffOutputDirectory(TiffDirectoryConstants.DIRECTORY_TYPE_ROOT, byteOrder);
76 addDirectory(result);
77 return result;
78 }
79
80 public void dump() {
81 Debug.debug(this.toString());
82 }
83
84 public TiffOutputDirectory findDirectory(final int directoryType) {
85 for (final TiffOutputDirectory directory : directories) {
86 if (directory.getType() == directoryType) {
87 return directory;
88 }
89 }
90 return null;
91 }
92
93 public TiffOutputField findField(final int tag) {
94 for (final TiffOutputDirectory directory : directories) {
95 final TiffOutputField field = directory.findField(tag);
96 if (null != field) {
97 return field;
98 }
99 }
100 return null;
101 }
102
103 public TiffOutputField findField(final TagInfo tagInfo) {
104 return findField(tagInfo.tag);
105 }
106
107 public List<TiffOutputDirectory> getDirectories() {
108 return new ArrayList<>(directories);
109 }
110
111 public TiffOutputDirectory getExifDirectory() {
112 return findDirectory(TiffDirectoryConstants.DIRECTORY_TYPE_EXIF);
113 }
114
115 public TiffOutputDirectory getGpsDirectory() {
116 return findDirectory(TiffDirectoryConstants.DIRECTORY_TYPE_GPS);
117 }
118
119 public TiffOutputDirectory getInteroperabilityDirectory() {
120 return findDirectory(TiffDirectoryConstants.DIRECTORY_TYPE_INTEROPERABILITY);
121 }
122
123 public TiffOutputDirectory getOrCreateExifDirectory() throws ImagingException {
124
125 getOrCreateRootDirectory();
126
127 final TiffOutputDirectory result = findDirectory(TiffDirectoryConstants.DIRECTORY_TYPE_EXIF);
128 if (null != result) {
129 return result;
130 }
131 return addExifDirectory();
132 }
133
134 public TiffOutputDirectory getOrCreateGpsDirectory() throws ImagingException {
135
136 getOrCreateExifDirectory();
137
138 final TiffOutputDirectory result = findDirectory(TiffDirectoryConstants.DIRECTORY_TYPE_GPS);
139 if (null != result) {
140 return result;
141 }
142 return addGpsDirectory();
143 }
144
145 public TiffOutputDirectory getOrCreateRootDirectory() throws ImagingException {
146 final TiffOutputDirectory result = findDirectory(TiffDirectoryConstants.DIRECTORY_TYPE_ROOT);
147 if (null != result) {
148 return result;
149 }
150 return addRootDirectory();
151 }
152
153 protected List<AbstractTiffOutputItem> getOutputItems(final TiffOutputSummary outputSummary) throws ImagingException {
154 final List<AbstractTiffOutputItem> result = new ArrayList<>();
155
156 for (final TiffOutputDirectory directory : directories) {
157 result.addAll(directory.getOutputItems(outputSummary));
158 }
159
160 return result;
161 }
162
163 public TiffOutputDirectory getRootDirectory() {
164 return findDirectory(TiffDirectoryConstants.DIRECTORY_TYPE_ROOT);
165 }
166
167 public boolean isEmpty() {
168 return directories.isEmpty();
169 }
170
171 @Override
172 public Iterator<TiffOutputDirectory> iterator() {
173 return directories.iterator();
174 }
175
176 public void removeField(final int tag) {
177 for (final TiffOutputDirectory directory : directories) {
178 directory.removeField(tag);
179 }
180 }
181
182 public void removeField(final TagInfo tagInfo) {
183 removeField(tagInfo.tag);
184 }
185
186
187
188
189
190
191
192
193 public void setGpsInDegrees(double longitude, double latitude) throws ImagingException {
194 final TiffOutputDirectory gpsDirectory = getOrCreateGpsDirectory();
195
196 gpsDirectory.removeField(GpsTagConstants.GPS_TAG_GPS_VERSION_ID);
197 gpsDirectory.add(GpsTagConstants.GPS_TAG_GPS_VERSION_ID, GpsTagConstants.gpsVersion());
198
199 final String longitudeRef = longitude < 0 ? "W" : "E";
200 longitude = Math.abs(longitude);
201 final String latitudeRef = latitude < 0 ? "S" : "N";
202 latitude = Math.abs(latitude);
203
204 gpsDirectory.removeField(GpsTagConstants.GPS_TAG_GPS_LONGITUDE_REF);
205 gpsDirectory.add(GpsTagConstants.GPS_TAG_GPS_LONGITUDE_REF, longitudeRef);
206
207 gpsDirectory.removeField(GpsTagConstants.GPS_TAG_GPS_LATITUDE_REF);
208 gpsDirectory.add(GpsTagConstants.GPS_TAG_GPS_LATITUDE_REF, latitudeRef);
209
210 {
211 double value = longitude;
212 final double longitudeDegrees = (long) value;
213 value %= 1;
214 value *= 60.0;
215 final double longitudeMinutes = (long) value;
216 value %= 1;
217 value *= 60.0;
218 final double longitudeSeconds = value;
219
220 gpsDirectory.removeField(GpsTagConstants.GPS_TAG_GPS_LONGITUDE);
221 gpsDirectory.add(GpsTagConstants.GPS_TAG_GPS_LONGITUDE, RationalNumber.valueOf(longitudeDegrees), RationalNumber.valueOf(longitudeMinutes),
222 RationalNumber.valueOf(longitudeSeconds));
223 }
224
225 {
226 double value = latitude;
227 final double latitudeDegrees = (long) value;
228 value %= 1;
229 value *= 60.0;
230 final double latitudeMinutes = (long) value;
231 value %= 1;
232 value *= 60.0;
233 final double latitudeSeconds = value;
234
235 gpsDirectory.removeField(GpsTagConstants.GPS_TAG_GPS_LATITUDE);
236 gpsDirectory.add(GpsTagConstants.GPS_TAG_GPS_LATITUDE, RationalNumber.valueOf(latitudeDegrees), RationalNumber.valueOf(latitudeMinutes),
237 RationalNumber.valueOf(latitudeSeconds));
238 }
239
240 }
241
242 @Override
243 public String toString() {
244 return toString(null);
245 }
246
247 public String toString(String prefix) {
248 if (prefix == null) {
249 prefix = "";
250 }
251
252 final StringBuilder result = new StringBuilder(39);
253
254 result.append(prefix);
255 result.append("TiffOutputSet {");
256 result.append(NEWLINE);
257
258 result.append(prefix);
259 result.append("byteOrder: ");
260 result.append(byteOrder);
261 result.append(NEWLINE);
262
263 for (int i = 0; i < directories.size(); i++) {
264 final TiffOutputDirectory directory = directories.get(i);
265 result.append(String.format("%s\tdirectory %d: %s (%d)%n", prefix, i, directory.description(), directory.getType()));
266
267 for (final TiffOutputField field : directory) {
268 result.append(prefix);
269 result.append("\t\tfield ").append(i).append(": ").append(field.tagInfo);
270 result.append(NEWLINE);
271 }
272 }
273 result.append(prefix);
274
275 result.append('}');
276 result.append(NEWLINE);
277
278 return result.toString();
279 }
280
281 }