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;
    }
}