Adding workaround for exif arser bug

Support for customized sort of directory entry contents
This commit is contained in:
Knut Forkalsrud 2009-05-03 14:03:42 -07:00
parent e29fb43972
commit 600201a52d
4 changed files with 181 additions and 27 deletions

BIN
photos/geiranger/91860001.jpg Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 MiB

View file

@ -0,0 +1,126 @@
/**
*
*/
package org.forkalsrud.album.exif;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @author knut
*
*/
public class ComparatorFactory {
public static final String ASC = "asc";
public static final String DESC = "desc";
public static final String DIR = "dir";
public static final String DATE = "date";
public static final String NAME = "name";
static Pattern SORT_SPEC_SYNTAX = Pattern.compile("(\\w+)(\\s+(" + ASC + "|" + DESC + "))?,? *");
static ComparatorFactory singleton = new ComparatorFactory();
Comparator<Entry> directoryFirst = new Comparator<Entry>() {
public int compare(Entry e1, Entry e2) {
if (!e1.isFile() && e2.isFile()) {
return -1;
} else if (e1.isFile() && !e2.isFile()) {
return +1;
}
return 0;
}
};
Comparator<Entry> dates = new Comparator<Entry>() {
public int compare(Entry e1, Entry e2) {
Date d1 = e1.getDate();
Date d2 = e2.getDate();
if (d1 != null && d2 != null) {
return d1.compareTo(d2);
} else if (d1 != null) {
return -1;
} else if (d2 != null) {
return +1;
} else {
return 0;
}
}
};
Comparator<Entry> names = new Comparator<Entry>() {
public int compare(Entry e1, Entry e2) {
String n1 = e1.getName();
String n2 = e2.getName();
if (n1 != null && n2 != null) {
return n1.compareTo(n2);
} else if (n1 != null) {
return -1;
} else if (n2 != null) {
return +1;
} else {
return 0;
}
}
};
HashMap<String, Comparator<Entry>> map = new HashMap<String, Comparator<Entry>>();
public ComparatorFactory() {
map.put(DIR, directoryFirst);
map.put(DATE, dates);
map.put(NAME, names);
}
public static <T> Comparator<T> reverse(final Comparator<T> c) {
return new Comparator<T>() {
public int compare(T o1, T o2) {
return c.compare(o2, o1);
}
};
}
public Comparator<Entry> getComparator(String sortSpec) {
Matcher m = SORT_SPEC_SYNTAX.matcher(sortSpec);
int start = 0;
ArrayList<Comparator<Entry>> list = new ArrayList<Comparator<Entry>>();
while (m.find(start)) {
String param = m.group(1);
String direction = m.group(3);
Comparator<Entry> c = map.get(param);
if (c == null) {
throw new IllegalArgumentException(param);
}
if (DESC.equals(direction)) {
c = reverse(c);
}
list.add(c);
start = m.end();
}
return new ComposingComparator<Entry>(list);
}
public static Comparator<Entry> getSort(String sortSpec) {
return singleton.getComparator(sortSpec != null ? sortSpec : "dir, date");
}
}

View file

@ -0,0 +1,32 @@
/**
*
*/
package org.forkalsrud.album.exif;
import java.util.Comparator;
import java.util.List;
/**
* @author knut
*/
public class ComposingComparator<T> implements Comparator<T> {
List<Comparator<T>> cmp;
public ComposingComparator(List<Comparator<T>> args) {
cmp = args;
}
public int compare(T o1, T o2) {
for (Comparator<T> c : cmp) {
int result = c.compare(o1, o2);
if (result != 0) {
return result;
}
}
return 0;
}
}

View file

@ -45,6 +45,7 @@ public class DirectoryEntry extends Entry {
File cache;
List<Entry> children = new ArrayList<Entry>();
boolean childrenLoaded = false;
Comparator<Entry> sort = null;
public DirectoryEntry(File file) {
super(file);
@ -138,9 +139,13 @@ public class DirectoryEntry extends Entry {
Properties generateCache() throws MetadataException, JpegProcessingException, IOException {
long start = System.currentTimeMillis();
Properties props = new Properties();
generateFileEntries(props);
props.store(new FileOutputStream(cache), "Extra Comments");
long end = System.currentTimeMillis();
System.out.println("Time to generate properties for " + file.getPath() + ": " + (end - start)/1000d + " s");
return props;
}
@ -206,9 +211,11 @@ public class DirectoryEntry extends Entry {
hasDim = true;
}
if (exifDirectory.containsTag(ExifDirectory.TAG_DATETIME_ORIGINAL)) {
Date captureDate = exifDirectory.getDate(ExifDirectory.TAG_DATETIME_ORIGINAL);
props.setProperty(base + "captureDate", sdf.format(captureDate));
hasDate = true;
Date captureDate = getExifDate(exifDirectory, ExifDirectory.TAG_DATETIME_ORIGINAL);
if (captureDate != null) {
props.setProperty(base + "captureDate", sdf.format(captureDate));
hasDate = true;
}
}
if (exifDirectory.containsTag(ExifDirectory.TAG_USER_COMMENT)) {
String comment = exifDirectory.getString(ExifDirectory.TAG_USER_COMMENT);
@ -238,7 +245,16 @@ public class DirectoryEntry extends Entry {
}
}
Dimension decodeImageForDimensions(File file) throws IOException {
private Date getExifDate(Directory exifDirectory, int tagName) throws MetadataException {
String dateStr = (String)exifDirectory.getObject(tagName);
if (" : : : : ".equals(dateStr)) {
return null;
}
return exifDirectory.getDate(tagName);
}
Dimension decodeImageForDimensions(File file) throws IOException {
String suffix = null;
String name = file.getName();
@ -259,28 +275,7 @@ public class DirectoryEntry extends Entry {
private void sort() {
Collections.sort(children, new Comparator<Entry>() {
public int compare(Entry e1, Entry e2) {
if (!e1.isFile() && e2.isFile()) {
return -1;
} else if (e1.isFile() && !e2.isFile()) {
return +1;
}
Date d1 = e1.getDate();
Date d2 = e2.getDate();
if (d1 != null && d2 != null) {
return d1.compareTo(d2);
} else if (d1 != null) {
return -1;
} else if (d2 != null) {
return +1;
} else {
return 0;
}
}
});
Collections.sort(children, sort);
}
void fillLinkedList() {
@ -304,6 +299,7 @@ public class DirectoryEntry extends Entry {
String coverFileName = props.getProperty("cover");
String caption = props.getProperty("caption");
setCaption(caption);
sort = ComparatorFactory.getSort(props.getProperty("sort"));
HashMap<String, Entry> entryMap = new HashMap<String, Entry>();
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd-HHmmss");
Iterator i = props.keySet().iterator();