imToken v2.9.3版本的 MD5 值为:42af1a08a3f01f69d2f3782d81007b3c

以下内容为反编译后的 ProcessAllImagesInFolderUtility.java 源代码,内容仅作参考


package com.drew.tools;

import com.adobe.xmp.XMPException;
import com.adobe.xmp.XMPIterator;
import com.adobe.xmp.properties.XMPPropertyInfo;
import com.drew.imaging.FileTypeDetector;
import com.drew.imaging.ImageMetadataReader;
import com.drew.imaging.jpeg.JpegProcessingException;
import com.drew.lang.StringUtil;
import com.drew.metadata.Directory;
import com.drew.metadata.Metadata;
import com.drew.metadata.Tag;
import com.drew.metadata.exif.ExifDirectoryBase;
import com.drew.metadata.exif.ExifIFD0Directory;
import com.drew.metadata.exif.ExifSubIFDDirectory;
import com.drew.metadata.exif.ExifThumbnailDirectory;
import com.drew.metadata.file.FileSystemDirectory;
import com.drew.metadata.xmp.XmpDirectory;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class ProcessAllImagesInFolderUtility {

    public interface FileHandler {
        void onBeforeExtraction(File file, PrintStream printStream, String str);

        void onExtractionError(File file, Throwable th, PrintStream printStream);

        void onExtractionSuccess(File file, Metadata metadata, String str, PrintStream printStream);

        void onScanCompleted(PrintStream printStream);

        void onStartingDirectory(File file);

        boolean shouldProcess(File file);
    }

    public static void main(String[] strArr) throws IOException, JpegProcessingException {
        ArrayList arrayList = new ArrayList();
        PrintStream printStream = System.out;
        FileHandler fileHandler = null;
        int i = 0;
        while (i < strArr.length) {
            String str = strArr[i];
            if (str.equalsIgnoreCase("--text")) {
                fileHandler = new TextFileOutputHandler();
            } else if (str.equalsIgnoreCase("--markdown")) {
                fileHandler = new MarkdownTableOutputHandler();
            } else if (str.equalsIgnoreCase("--unknown")) {
                fileHandler = new UnknownTagHandler();
            } else if (str.equalsIgnoreCase("--log-file")) {
                if (i == strArr.length - 1) {
                    printUsage();
                    System.exit(1);
                }
                i++;
                printStream = new PrintStream((OutputStream) new FileOutputStream(strArr[i], false), true);
            } else {
                arrayList.add(str);
            }
            i++;
        }
        if (arrayList.isEmpty()) {
            System.err.println("Expects one or more directories as arguments.");
            printUsage();
            System.exit(1);
        }
        if (fileHandler == null) {
            fileHandler = new BasicFileHandler();
        }
        long nanoTime = System.nanoTime();
        Iterator it = arrayList.iterator();
        while (it.hasNext()) {
            processDirectory(new File((String) it.next()), fileHandler, "", printStream);
        }
        fileHandler.onScanCompleted(printStream);
        System.out.println(String.format("Completed in %d ms", Long.valueOf((System.nanoTime() - nanoTime) / 1000000)));
        if (printStream != System.out) {
            printStream.close();
        }
    }

    private static void printUsage() {
        System.out.println("Usage:");
        System.out.println();
        System.out.println("  java com.drew.tools.ProcessAllImagesInFolderUtility [--text|--markdown|--unknown] [--log-file <file-name>]");
    }

    private static void processDirectory(File file, FileHandler fileHandler, String str, PrintStream printStream) {
        fileHandler.onStartingDirectory(file);
        String[] list = file.list();
        if (list == null) {
            return;
        }
        Arrays.sort(list);
        for (String str2 : list) {
            File file2 = new File(file, str2);
            if (file2.isDirectory()) {
                if (str.length() != 0) {
                    str2 = str + "/" + str2;
                }
                processDirectory(file2, fileHandler, str2, printStream);
            } else if (fileHandler.shouldProcess(file2)) {
                fileHandler.onBeforeExtraction(file2, printStream, str);
                try {
                    fileHandler.onExtractionSuccess(file2, ImageMetadataReader.readMetadata(file2), str, printStream);
                } catch (Throwable th) {
                    fileHandler.onExtractionError(file2, th, printStream);
                }
            }
        }
    }

    static abstract class FileHandlerBase implements FileHandler {
        private final Set<String> _supportedExtensions = new HashSet(Arrays.asList("jpg", "jpeg", "png", "gif", "bmp", "ico", "webp", "pcx", "ai", "eps", "nef", "crw", "cr2", "orf", "arw", "raf", "srw", "x3f", "rw2", "rwl", "tif", "tiff", "psd", "dng", "3g2", "3gp", "m4v", "mov", "mp4", "pbm", "pnm", "pgm"));
        private int _processedFileCount = 0;
        private int _exceptionCount = 0;
        private int _errorCount = 0;
        private long _processedByteCount = 0;

        @Override
        public void onStartingDirectory(File file) {
        }

        FileHandlerBase() {
        }

        @Override
        public boolean shouldProcess(File file) {
            String extension = getExtension(file);
            return extension != null && this._supportedExtensions.contains(extension.toLowerCase());
        }

        @Override
        public void onBeforeExtraction(File file, PrintStream printStream, String str) {
            this._processedFileCount++;
            this._processedByteCount += file.length();
        }

        @Override
        public void onExtractionError(File file, Throwable th, PrintStream printStream) {
            this._exceptionCount++;
            printStream.printf("\t[%s] %s\n", th.getClass().getName(), th.getMessage());
        }

        @Override
        public void onExtractionSuccess(File file, Metadata metadata, String str, PrintStream printStream) {
            if (metadata.hasErrors()) {
                printStream.print(file);
                printStream.print('\n');
                for (Directory directory : metadata.getDirectories()) {
                    if (directory.hasErrors()) {
                        Iterator<String> it = directory.getErrors().iterator();
                        while (it.hasNext()) {
                            printStream.printf("\t[%s] %s\n", directory.getName(), it.next());
                            this._errorCount++;
                        }
                    }
                }
            }
        }

        @Override
        public void onScanCompleted(PrintStream printStream) {
            int i = this._processedFileCount;
            if (i > 0) {
                printStream.print(String.format("Processed %,d files (%,d bytes) with %,d exceptions and %,d file errors\n", Integer.valueOf(i), Long.valueOf(this._processedByteCount), Integer.valueOf(this._exceptionCount), Integer.valueOf(this._errorCount)));
            }
        }

        protected String getExtension(File file) {
            String name = file.getName();
            int lastIndexOf = name.lastIndexOf(46);
            if (lastIndexOf == -1 || lastIndexOf == name.length() - 1) {
                return null;
            }
            return name.substring(lastIndexOf + 1);
        }
    }

    static class TextFileOutputHandler extends FileHandlerBase {
        private static final String NEW_LINE = "\n";

        TextFileOutputHandler() {
        }

        @Override
        public void onStartingDirectory(File file) {
            super.onStartingDirectory(file);
            File file2 = new File(file + "/metadata");
            if (file2.exists()) {
                deleteRecursively(file2);
            }
        }

        private static void deleteRecursively(File file) {
            String[] list;
            if (!file.isDirectory()) {
                throw new IllegalArgumentException("Must be a directory.");
            }
            if (file.exists() && (list = file.list()) != null) {
                for (String str : list) {
                    File file2 = new File(str);
                    if (file2.isDirectory()) {
                        deleteRecursively(file2);
                    } else {
                        file2.delete();
                    }
                }
            }
            file.delete();
        }

        @Override
        public void onBeforeExtraction(File file, PrintStream printStream, String str) {
            super.onBeforeExtraction(file, printStream, str);
            printStream.print(file.getAbsoluteFile());
            printStream.print("\n");
        }

        @Override
        public void onExtractionSuccess(File file, Metadata metadata, String str, PrintStream printStream) {
            PrintWriter printWriter;
            boolean z;
            super.onExtractionSuccess(file, metadata, str, printStream);
            try {
                try {
                    PrintWriter openWriter = openWriter(file);
                    try {
                        int i = 3;
                        if (metadata.hasErrors()) {
                            for (Directory directory : metadata.getDirectories()) {
                                if (directory.hasErrors()) {
                                    Iterator<String> it = directory.getErrors().iterator();
                                    while (it.hasNext()) {
                                        openWriter.format("[ERROR: %s] %s%s", directory.getName(), it.next(), "\n");
                                    }
                                }
                            }
                            openWriter.write("\n");
                        }
                        for (Directory directory2 : metadata.getDirectories()) {
                            String name = directory2.getName();
                            Iterator<Tag> it2 = directory2.getTags().iterator();
                            while (true) {
                                String str2 = "";
                                if (!it2.hasNext()) {
                                    break;
                                }
                                Tag next = it2.next();
                                String tagName = next.getTagName();
                                String description = next.getDescription();
                                if (description != null) {
                                    str2 = description;
                                }
                                if ((directory2 instanceof FileSystemDirectory) && next.getTagType() == i) {
                                    str2 = "<omitted for regression testing as checkout dependent>";
                                }
                                Object[] objArr = new Object[5];
                                objArr[0] = name;
                                objArr[1] = next.getTagTypeHex();
                                objArr[2] = tagName;
                                objArr[i] = str2;
                                objArr[4] = "\n";
                                openWriter.format("[%s - %s] %s = %s%s", objArr);
                            }
                            if (directory2.getTagCount() != 0) {
                                openWriter.write("\n");
                            }
                            if (directory2 instanceof XmpDirectory) {
                                try {
                                    XMPIterator it3 = ((XmpDirectory) directory2).getXMPMeta().iterator();
                                    z = false;
                                    while (it3.hasNext()) {
                                        try {
                                            XMPPropertyInfo xMPPropertyInfo = (XMPPropertyInfo) it3.next();
                                            String namespace = xMPPropertyInfo.getNamespace();
                                            String path = xMPPropertyInfo.getPath();
                                            String value = xMPPropertyInfo.getValue();
                                            if (namespace == null) {
                                                namespace = "";
                                            }
                                            if (path == null) {
                                                path = "";
                                            }
                                            if (value == null) {
                                                value = "";
                                            } else if (value.length() > 512) {
                                                value = String.format("%s <truncated from %d characters>", value.substring(0, 512), Integer.valueOf(value.length()));
                                            }
                                            Object[] objArr2 = new Object[4];
                                            objArr2[0] = namespace;
                                            objArr2[1] = path;
                                            objArr2[2] = value;
                                            try {
                                                objArr2[3] = "\n";
                                                openWriter.format("[XMPMeta - %s] %s = %s%s", objArr2);
                                                z = true;
                                            } catch (XMPException e) {
                                                e = e;
                                                e.printStackTrace();
                                                if (!z) {
                                                }
                                                i = 3;
                                            }
                                        } catch (XMPException e2) {
                                            e = e2;
                                        }
                                    }
                                } catch (XMPException e3) {
                                    e = e3;
                                    z = false;
                                }
                                if (!z) {
                                    openWriter.write("\n");
                                }
                            }
                            i = 3;
                        }
                        writeHierarchyLevel(metadata, openWriter, null, 0);
                        openWriter.write("\n");
                        closeWriter(openWriter);
                    } catch (Throwable th) {
                        th = th;
                        printWriter = openWriter;
                        closeWriter(printWriter);
                        throw th;
                    }
                } catch (Throwable th2) {
                    th = th2;
                    printWriter = null;
                }
            } catch (IOException e4) {
                e4.printStackTrace();
            }
        }

        private static void writeHierarchyLevel(Metadata metadata, PrintWriter printWriter, Directory directory, int i) {
            int i2;
            for (Directory directory2 : metadata.getDirectories()) {
                if (directory == null) {
                    if (directory2.getParent() == null) {
                        for (i2 = 0; i2 < i * 4; i2++) {
                            printWriter.write(32);
                        }
                        printWriter.write("- ");
                        printWriter.write(directory2.getName());
                        printWriter.write("\n");
                        writeHierarchyLevel(metadata, printWriter, directory2, i + 1);
                    }
                } else if (directory.equals(directory2.getParent())) {
                    while (i2 < i * 4) {
                    }
                    printWriter.write("- ");
                    printWriter.write(directory2.getName());
                    printWriter.write("\n");
                    writeHierarchyLevel(metadata, printWriter, directory2, i + 1);
                }
            }
        }

        @Override
        public void onExtractionError(File file, Throwable th, PrintStream printStream) {
            PrintWriter printWriter;
            super.onExtractionError(file, th, printStream);
            try {
                try {
                    printWriter = openWriter(file);
                    try {
                        printWriter.write("EXCEPTION: " + th.getMessage() + "\n");
                        printWriter.write("\n");
                        closeWriter(printWriter);
                    } catch (Throwable th2) {
                        th = th2;
                        closeWriter(printWriter);
                        throw th;
                    }
                } catch (IOException e) {
                    printStream.printf("IO exception writing metadata file: %s%s", e.getMessage(), "\n");
                }
            } catch (Throwable th3) {
                th = th3;
                printWriter = null;
            }
        }

        private static PrintWriter openWriter(File file) throws IOException {
            File file2 = new File(String.format("%s/metadata", file.getParent()));
            if (!file2.exists()) {
                file2.mkdir();
            }
            OutputStreamWriter outputStreamWriter = new OutputStreamWriter(new FileOutputStream(String.format("%s/metadata/%s.txt", file.getParent(), file.getName())), "UTF-8");
            outputStreamWriter.write("FILE: " + file.getName() + "\n");
            BufferedInputStream bufferedInputStream = null;
            try {
                BufferedInputStream bufferedInputStream2 = new BufferedInputStream(new FileInputStream(file));
                try {
                    outputStreamWriter.write(String.format("TYPE: %s\n", FileTypeDetector.detectFileType(bufferedInputStream2).toString().toUpperCase()));
                    outputStreamWriter.write("\n");
                    bufferedInputStream2.close();
                    return new PrintWriter(outputStreamWriter);
                } catch (Throwable th) {
                    th = th;
                    bufferedInputStream = bufferedInputStream2;
                    if (bufferedInputStream != null) {
                        bufferedInputStream.close();
                    }
                    throw th;
                }
            } catch (Throwable th2) {
                th = th2;
            }
        }

        private static void closeWriter(Writer writer) throws IOException {
            if (writer != null) {
                writer.write("Generated using metadata-extractor\n");
                writer.write("https://drewnoakes.com/code/exif/\n");
                writer.flush();
                writer.close();
            }
        }
    }

    static class MarkdownTableOutputHandler extends FileHandlerBase {
        private final Map<String, String> _extensionEquivalence = new HashMap();
        private final Map<String, List<Row>> _rowListByExtension = new HashMap();

        public static class Row {
            private String exifVersion;
            final File file;
            private String makernote;
            private String manufacturer;
            final Metadata metadata;
            private String model;
            final String relativePath;
            private String thumbnail;

            Row(File file, Metadata metadata, String str) {
                boolean z;
                this.file = file;
                this.metadata = metadata;
                this.relativePath = str;
                ExifIFD0Directory exifIFD0Directory = (ExifIFD0Directory) metadata.getFirstDirectoryOfType(ExifIFD0Directory.class);
                ExifSubIFDDirectory exifSubIFDDirectory = (ExifSubIFDDirectory) metadata.getFirstDirectoryOfType(ExifSubIFDDirectory.class);
                ExifThumbnailDirectory exifThumbnailDirectory = (ExifThumbnailDirectory) metadata.getFirstDirectoryOfType(ExifThumbnailDirectory.class);
                if (exifIFD0Directory != null) {
                    this.manufacturer = exifIFD0Directory.getDescription(271);
                    this.model = exifIFD0Directory.getDescription(272);
                }
                if (exifSubIFDDirectory != null) {
                    this.exifVersion = exifSubIFDDirectory.getDescription(ExifDirectoryBase.TAG_EXIF_VERSION);
                    z = exifSubIFDDirectory.containsTag(ExifDirectoryBase.TAG_MAKERNOTE);
                } else {
                    z = false;
                }
                if (exifThumbnailDirectory != null) {
                    Integer integer = exifThumbnailDirectory.getInteger(256);
                    Integer integer2 = exifThumbnailDirectory.getInteger(257);
                    this.thumbnail = (integer == null || integer2 == null) ? "Yes" : String.format("Yes (%s x %s)", integer, integer2);
                }
                Iterator<Directory> it = metadata.getDirectories().iterator();
                while (true) {
                    if (!it.hasNext()) {
                        break;
                    }
                    Directory next = it.next();
                    if (next.getClass().getName().contains("Makernote")) {
                        this.makernote = next.getName().replace("Makernote", "").trim();
                        break;
                    }
                }
                if (this.makernote == null) {
                    this.makernote = z ? "(Unknown)" : "N/A";
                }
            }
        }

        public MarkdownTableOutputHandler() {
            this._extensionEquivalence.put("jpeg", "jpg");
        }

        @Override
        public void onExtractionSuccess(File file, Metadata metadata, String str, PrintStream printStream) {
            super.onExtractionSuccess(file, metadata, str, printStream);
            String extension = getExtension(file);
            if (extension == null) {
                return;
            }
            String lowerCase = extension.toLowerCase();
            if (this._extensionEquivalence.containsKey(lowerCase)) {
                lowerCase = this._extensionEquivalence.get(lowerCase);
            }
            List<Row> list = this._rowListByExtension.get(lowerCase);
            if (list == null) {
                list = new ArrayList<>();
                this._rowListByExtension.put(lowerCase, list);
            }
            list.add(new Row(file, metadata, str));
        }

        @Override
        public void onScanCompleted(PrintStream printStream) {
            PrintStream printStream2;
            FileOutputStream fileOutputStream;
            IOException e;
            super.onScanCompleted(printStream);
            try {
                try {
                    try {
                        fileOutputStream = new FileOutputStream("../wiki/ImageDatabaseSummary.md", false);
                    } catch (Throwable th) {
                        th = th;
                    }
                    try {
                        printStream2 = new PrintStream((OutputStream) fileOutputStream, false);
                        try {
                            writeOutput(printStream2);
                            printStream2.flush();
                            printStream2.close();
                            fileOutputStream.close();
                        } catch (IOException e2) {
                            e = e2;
                            e.printStackTrace();
                            if (printStream2 != null) {
                                printStream2.close();
                            }
                            if (fileOutputStream != null) {
                                fileOutputStream.close();
                            }
                        }
                    } catch (IOException e3) {
                        printStream2 = null;
                        e = e3;
                    } catch (Throwable th2) {
                        printStream2 = null;
                        th = th2;
                        if (printStream2 != null) {
                            printStream2.close();
                        }
                        if (fileOutputStream != null) {
                            try {
                                fileOutputStream.close();
                            } catch (IOException e4) {
                                e4.printStackTrace();
                            }
                        }
                        throw th;
                    }
                } catch (IOException e5) {
                    printStream2 = null;
                    e = e5;
                    fileOutputStream = null;
                } catch (Throwable th3) {
                    printStream2 = null;
                    th = th3;
                    fileOutputStream = null;
                }
            } catch (IOException e6) {
                e6.printStackTrace();
            }
        }

        private void writeOutput(PrintStream printStream) throws IOException {
            OutputStreamWriter outputStreamWriter = new OutputStreamWriter(printStream);
            outputStreamWriter.write("# Image Database Summary\n\n");
            for (Map.Entry<String, List<Row>> entry : this._rowListByExtension.entrySet()) {
                outputStreamWriter.write("## " + entry.getKey().toUpperCase() + " Files\n\n");
                outputStreamWriter.write("File|Manufacturer|Model|Dir Count|Exif?|Makernote|Thumbnail|All Data\n");
                outputStreamWriter.write("----|------------|-----|---------|-----|---------|---------|--------\n");
                List<Row> value = entry.getValue();
                Collections.sort(value, new Comparator<Row>() {
                    @Override
                    public int compare(Row row, Row row2) {
                        int compare = StringUtil.compare(row.manufacturer, row2.manufacturer);
                        return compare != 0 ? compare : StringUtil.compare(row.model, row2.model);
                    }
                });
                for (Row row : value) {
                    Object[] objArr = new Object[11];
                    objArr[0] = row.file.getName();
                    objArr[1] = row.relativePath;
                    objArr[2] = StringUtil.urlEncode(row.file.getName());
                    String str = "";
                    objArr[3] = row.manufacturer == null ? "" : row.manufacturer;
                    objArr[4] = row.model == null ? "" : row.model;
                    objArr[5] = Integer.valueOf(row.metadata.getDirectoryCount());
                    objArr[6] = row.exifVersion == null ? "" : row.exifVersion;
                    objArr[7] = row.makernote == null ? "" : row.makernote;
                    if (row.thumbnail != null) {
                        str = row.thumbnail;
                    }
                    objArr[8] = str;
                    objArr[9] = row.relativePath;
                    objArr[10] = StringUtil.urlEncode(row.file.getName()).toLowerCase();
                    outputStreamWriter.write(String.format("[%s](https://raw.githubusercontent.com/drewnoakes/metadata-extractor-images/master/%s/%s)|%s|%s|%d|%s|%s|%s|[metadata](https://raw.githubusercontent.com/drewnoakes/metadata-extractor-images/master/%s/metadata/%s.txt)\n", objArr));
                }
                outputStreamWriter.write(10);
            }
            outputStreamWriter.flush();
        }
    }

    static class UnknownTagHandler extends FileHandlerBase {
        private HashMap<String, HashMap<Integer, Integer>> _occurrenceCountByTagByDirectory = new HashMap<>();

        UnknownTagHandler() {
        }

        @Override
        public void onExtractionSuccess(File file, Metadata metadata, String str, PrintStream printStream) {
            super.onExtractionSuccess(file, metadata, str, printStream);
            for (Directory directory : metadata.getDirectories()) {
                for (Tag tag : directory.getTags()) {
                    if (!tag.hasTagName()) {
                        HashMap<Integer, Integer> hashMap = this._occurrenceCountByTagByDirectory.get(directory.getName());
                        if (hashMap == null) {
                            hashMap = new HashMap<>();
                            this._occurrenceCountByTagByDirectory.put(directory.getName(), hashMap);
                        }
                        Integer num = hashMap.get(Integer.valueOf(tag.getTagType()));
                        if (num == null) {
                            hashMap.put(Integer.valueOf(tag.getTagType()), 0);
                            num = 0;
                        }
                        hashMap.put(Integer.valueOf(tag.getTagType()), Integer.valueOf(num.intValue() + 1));
                    }
                }
            }
        }

        @Override
        public void onScanCompleted(PrintStream printStream) {
            super.onScanCompleted(printStream);
            for (Map.Entry<String, HashMap<Integer, Integer>> entry : this._occurrenceCountByTagByDirectory.entrySet()) {
                String key = entry.getKey();
                ArrayList<Map.Entry> arrayList = new ArrayList(entry.getValue().entrySet());
                Collections.sort(arrayList, new Comparator<Map.Entry<Integer, Integer>>() {
                    @Override
                    public int compare(Map.Entry<Integer, Integer> entry2, Map.Entry<Integer, Integer> entry3) {
                        return entry3.getValue().compareTo(entry2.getValue());
                    }
                });
                for (Map.Entry entry2 : arrayList) {
                    printStream.format("%s, 0x%04X, %d\n", key, (Integer) entry2.getKey(), (Integer) entry2.getValue());
                }
            }
        }
    }

    static class BasicFileHandler extends FileHandlerBase {
        BasicFileHandler() {
        }

        @Override
        public void onExtractionSuccess(File file, Metadata metadata, String str, PrintStream printStream) {
            super.onExtractionSuccess(file, metadata, str, printStream);
            for (Directory directory : metadata.getDirectories()) {
                directory.getName();
                for (Tag tag : directory.getTags()) {
                    tag.getTagName();
                    tag.getDescription();
                }
            }
        }
    }
}