Skip to content

Commit 2c80f00

Browse files
authored
Merge pull request #331 from nagix/issue-331
Improve Quicktime Metadata Atom handling
2 parents fc8aeb3 + 716dbf5 commit 2c80f00

3 files changed

Lines changed: 155 additions & 70 deletions

File tree

Source/com/drew/metadata/mov/metadata/QuickTimeDataHandler.java

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -98,10 +98,37 @@ protected void processKeys(@NotNull SequentialByteArrayReader reader) throws IOE
9898
@Override
9999
protected void processData(@NotNull byte[] payload, @NotNull SequentialByteArrayReader reader) throws IOException
100100
{
101-
// 4 bytes: type indicator
101+
int type = reader.getInt32();
102102
// 4 bytes: locale indicator
103-
reader.skip(8);
104-
String value = new String(reader.getBytes(payload.length - 8));
105-
directory.setString(QuickTimeMetadataDirectory._tagIntegerMap.get(keys.get(currentIndex)), value);
103+
reader.skip(4);
104+
Integer tag = QuickTimeMetadataDirectory._tagIntegerMap.get(keys.get(currentIndex));
105+
if (tag != null) {
106+
int length = payload.length - 8;
107+
switch (type) {
108+
case 1:
109+
directory.setString(tag, reader.getString(length, "UTF-8"));
110+
break;
111+
case 13:
112+
case 14:
113+
case 27:
114+
directory.setByteArray(tag, reader.getBytes(length));
115+
break;
116+
case 22:
117+
byte[] buf = new byte[4];
118+
reader.getBytes(buf, 4 - length, length);
119+
directory.setInt(tag, new SequentialByteArrayReader(buf).getInt32());
120+
break;
121+
case 23:
122+
directory.setFloat(tag, reader.getFloat32());
123+
break;
124+
case 30:
125+
int[] value = new int[length / 4];
126+
for (int i = 0; i < value.length; i++) {
127+
value[i] = reader.getInt32();
128+
}
129+
directory.setIntArray(tag, value);
130+
break;
131+
}
132+
}
106133
}
107134
}

Source/com/drew/metadata/mov/metadata/QuickTimeMetadataDescriptor.java

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
import com.drew.metadata.mov.QuickTimeDescriptor;
2424
import com.drew.metadata.mov.QuickTimeDirectory;
2525

26+
import static com.drew.metadata.mov.metadata.QuickTimeMetadataDirectory.*;
27+
2628
/**
2729
* @author Payton Garland
2830
*/
@@ -36,6 +38,27 @@ public QuickTimeMetadataDescriptor(QuickTimeDirectory directory)
3638
@Override
3739
public String getDescription(int tagType)
3840
{
39-
return super.getDescription(tagType);
41+
switch (tagType) {
42+
case TAG_ARTWORK:
43+
return getArtworkDescription();
44+
case TAG_LOCATION_ROLE:
45+
return getLocationRoleDescription();
46+
default:
47+
return super.getDescription(tagType);
48+
}
49+
}
50+
51+
private String getArtworkDescription()
52+
{
53+
return getByteLengthDescription(TAG_ARTWORK);
54+
}
55+
56+
private String getLocationRoleDescription()
57+
{
58+
return getIndexedDescription(TAG_LOCATION_ROLE, 0,
59+
"Shooting location",
60+
"Real location",
61+
"Fictional location"
62+
);
4063
}
4164
}

Source/com/drew/metadata/mov/metadata/QuickTimeMetadataDirectory.java

Lines changed: 100 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,39 @@ public class QuickTimeMetadataDirectory extends QuickTimeDirectory
3636
// User Metadata Types Holder (0x0500 - 0x05FF)
3737
// https://developer.apple.com/library/content/documentation/QuickTime/QTFF/Metadata/Metadata.html#//apple_ref/doc/uid/TP40000939-CH1-SW43
3838
// https://sno.phy.queensu.ca/~phil/exiftool/TagNames/QuickTime.html#Meta
39+
public static final int TAG_ALBUM = 0x0500;
40+
public static final int TAG_ARTIST = 0x0501;
41+
public static final int TAG_ARTWORK = 0x0502;
42+
public static final int TAG_AUTHOR = 0x0503;
43+
public static final int TAG_COMMENT = 0x0504;
44+
public static final int TAG_COPYRIGHT = 0x0505;
45+
public static final int TAG_CREATION_DATE = 0x0506;
46+
public static final int TAG_DESCRIPTION = 0x0507;
47+
public static final int TAG_DIRECTOR = 0x0508;
48+
public static final int TAG_TITLE = 0x0509;
49+
public static final int TAG_GENRE = 0x050A;
50+
public static final int TAG_INFORMATION = 0x050B;
51+
public static final int TAG_KEYWORDS = 0x050C;
52+
public static final int TAG_LOCATION_ISO6709 = 0x050D;
53+
public static final int TAG_PRODUCER = 0x050E;
54+
public static final int TAG_PUBLISHER = 0x050F;
55+
public static final int TAG_SOFTWARE = 0x0510;
56+
public static final int TAG_YEAR = 0x0511;
57+
public static final int TAG_COLLECTION_USER = 0x0512;
58+
public static final int TAG_RATING_USER = 0x0513;
59+
public static final int TAG_LOCATION_NAME = 0x0514;
60+
public static final int TAG_LOCATION_BODY = 0x0515;
61+
public static final int TAG_LOCATION_NOTE = 0x0516;
62+
public static final int TAG_LOCATION_ROLE = 0x0517;
63+
public static final int TAG_LOCATION_DATE = 0x0518;
64+
public static final int TAG_DIRECTION_FACING = 0x0519;
65+
public static final int TAG_DIRECTION_MOTION = 0x051A;
66+
public static final int TAG_DISPLAY_NAME = 0x051B;
67+
public static final int TAG_CONTENT_IDENTIFIER = 0x051C;
68+
public static final int TAG_MAKE = 0x051D;
69+
public static final int TAG_MODEL = 0x051E;
70+
public static final int TAG_ORIGINATING_SIGNATURE = 0x051F;
71+
public static final int TAG_PIXEL_DENSITY = 0x0520;
3972

4073
public QuickTimeMetadataDirectory()
4174
{
@@ -50,38 +83,39 @@ public QuickTimeMetadataDirectory()
5083

5184
static
5285
{
53-
_tagIntegerMap.put("com.apple.quicktime.album", 0x0500);
54-
_tagIntegerMap.put("com.apple.quicktime.artist", 0x0501);
55-
_tagIntegerMap.put("com.apple.quicktime.artwork", 0x0502);
56-
_tagIntegerMap.put("com.apple.quicktime.author", 0x0503);
57-
_tagIntegerMap.put("com.apple.quicktime.comment", 0x0504);
58-
_tagIntegerMap.put("com.apple.quicktime.copyright", 0x0505);
59-
_tagIntegerMap.put("com.apple.quicktime.creationdate", 0x0506);
60-
_tagIntegerMap.put("com.apple.quicktime.description", 0x0507);
61-
_tagIntegerMap.put("com.apple.quicktime.director", 0x0508);
62-
_tagIntegerMap.put("com.apple.quicktime.title", 0x0509);
63-
_tagIntegerMap.put("com.apple.quicktime.genre", 0x050A);
64-
_tagIntegerMap.put("com.apple.quicktime.information", 0x050B);
65-
_tagIntegerMap.put("com.apple.quicktime.keywords", 0x050C);
66-
_tagIntegerMap.put("com.apple.quicktime.location.ISO6709", 0x050D);
67-
_tagIntegerMap.put("com.apple.quicktime.producer", 0x050E);
68-
_tagIntegerMap.put("com.apple.quicktime.publisher", 0x050F);
69-
_tagIntegerMap.put("com.apple.quicktime.software", 0x0510);
70-
_tagIntegerMap.put("com.apple.quicktime.year", 0x0511);
71-
_tagIntegerMap.put("com.apple.quicktime.collection.user", 0x0512);
72-
_tagIntegerMap.put("com.apple.quicktime.rating.user", 0x0513);
73-
_tagIntegerMap.put("com.apple.quicktime.location.name", 0x0514);
74-
_tagIntegerMap.put("com.apple.quicktime.location.body", 0x0515);
75-
_tagIntegerMap.put("com.apple.quicktime.location.note", 0x0516);
76-
_tagIntegerMap.put("com.apple.quicktime.location.role", 0x0517);
77-
_tagIntegerMap.put("com.apple.quicktime.location.date", 0x0518);
78-
_tagIntegerMap.put("com.apple.quicktime.direction.facing", 0x0519);
79-
_tagIntegerMap.put("com.apple.quicktime.direction.motion", 0x051A);
80-
_tagIntegerMap.put("com.apple.quicktime.displayname", 0x051B);
81-
_tagIntegerMap.put("com.apple.quicktime.content.identifier", 0x051C);
82-
_tagIntegerMap.put("com.apple.quicktime.make", 0x051D);
83-
_tagIntegerMap.put("com.apple.quicktime.model", 0x051E);
84-
_tagIntegerMap.put("com.apple.photos.originating.signature", 0x051F);
86+
_tagIntegerMap.put("com.apple.quicktime.album", TAG_ALBUM);
87+
_tagIntegerMap.put("com.apple.quicktime.artist", TAG_ARTIST);
88+
_tagIntegerMap.put("com.apple.quicktime.artwork", TAG_ARTWORK);
89+
_tagIntegerMap.put("com.apple.quicktime.author", TAG_AUTHOR);
90+
_tagIntegerMap.put("com.apple.quicktime.comment", TAG_COMMENT);
91+
_tagIntegerMap.put("com.apple.quicktime.copyright", TAG_COPYRIGHT);
92+
_tagIntegerMap.put("com.apple.quicktime.creationdate", TAG_CREATION_DATE);
93+
_tagIntegerMap.put("com.apple.quicktime.description", TAG_DESCRIPTION);
94+
_tagIntegerMap.put("com.apple.quicktime.director", TAG_DIRECTOR);
95+
_tagIntegerMap.put("com.apple.quicktime.title", TAG_TITLE);
96+
_tagIntegerMap.put("com.apple.quicktime.genre", TAG_GENRE);
97+
_tagIntegerMap.put("com.apple.quicktime.information", TAG_INFORMATION);
98+
_tagIntegerMap.put("com.apple.quicktime.keywords", TAG_KEYWORDS);
99+
_tagIntegerMap.put("com.apple.quicktime.location.ISO6709", TAG_LOCATION_ISO6709);
100+
_tagIntegerMap.put("com.apple.quicktime.producer", TAG_PRODUCER);
101+
_tagIntegerMap.put("com.apple.quicktime.publisher", TAG_PUBLISHER);
102+
_tagIntegerMap.put("com.apple.quicktime.software", TAG_SOFTWARE);
103+
_tagIntegerMap.put("com.apple.quicktime.year", TAG_YEAR);
104+
_tagIntegerMap.put("com.apple.quicktime.collection.user", TAG_COLLECTION_USER);
105+
_tagIntegerMap.put("com.apple.quicktime.rating.user", TAG_RATING_USER);
106+
_tagIntegerMap.put("com.apple.quicktime.location.name", TAG_LOCATION_NAME);
107+
_tagIntegerMap.put("com.apple.quicktime.location.body", TAG_LOCATION_BODY);
108+
_tagIntegerMap.put("com.apple.quicktime.location.note", TAG_LOCATION_NOTE);
109+
_tagIntegerMap.put("com.apple.quicktime.location.role", TAG_LOCATION_ROLE);
110+
_tagIntegerMap.put("com.apple.quicktime.location.date", TAG_LOCATION_DATE);
111+
_tagIntegerMap.put("com.apple.quicktime.direction.facing", TAG_DIRECTION_FACING);
112+
_tagIntegerMap.put("com.apple.quicktime.direction.motion", TAG_DIRECTION_MOTION);
113+
_tagIntegerMap.put("com.apple.quicktime.displayname", TAG_DISPLAY_NAME);
114+
_tagIntegerMap.put("com.apple.quicktime.content.identifier", TAG_CONTENT_IDENTIFIER);
115+
_tagIntegerMap.put("com.apple.quicktime.make", TAG_MAKE);
116+
_tagIntegerMap.put("com.apple.quicktime.model", TAG_MODEL);
117+
_tagIntegerMap.put("com.apple.photos.originating.signature", TAG_ORIGINATING_SIGNATURE);
118+
_tagIntegerMap.put("com.apple.quicktime.pixeldensity", TAG_PIXEL_DENSITY);
85119

86120
_tagIntegerMap.put("----", 0x0400);
87121
_tagIntegerMap.put("@PST", 0x0401);
@@ -166,39 +200,40 @@ public QuickTimeMetadataDirectory()
166200
_tagIntegerMap.put("�trk", 0x0450);
167201
_tagIntegerMap.put("�wrt", 0x0451);
168202

169-
_tagNameMap.put(0x0500, "Album");
170-
_tagNameMap.put(0x0501, "Artist");
171-
_tagNameMap.put(0x0502, "Artwork");
172-
_tagNameMap.put(0x0503, "Author");
173-
_tagNameMap.put(0x0504, "Comment");
174-
_tagNameMap.put(0x0505, "Copyright");
175-
_tagNameMap.put(0x0506, "Creation Date");
176-
_tagNameMap.put(0x0507, "Description");
177-
_tagNameMap.put(0x0508, "Director");
178-
_tagNameMap.put(0x0509, "Title");
179-
_tagNameMap.put(0x050A, "Genre");
180-
_tagNameMap.put(0x050B, "Information");
181-
_tagNameMap.put(0x050C, "Keywords");
182-
_tagNameMap.put(0x050D, "ISO 6709");
183-
_tagNameMap.put(0x050E, "Producer");
184-
_tagNameMap.put(0x050F, "Publisher");
185-
_tagNameMap.put(0x0510, "Software");
186-
_tagNameMap.put(0x0511, "Year");
187-
_tagNameMap.put(0x0512, "Collection User");
188-
_tagNameMap.put(0x0513, "Rating User");
189-
_tagNameMap.put(0x0514, "Location Name");
190-
_tagNameMap.put(0x0515, "Location Body");
191-
_tagNameMap.put(0x0516, "Location Note");
192-
_tagNameMap.put(0x0517, "Location Role");
193-
_tagNameMap.put(0x0518, "Location Date");
194-
_tagNameMap.put(0x0519, "Direction Facing");
195-
_tagNameMap.put(0x051A, "Direction Motion");
196-
_tagNameMap.put(0x051B, "Display Name");
197-
_tagNameMap.put(0x051C, "Content Identifier");
198-
_tagNameMap.put(0x051D, "Make");
199-
_tagNameMap.put(0x051E, "Model");
200-
_tagNameMap.put(0x051F, "Originating Signature");
201-
203+
_tagNameMap.put(TAG_ALBUM, "Album");
204+
_tagNameMap.put(TAG_ARTIST, "Artist");
205+
_tagNameMap.put(TAG_ARTWORK, "Artwork");
206+
_tagNameMap.put(TAG_AUTHOR, "Author");
207+
_tagNameMap.put(TAG_COMMENT, "Comment");
208+
_tagNameMap.put(TAG_COPYRIGHT, "Copyright");
209+
_tagNameMap.put(TAG_CREATION_DATE, "Creation Date");
210+
_tagNameMap.put(TAG_DESCRIPTION, "Description");
211+
_tagNameMap.put(TAG_DIRECTOR, "Director");
212+
_tagNameMap.put(TAG_TITLE, "Title");
213+
_tagNameMap.put(TAG_GENRE, "Genre");
214+
_tagNameMap.put(TAG_INFORMATION, "Information");
215+
_tagNameMap.put(TAG_KEYWORDS, "Keywords");
216+
_tagNameMap.put(TAG_LOCATION_ISO6709, "ISO 6709");
217+
_tagNameMap.put(TAG_PRODUCER, "Producer");
218+
_tagNameMap.put(TAG_PUBLISHER, "Publisher");
219+
_tagNameMap.put(TAG_SOFTWARE, "Software");
220+
_tagNameMap.put(TAG_YEAR, "Year");
221+
_tagNameMap.put(TAG_COLLECTION_USER, "Collection User");
222+
_tagNameMap.put(TAG_RATING_USER, "Rating User");
223+
_tagNameMap.put(TAG_LOCATION_NAME, "Location Name");
224+
_tagNameMap.put(TAG_LOCATION_BODY, "Location Body");
225+
_tagNameMap.put(TAG_LOCATION_NOTE, "Location Note");
226+
_tagNameMap.put(TAG_LOCATION_ROLE, "Location Role");
227+
_tagNameMap.put(TAG_LOCATION_DATE, "Location Date");
228+
_tagNameMap.put(TAG_DIRECTION_FACING, "Direction Facing");
229+
_tagNameMap.put(TAG_DIRECTION_MOTION, "Direction Motion");
230+
_tagNameMap.put(TAG_DISPLAY_NAME, "Display Name");
231+
_tagNameMap.put(TAG_CONTENT_IDENTIFIER, "Content Identifier");
232+
_tagNameMap.put(TAG_MAKE, "Make");
233+
_tagNameMap.put(TAG_MODEL, "Model");
234+
_tagNameMap.put(TAG_ORIGINATING_SIGNATURE, "Originating Signature");
235+
_tagNameMap.put(TAG_PIXEL_DENSITY, "Pixel Density");
236+
202237
_tagNameMap.put(0x0400, "iTunes Info");
203238
_tagNameMap.put(0x0401, "Parent Short Title");
204239
_tagNameMap.put(0x0402, "Parent Product ID");

0 commit comments

Comments
 (0)