/* Copyright (C) 2005-2011 Fabio Riccardi */

package com.lightcrafts.image.types;

import java.io.IOException;

import org.w3c.dom.Document;

import com.lightcrafts.image.BadImageFileException;
import com.lightcrafts.image.ImageInfo;
import com.lightcrafts.image.UnknownImageTypeException;
import com.lightcrafts.image.metadata.DNGDirectory;
import com.lightcrafts.image.metadata.ImageMetadata;
import com.lightcrafts.image.metadata.TIFFMetadataReader;
import com.lightcrafts.image.metadata.XMPMetadataReader;

/**
 * A <code>DNGImageType</code> is-a {@link RawImageType} for DNG (Digital
 * NeGative) images.
 *
 * @author Paul J. Lucas [paul@lightcrafts.com]
 */
public final class DNGImageType extends RawImageType {

    ////////// public /////////////////////////////////////////////////////////

    /** The singleton instance of <code>DNGImageType</code>. */
    public static final DNGImageType INSTANCE = new DNGImageType();

    /**
     * {@inheritDoc}
     */
    public String[] getExtensions() {
        return EXTENSIONS;
    }

    /**
     * {@inheritDoc}
     */
    public String getName() {
        return "DNG";
    }

    /**
     * {@inheritDoc}
     */
    public Document getXMP( ImageInfo imageInfo )
        throws BadImageFileException, IOException, UnknownImageTypeException
    {
        return TIFFImageType.getXMP( imageInfo, DNGDirectory.class );
    }

    /**
     * Reads all the metadata for a given DNG image.
     *
     * @param imageInfo The image to read the metadata from.
     */
    public void readMetadata( ImageInfo imageInfo )
        throws BadImageFileException, IOException, UnknownImageTypeException
    {
        final TIFFMetadataReader reader =
            new TIFFMetadataReader( imageInfo, DNGDirectory.class );
        final ImageMetadata metadata = reader.readMetadata();
        final Document xmpDoc = getXMP( imageInfo );
        if ( xmpDoc != null ) {
            final ImageMetadata xmpMetadata =
                XMPMetadataReader.readFrom( xmpDoc );
            metadata.mergeFrom( xmpMetadata );
        }
    }

    // through DCRaw, should be fast enough...
    public boolean hasFastPreview() {
        return true;
    }

    ////////// private ////////////////////////////////////////////////////////

    /**
     * Construct a <code>DNGImageType</code>.
     * The constructor is <code>private</code> so only the singleton instance
     * can be constructed.
     */
    private DNGImageType() {
        // do nothing
    }

    /**
     * All the possible filename extensions for DNG files.  All must be lower
     * case and the preferred one must be first.
     */
    private static final String EXTENSIONS[] = {
        "dng"
    };
}
/* vim:set et sw=4 ts=4: */

@@ -117,178 +117,260 @@
 ort 
-org.w3c.dom.Document;%0A%0Aimport com.lightcrafts.image.BadImageFileException;%0Aimport com.lightcrafts.image.ImageInfo;%0Aimport com.lightcrafts.image.UnknownImageTypeException;
+com.lightcrafts.image.metadata.*;%0Aimport com.lightcrafts.image.metadata.makernotes.MakerNoteProbe;%0Aimport com.lightcrafts.image.metadata.makernotes.MakerNotesDirectory;%0Aimport com.lightcrafts.utils.bytebuffer.LCByteBuffer;%0Aimport org.w3c.dom.Document;%0A
 %0Aimp
@@ -399,29 +399,29 @@
 age.
-metadata.DNGDirectory
+BadImageFileException
 ;%0Aim
@@ -451,30 +451,17 @@
 age.
-metadata.ImageMetadata
+ImageInfo
 ;%0Aim
@@ -491,44 +491,43 @@
 age.
-metadata.TIFFMetadataReader;
+UnknownImageTypeException;%0A
 %0Aimport 
 com.
@@ -514,32 +514,39 @@
 eption;%0A%0Aimport 
+static 
 com.lightcrafts.
@@ -560,33 +560,40 @@
 etadata.
-XMPMetadataReader
+DNGTags.DNG_PRIVATE_DATA
 ;%0A%0A/**%0A 
@@ -794,16 +794,38 @@
 ageType 
+implements TagHandler 
 %7B%0A%0A    /
@@ -1062,32 +1062,46 @@
 ritDoc%7D%0A     */%0A
+    @Override%0A
     public Strin
@@ -1185,32 +1185,46 @@
 ritDoc%7D%0A     */%0A
+    @Override%0A
     public Strin
@@ -1295,32 +1295,46 @@
 ritDoc%7D%0A     */%0A
+    @Override%0A
     public Docum
@@ -1519,32 +1519,1301 @@
 class );%0A    %7D%0A%0A
+    /**%0A     * %7B@inheritDoc%7D%0A     */%0A    @Override%0A    public boolean handleTag(int tagID, int fieldType, int numValues,%0A                             int byteCount,%0A                             int valueOffset, int valueOffsetAdjustment,%0A                             int subdirOffset, ImageInfo imageInfo,%0A                             LCByteBuffer buf, ImageMetadataDirectory dir)%0A            throws IOException%0A    %7B%0A        switch (tagID) %7B%0A            case DNG_PRIVATE_DATA:%0A                // This is used for maker notes by some camera vendors.%0A                final ImageMetadata metadata = imageInfo.getCurrentMetadata();%0A                final Class%3C? extends MakerNotesDirectory%3E notesClass =%0A                        MakerNoteProbe.determineMakerNotesFrom(metadata);%0A                if (notesClass != null) %7B%0A                    final ImageMetadataDirectory notesDir =%0A                            metadata.getDirectoryFor(notesClass, true);%0A                    final EXIFMetadataReader reader =%0A                            new EXIFMetadataReader(imageInfo, buf, true);%0A                    reader.readMakerNotes(valueOffset, byteCount, notesDir);%0A                %7D%0A                return true;%0A            default:%0A                return false;%0A        %7D%0A    %7D%0A%0A
     /**%0A     * R
@@ -2929,24 +2929,38 @@
 om.%0A     */%0A
+    @Override%0A
     public v
@@ -3189,24 +3189,62 @@
 ry.class );%0A
+        reader.setTagHandler( this );%0A
         fina
@@ -3589,16 +3589,30 @@
 ough...%0A
+    @Override%0A
     publ

Handle DNG_PRIVATE_DATA dir