imToken v2.14.1版本的 MD5 值为:83050b2c91219b46832c8336279e7878
以下内容为反编译后的 XmpReader.java 源代码,内容仅作参考
package com.drew.metadata.xmp;
import com.adobe.internal.xmp.XMPException;
import com.adobe.internal.xmp.XMPIterator;
import com.adobe.internal.xmp.XMPMeta;
import com.adobe.internal.xmp.XMPMetaFactory;
import com.adobe.internal.xmp.impl.ByteBuffer;
import com.adobe.internal.xmp.options.ParseOptions;
import com.adobe.internal.xmp.properties.XMPPropertyInfo;
import com.drew.imaging.jpeg.JpegSegmentMetadataReader;
import com.drew.imaging.jpeg.JpegSegmentType;
import com.drew.lang.SequentialByteArrayReader;
import com.drew.metadata.Directory;
import com.drew.metadata.Metadata;
import com.drew.metadata.StringValue;
import java.io.IOException;
import java.util.Collections;
import java.util.Iterator;
public class XmpReader implements JpegSegmentMetadataReader {
private static final String ATTRIBUTE_EXTENDED_XMP = "xmpNote:HasExtendedXMP";
private static final int EXTENDED_XMP_GUID_LENGTH = 32;
private static final int EXTENDED_XMP_INT_LENGTH = 4;
private static final ParseOptions PARSE_OPTIONS = new ParseOptions().setXMPNodesToLimit(Collections.singletonMap("photoshop:DocumentAncestors", 1000));
private static final String SCHEMA_XMP_NOTES = "http://ns.adobe.com/xmp/note/";
private static final String XMP_EXTENSION_JPEG_PREAMBLE = "http://ns.adobe.com/xmp/extension/\u0000";
private static final String XMP_JPEG_PREAMBLE = "http://ns.adobe.com/xap/1.0/\u0000";
@Override
public Iterable<JpegSegmentType> getSegmentTypes() {
return Collections.singletonList(JpegSegmentType.APP1);
}
@Override
public void readJpegSegments(Iterable<byte[]> iterable, Metadata metadata, JpegSegmentType jpegSegmentType) {
byte[] bArr = null;
String str = null;
for (byte[] bArr2 : iterable) {
if (bArr2.length >= 29 && (XMP_JPEG_PREAMBLE.equalsIgnoreCase(new String(bArr2, 0, 29)) || "XMP".equalsIgnoreCase(new String(bArr2, 0, 3)))) {
int length = bArr2.length - 29;
byte[] bArr3 = new byte[length];
System.arraycopy(bArr2, 29, bArr3, 0, length);
extract(bArr3, metadata);
str = getExtendedXMPGUID(metadata);
} else if (str != null && bArr2.length >= 35 && XMP_EXTENSION_JPEG_PREAMBLE.equalsIgnoreCase(new String(bArr2, 0, 35))) {
bArr = processExtendedXMPChunk(metadata, bArr2, str, bArr);
}
}
if (bArr != null) {
extract(bArr, metadata);
}
}
public void extract(byte[] bArr, Metadata metadata) {
extract(bArr, metadata, (Directory) null);
}
public void extract(byte[] bArr, Metadata metadata, Directory directory) {
extract(bArr, 0, bArr.length, metadata, directory);
}
public void extract(byte[] bArr, int i2, int i3, Metadata metadata, Directory directory) {
XMPMeta parseFromBuffer;
XmpDirectory xmpDirectory = new XmpDirectory();
if (directory != null) {
xmpDirectory.setParent(directory);
}
if (i2 == 0) {
try {
} catch (XMPException e2) {
xmpDirectory.addError("Error processing XMP data: " + e2.getMessage());
}
if (i3 == bArr.length) {
parseFromBuffer = XMPMetaFactory.parseFromBuffer(bArr, PARSE_OPTIONS);
xmpDirectory.setXMPMeta(parseFromBuffer);
if (xmpDirectory.isEmpty()) {
metadata.addDirectory(xmpDirectory);
return;
}
return;
}
}
parseFromBuffer = XMPMetaFactory.parse(new ByteBuffer(bArr, i2, i3).getByteStream(), PARSE_OPTIONS);
xmpDirectory.setXMPMeta(parseFromBuffer);
if (xmpDirectory.isEmpty()) {
}
}
public void extract(String str, Metadata metadata) {
extract(str, metadata, (Directory) null);
}
public void extract(StringValue stringValue, Metadata metadata) {
extract(stringValue.getBytes(), metadata, (Directory) null);
}
public void extract(String str, Metadata metadata, Directory directory) {
XmpDirectory xmpDirectory = new XmpDirectory();
if (directory != null) {
xmpDirectory.setParent(directory);
}
try {
xmpDirectory.setXMPMeta(XMPMetaFactory.parseFromString(str, PARSE_OPTIONS));
} catch (XMPException e2) {
xmpDirectory.addError("Error processing XMP data: " + e2.getMessage());
}
if (xmpDirectory.isEmpty()) {
return;
}
metadata.addDirectory(xmpDirectory);
}
private static String getExtendedXMPGUID(Metadata metadata) {
Iterator it = metadata.getDirectoriesOfType(XmpDirectory.class).iterator();
while (it.hasNext()) {
try {
XMPIterator it2 = ((XmpDirectory) it.next()).getXMPMeta().iterator("http://ns.adobe.com/xmp/note/", null, null);
if (it2 != null) {
while (it2.hasNext()) {
XMPPropertyInfo xMPPropertyInfo = (XMPPropertyInfo) it2.next();
if (ATTRIBUTE_EXTENDED_XMP.equals(xMPPropertyInfo.getPath())) {
return xMPPropertyInfo.getValue();
}
}
continue;
}
} catch (XMPException unused) {
}
}
return null;
}
private static byte[] processExtendedXMPChunk(Metadata metadata, byte[] bArr, String str, byte[] bArr2) {
int length = bArr.length;
if (length >= 75) {
try {
SequentialByteArrayReader sequentialByteArrayReader = new SequentialByteArrayReader(bArr);
sequentialByteArrayReader.skip(35);
if (str.equals(sequentialByteArrayReader.getString(32))) {
int uInt32 = (int) sequentialByteArrayReader.getUInt32();
int uInt322 = (int) sequentialByteArrayReader.getUInt32();
if (bArr2 == null) {
bArr2 = new byte[uInt32];
}
if (bArr2.length == uInt32) {
System.arraycopy(bArr, 75, bArr2, uInt322, length - 75);
} else {
XmpDirectory xmpDirectory = new XmpDirectory();
xmpDirectory.addError(String.format("Inconsistent length for the Extended XMP buffer: %d instead of %d", Integer.valueOf(uInt32), Integer.valueOf(bArr2.length)));
metadata.addDirectory(xmpDirectory);
}
}
} catch (IOException e2) {
XmpDirectory xmpDirectory2 = new XmpDirectory();
xmpDirectory2.addError(e2.getMessage());
metadata.addDirectory(xmpDirectory2);
}
}
return bArr2;
}
}