diff --git a/.classpath b/.classpath
index 367c9a5..673ec12 100644
--- a/.classpath
+++ b/.classpath
@@ -3,5 +3,7 @@
+
+
diff --git a/lib/metadata-extractor-2.3.1-src.jar b/lib/metadata-extractor-2.3.1-src.jar
new file mode 100644
index 0000000..631f360
Binary files /dev/null and b/lib/metadata-extractor-2.3.1-src.jar differ
diff --git a/lib/metadata-extractor-2.3.1.jar b/lib/metadata-extractor-2.3.1.jar
new file mode 100644
index 0000000..f5f6848
Binary files /dev/null and b/lib/metadata-extractor-2.3.1.jar differ
diff --git a/src/album/exif/ExifDataTest.java b/src/album/exif/ExifDataTest.java
new file mode 100644
index 0000000..9a196c1
--- /dev/null
+++ b/src/album/exif/ExifDataTest.java
@@ -0,0 +1,224 @@
+package album.exif;
+
+import static org.junit.Assert.assertEquals;
+
+import java.awt.Container;
+import java.awt.Dimension;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.image.BufferedImage;
+import java.io.File;
+import java.io.IOException;
+import java.util.Iterator;
+
+import javax.imageio.ImageIO;
+import javax.imageio.ImageReadParam;
+import javax.imageio.ImageReader;
+import javax.imageio.metadata.IIOMetadata;
+import javax.imageio.stream.ImageInputStream;
+import javax.swing.JComponent;
+import javax.swing.JFrame;
+
+import org.junit.Test;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import com.drew.imaging.jpeg.JpegMetadataReader;
+import com.drew.imaging.jpeg.JpegProcessingException;
+import com.drew.metadata.Directory;
+import com.drew.metadata.Metadata;
+import com.drew.metadata.MetadataException;
+import com.drew.metadata.Tag;
+import com.drew.metadata.exif.ExifDirectory;
+
+
+public class ExifDataTest {
+
+ String readOrientation(String imgFile) throws IOException {
+
+ ImageInputStream iis = ImageIO.createImageInputStream(new File(imgFile));
+ Iterator readers = ImageIO.getImageReaders(iis);
+ ImageReader reader = readers.next();
+ reader.setInput(iis);
+ IIOMetadata meta = reader.getImageMetadata(0);
+ return displayMetadata(meta);
+ }
+
+ @Test
+ public void testOrientation() throws Exception {
+
+ assertEquals("Top, left side (Horizontal / normal)", readOrientation2("photos/IMG_0129.JPG"));
+ assertEquals("Right side, top (Rotate 90 CW)", readOrientation2("photos/IMG_0139.JPG"));
+
+ framePicture("photos/IMG_0129.JPG");
+ framePicture("photos/IMG_0139.JPG");
+ Thread.sleep(50000);
+ }
+
+ String readOrientation2(String imgFile) throws JpegProcessingException, MetadataException {
+ String ret = null;
+ Metadata metadata = JpegMetadataReader.readMetadata(new File(imgFile));
+ // iterate through metadata directories
+ Iterator directories = metadata.getDirectoryIterator();
+ while (directories.hasNext()) {
+ Directory directory = (Directory) directories.next();
+ // iterate through tags and print to System.out
+ Iterator tags = directory.getTagIterator();
+ while (tags.hasNext()) {
+ Tag tag = (Tag) tags.next();
+ // use Tag.toString()
+ System.out.println(tag);
+ if ("Orientation".equals(tag.getTagName())) {
+ ret = String.valueOf(tag.getDescription());
+ }
+ }
+ }
+ return ret;
+ }
+
+ public String displayMetadata(IIOMetadata metadata) {
+
+ String ret = null;
+ String [] names = metadata.getMetadataFormatNames();
+ for (int i = 0; i < names.length; ++i) {
+ System.out.println();
+ System.out.println("METADATA FOR FORMAT: " + names[i]);
+ String r1 = displayTree(metadata.getAsTree(names[i]), 0);
+ if (r1 != null) {
+ ret = r1;
+ }
+ }
+ return ret;
+ }
+
+ public static String displayTree(Node node, int indent) {
+ String ret = null;
+ indent(indent);
+ String name = node.getNodeName();
+ System.out.print("<" + name);
+ NamedNodeMap nm = node.getAttributes();
+ for (int i = 0; i < nm.getLength(); i++) {
+ Node an = nm.item(i);
+ System.out.print(" " + an.getNodeName() + "=\"" + an.getNodeValue() + "\"");
+ if ("ImageOrientation".equals(node.getNodeName()) && "value".equals(an.getNodeName())) {
+ ret = an.getNodeValue();
+ }
+ }
+ if (node.hasChildNodes()) {
+ System.out.println(">");
+ NodeList children = node.getChildNodes();
+ for (int i = 0, ub = children.getLength(); i < ub; ++i) {
+ String r1 = displayTree(children.item(i), indent + 4);
+ if (r1 != null) {
+ ret = r1;
+ }
+ }
+ indent(indent);
+ System.out.println("" + name + ">");
+ } else {
+ System.out.println("/>");
+ }
+ return ret;
+ }
+
+ static void indent(int indent) {
+ for (int i = 0; i < indent; ++i)
+ System.out.print(' ');
+ }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ @Test
+ public void testThumbnail() throws Exception {
+
+ assertEquals(1, getOrientationID("photos/IMG_0129.JPG"));
+ assertEquals(6, getOrientationID("photos/IMG_0139.JPG"));
+ }
+
+// case 1: return "Top, left side (Horizontal / normal)";
+// case 2: return "Top, right side (Mirror horizontal)";
+// case 3: return "Bottom, right side (Rotate 180)";
+// case 4: return "Bottom, left side (Mirror vertical)";
+// case 5: return "Left side, top (Mirror horizontal and rotate 270 CW)";
+// case 6: return "Right side, top (Rotate 90 CW)";
+// case 7: return "Right side, bottom (Mirror horizontal and rotate 90 CW)";
+// case 8: return "Left side, bottom (Rotate 270 CW)";
+
+ /**
+ * @param imgFile
+ * @return
+ * @throws JpegProcessingException
+ * @throws MetadataException
+ */
+ int getOrientationID(String imgFile) throws JpegProcessingException, MetadataException {
+ Metadata metadata = JpegMetadataReader.readMetadata(new File(imgFile));
+ Directory exifDirectory = metadata.getDirectory(ExifDirectory.class);
+ int orientation = exifDirectory.getInt(ExifDirectory.TAG_ORIENTATION);
+ return orientation;
+ }
+
+
+
+ void framePicture(String imgFile) throws Exception {
+
+ JFrame frame = new JFrame(imgFile);
+ frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
+
+ Container c = frame.getContentPane();
+ c.add(new ImgComponent(imgFile));
+ frame.pack();
+ frame.setVisible(true);
+
+ }
+
+ class ImgComponent extends JComponent {
+
+ BufferedImage img;
+
+ public ImgComponent(String imgFile) throws IOException, JpegProcessingException, MetadataException {
+ Iterator readers = ImageIO.getImageReadersByFormatName("jpg");
+ ImageReader reader = (ImageReader)readers.next();
+ ImageInputStream iis = ImageIO.createImageInputStream(new File(imgFile));
+ reader.setInput(iis, true);
+ ImageReadParam param = reader.getDefaultReadParam();
+ param.setSourceSubsampling(8, 8, 0, 0);
+ img = reader.read(0, param);
+
+ if (getOrientationID(imgFile) == 6) {
+ BufferedImage buf2 = new BufferedImage(img.getHeight(), img.getWidth(), img.getType());
+ Graphics2D g2 = buf2.createGraphics();
+ g2.translate(img.getHeight() / 2, img.getWidth() / 2);
+ g2.rotate(Math.PI / 2);
+ g2.translate(-img.getWidth() / 2, -img.getHeight() / 2);
+ g2.drawImage(img, 0, 0, this);
+ img = buf2;
+ }
+ }
+
+
+ @Override
+ public Dimension getPreferredSize() {
+ return new Dimension(img.getWidth(this), img.getHeight(this));
+ }
+
+
+ @Override
+ public void paintComponent(Graphics g) {
+
+ super.paintComponent(g);
+ g.drawImage(img, 0, 0, this);
+ }
+ }
+}
diff --git a/src/album/web/BitmapServlet.java b/src/album/web/BitmapServlet.java
index 7bc9643..f12ecc0 100644
--- a/src/album/web/BitmapServlet.java
+++ b/src/album/web/BitmapServlet.java
@@ -15,7 +15,7 @@ public class BitmapServlet
extends HttpServlet
implements ImageObserver
{
- File baseDir = new File("/home/knut");
+ File baseDir = new File("photos");
File cacheDir = new File("/var/album");
final static int BUF_SIZE = 1024;