/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.commons.sanselan.formats.jpeg;

import java.awt.Dimension;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.sanselan.ImageFormat;
import org.apache.commons.sanselan.ImageInfo;
import org.apache.commons.sanselan.ImageParser;
import org.apache.commons.sanselan.ImageReadException;
import org.apache.commons.sanselan.common.IImageMetadata;
import org.apache.commons.sanselan.common.bytesource.ByteSource;
import org.apache.commons.sanselan.formats.jpeg.decoder.JpegDecoder;
import org.apache.commons.sanselan.formats.jpeg.iptc.IptcParser;
import org.apache.commons.sanselan.formats.jpeg.iptc.PhotoshopApp13Data;
import org.apache.commons.sanselan.formats.jpeg.segments.App13Segment;
import org.apache.commons.sanselan.formats.jpeg.segments.App2Segment;
import org.apache.commons.sanselan.formats.jpeg.segments.ComSegment;
import org.apache.commons.sanselan.formats.jpeg.segments.DqtSegment;
import org.apache.commons.sanselan.formats.jpeg.segments.GenericSegment;
import org.apache.commons.sanselan.formats.jpeg.segments.JfifSegment;
import org.apache.commons.sanselan.formats.jpeg.segments.Segment;
import org.apache.commons.sanselan.formats.jpeg.segments.SofnSegment;
import org.apache.commons.sanselan.formats.jpeg.segments.UnknownSegment;
import org.apache.commons.sanselan.formats.jpeg.xmp.JpegXmpParser;
import org.apache.commons.sanselan.formats.tiff.TiffField;
import org.apache.commons.sanselan.formats.tiff.TiffImageMetadata;
import org.apache.commons.sanselan.formats.tiff.TiffImageParser;
import org.apache.commons.sanselan.formats.tiff.constants.TiffTagConstants;
import org.apache.commons.sanselan.util.Debug;

public class JpegImageParser extends ImageParser implements JpegConstants
{
    public JpegImageParser()
    {
        setByteOrder(BYTE_ORDER_NETWORK);
        // setDebug(true);
    }

    @Override
    protected ImageFormat[] getAcceptedTypes()
    {
        return new ImageFormat[] { ImageFormat.IMAGE_FORMAT_JPEG, //
        };
    }

    @Override
    public String getName()
    {
        return "Jpeg-Custom";
    }

    @Override
    public String getDefaultExtension()
    {
        return DEFAULT_EXTENSION;
    }

    private static final String DEFAULT_EXTENSION = ".jpg";

    private static final String ACCEPTED_EXTENSIONS[] = { ".jpg", ".jpeg", };

    @Override
    protected String[] getAcceptedExtensions()
    {
        return ACCEPTED_EXTENSIONS;
    }

    @Override
    public final BufferedImage getBufferedImage(ByteSource byteSource,
            Map params) throws ImageReadException, IOException
    {
        JpegDecoder jpegDecoder = new JpegDecoder();
        return jpegDecoder.decode(byteSource);
    }

    private boolean keepMarker(int marker, int markers[])
    {
        if (markers == null)
            return true;

        for (int i = 0; i < markers.length; i++)
        {
            if (markers[i] == marker)
                return true;
        }

        return false;
    }

    public List<Segment> readSegments(ByteSource byteSource, final int markers[],
            final boolean returnAfterFirst, boolean readEverything)
            throws ImageReadException, IOException
    {
        final List<Segment> result = new ArrayList<Segment>();
        final JpegImageParser parser = this;
        final int[] sofnSegments = {
                // kJFIFMarker,
                SOF0Marker,

                SOF1Marker, SOF2Marker, SOF3Marker, SOF5Marker, SOF6Marker,
                SOF7Marker, SOF9Marker, SOF10Marker, SOF11Marker, SOF13Marker,
                SOF14Marker, SOF15Marker,
        };

        JpegUtils.Visitor visitor = new JpegUtils.Visitor() {
            // return false to exit before reading image data.
            public boolean beginSOS()
            {
                return false;
            }

            public void visitSOS(int marker, byte markerBytes[],
                    byte imageData[])
            {
            }

            // return false to exit traversal.
            public boolean visitSegment(int marker, byte markerBytes[],
                    int markerLength, byte markerLengthBytes[],
                    byte segmentData[]) throws ImageReadException, IOException
            {
                if (marker == EOIMarker)
                    return false;

                // Debug.debug("visitSegment marker", marker);
                // // Debug.debug("visitSegment keepMarker(marker, markers)",
                // keepMarker(marker, markers));
                // Debug.debug("visitSegment keepMarker(marker, markers)",
                // keepMarker(marker, markers));

                if (!keepMarker(marker, markers))
                    return true;

                if (marker == JPEG_APP13_Marker)
                {
                    // Debug.debug("app 13 segment data", segmentData.length);
                    result.add(new App13Segment(parser, marker, segmentData));
                } else if (marker == JPEG_APP2_Marker)
                {
                    result.add(new App2Segment(marker, segmentData));
                } else if (marker == JFIFMarker)
                {
                    result.add(new JfifSegment(marker, segmentData));
                } else if (Arrays.binarySearch(sofnSegments, marker) >= 0)
                {
                    result.add(new SofnSegment(marker, segmentData));
                } else if (marker == DQTMarker)
                {
                    result.add(new DqtSegment(marker, segmentData));
                } else if ((marker >= JPEG_APP1_Marker)
                        && (marker <= JPEG_APP15_Marker))
                {
                    result.add(new UnknownSegment(marker, segmentData));
                } else if (marker == COMMarker)
                {
                    result.add(new ComSegment(marker, segmentData));
                }

                if (returnAfterFirst)
                    return false;

                return true;
            }
        };

        new JpegUtils().traverseJFIF(byteSource, visitor);

        return result;
    }

    public static final boolean permissive = true;

    private byte[] assembleSegments(List<App2Segment> v) throws ImageReadException
    {
        try
        {
            return assembleSegments(v, false);
        } catch (ImageReadException e)
        {
            return assembleSegments(v, true);
        }
    }

    private byte[] assembleSegments(List<App2Segment> v, boolean start_with_zero)
            throws ImageReadException
    {
        if (v.size() < 1)
            throw new ImageReadException("No App2 Segments Found.");

        int markerCount = v.get(0).num_markers;

        // if (permissive && (markerCount == 0))
        // markerCount = v.size();

        if (v.size() != markerCount)
            throw new ImageReadException("App2 Segments Missing.  Found: "
                    + v.size() + ", Expected: " + markerCount + ".");

        Collections.sort(v);

        int offset = start_with_zero ? 0 : 1;

        int total = 0;
        for (int i = 0; i < v.size(); i++)
        {
            App2Segment segment = (App2Segment) v.get(i);

            if ((i + offset) != segment.cur_marker)
            {
                dumpSegments(v);
                throw new ImageReadException(
                        "Incoherent App2 Segment Ordering.  i: " + i
                                + ", segment[" + i + "].cur_marker: "
                                + segment.cur_marker + ".");
            }

            if (markerCount != segment.num_markers)
            {
                dumpSegments(v);
                throw new ImageReadException(
                        "Inconsistent App2 Segment Count info.  markerCount: "
                                + markerCount + ", segment[" + i
                                + "].num_markers: " + segment.num_markers + ".");
            }

            total += segment.icc_bytes.length;
        }

        byte result[] = new byte[total];
        int progress = 0;

        for (int i = 0; i < v.size(); i++)
        {
            App2Segment segment = (App2Segment) v.get(i);

            System.arraycopy(segment.icc_bytes, 0, result, progress,
                    segment.icc_bytes.length);
            progress += segment.icc_bytes.length;
        }

        return result;
    }

    private void dumpSegments(List<? extends Segment> v)
    {
        Debug.debug();
        Debug.debug("dumpSegments", v.size());

        for (int i = 0; i < v.size(); i++)
        {
            App2Segment segment = (App2Segment) v.get(i);

            Debug.debug((i) + ": " + segment.cur_marker + " / "
                    + segment.num_markers);
        }
        Debug.debug();
    }

    public List<Segment> readSegments(ByteSource byteSource, int markers[],
            boolean returnAfterFirst) throws ImageReadException, IOException
    {
        return readSegments(byteSource, markers, returnAfterFirst, false);
    }

    @Override
    public byte[] getICCProfileBytes(ByteSource byteSource, Map params)
            throws ImageReadException, IOException
    {
        List<Segment> segments = readSegments(byteSource,
                new int[] { JPEG_APP2_Marker, }, false);

        List<App2Segment> filtered = new ArrayList<App2Segment>();
        if (segments != null)
        {
            // throw away non-icc profile app2 segments.
            for (int i = 0; i < segments.size(); i++)
            {
                App2Segment segment = (App2Segment) segments.get(i);
                if (segment.icc_bytes != null)
                    filtered.add(segment);
            }
        }

        if ((filtered == null) || (filtered.size() < 1))
            return null;

        byte bytes[] = assembleSegments(filtered);

        if (debug)
            System.out.println("bytes" + ": "
                    + ((bytes == null) ? null : "" + bytes.length));

        if (debug)
            System.out.println("");

        return (bytes);
    }

    @Override
    public IImageMetadata getMetadata(ByteSource byteSource, Map params)
            throws ImageReadException, IOException
    {
        TiffImageMetadata exif = getExifMetadata(byteSource, params);

        JpegPhotoshopMetadata photoshop = getPhotoshopMetadata(byteSource,
                params);

        if (null == exif && null == photoshop)
            return null;

        JpegImageMetadata result = new JpegImageMetadata(photoshop, exif);

        return result;
    }

    public static boolean isExifAPP1Segment(GenericSegment segment)
    {
        return byteArrayHasPrefix(segment.bytes, EXIF_IDENTIFIER_CODE);
    }

    private List<Segment> filterAPP1Segments(List<Segment> v)
    {
        List<Segment> result = new ArrayList<Segment>();

        for (int i = 0; i < v.size(); i++)
        {
            GenericSegment segment = (GenericSegment) v.get(i);
            if (isExifAPP1Segment(segment))
                result.add(segment);
        }

        return result;
    }

    public TiffImageMetadata getExifMetadata(ByteSource byteSource, Map params)
            throws ImageReadException, IOException
    {
        byte bytes[] = getExifRawData(byteSource);
        if (null == bytes)
            return null;

        if (params == null)
            params = new HashMap();
        if (!params.containsKey(PARAM_KEY_READ_THUMBNAILS))
            params.put(PARAM_KEY_READ_THUMBNAILS, Boolean.TRUE);

        return (TiffImageMetadata) new TiffImageParser().getMetadata(bytes,
                params);
    }

    public byte[] getExifRawData(ByteSource byteSource)
            throws ImageReadException, IOException
    {
        List<Segment> segments = readSegments(byteSource,
                new int[] { JPEG_APP1_Marker, }, false);

        if ((segments == null) || (segments.size() < 1))
            return null;

        List<Segment> exifSegments = filterAPP1Segments(segments);
        if (debug)
            System.out.println("exif_segments.size" + ": "
                    + exifSegments.size());

        // Debug.debug("segments", segments);
        // Debug.debug("exifSegments", exifSegments);

        // TODO: concatenate if multiple segments, need example.
        if (exifSegments.size() < 1)
            return null;
        if (exifSegments.size() > 1)
            throw new ImageReadException(
                    "Sanselan currently can't parse EXIF metadata split across multiple APP1 segments.  "
                            + "Please send this image to the Sanselan project.");

        GenericSegment segment = (GenericSegment) exifSegments.get(0);
        byte bytes[] = segment.bytes;

        // byte head[] = readBytearray("exif head", bytes, 0, 6);
        //
        // Debug.debug("head", head);

        return getByteArrayTail("trimmed exif bytes", bytes, 6);
    }

    public boolean hasExifSegment(ByteSource byteSource)
            throws ImageReadException, IOException
    {
        final boolean result[] = { false, };

        JpegUtils.Visitor visitor = new JpegUtils.Visitor() {
            // return false to exit before reading image data.
            public boolean beginSOS()
            {
                return false;
            }

            public void visitSOS(int marker, byte markerBytes[],
                    byte imageData[])
            {
            }

            // return false to exit traversal.
            public boolean visitSegment(int marker, byte markerBytes[],
                    int markerLength, byte markerLengthBytes[],
                    byte segmentData[]) throws ImageReadException, IOException
            {
                if (marker == 0xffd9)
                    return false;

                if (marker == JPEG_APP1_Marker)
                {
                    if (byteArrayHasPrefix(segmentData, EXIF_IDENTIFIER_CODE))
                    {
                        result[0] = true;
                        return false;
                    }
                }

                return true;
            }
        };

        new JpegUtils().traverseJFIF(byteSource, visitor);

        return result[0];
    }

    public boolean hasIptcSegment(ByteSource byteSource)
            throws ImageReadException, IOException
    {
        final boolean result[] = { false, };

        JpegUtils.Visitor visitor = new JpegUtils.Visitor() {
            // return false to exit before reading image data.
            public boolean beginSOS()
            {
                return false;
            }

            public void visitSOS(int marker, byte markerBytes[],
                    byte imageData[])
            {
            }

            // return false to exit traversal.
            public boolean visitSegment(int marker, byte markerBytes[],
                    int markerLength, byte markerLengthBytes[],
                    byte segmentData[]) throws ImageReadException, IOException
            {
                if (marker == 0xffd9)
                    return false;

                if (marker == JPEG_APP13_Marker)
                {
                    if (new IptcParser().isPhotoshopJpegSegment(segmentData))
                    {
                        result[0] = true;
                        return false;
                    }
                }

                return true;
            }
        };

        new JpegUtils().traverseJFIF(byteSource, visitor);

        return result[0];
    }

    public boolean hasXmpSegment(ByteSource byteSource)
            throws ImageReadException, IOException
    {
        final boolean result[] = { false, };

        JpegUtils.Visitor visitor = new JpegUtils.Visitor() {
            // return false to exit before reading image data.
            public boolean beginSOS()
            {
                return false;
            }

            public void visitSOS(int marker, byte markerBytes[],
                    byte imageData[])
            {
            }

            // return false to exit traversal.
            public boolean visitSegment(int marker, byte markerBytes[],
                    int markerLength, byte markerLengthBytes[],
                    byte segmentData[]) throws ImageReadException, IOException
            {
                if (marker == 0xffd9)
                    return false;

                if (marker == JPEG_APP1_Marker)
                {
                    if (new JpegXmpParser().isXmpJpegSegment(segmentData))
                    {
                        result[0] = true;
                        return false;
                    }
                }

                return true;
            }
        };
        new JpegUtils().traverseJFIF(byteSource, visitor);

        return result[0];
    }

    /**
     * Extracts embedded XML metadata as XML string.
     * <p>
     *
     * @param byteSource
     *            File containing image data.
     * @param params
     *            Map of optional parameters, defined in SanselanConstants.
     * @return Xmp Xml as String, if present. Otherwise, returns null.
     */
    @Override
    public String getXmpXml(ByteSource byteSource, Map params)
            throws ImageReadException, IOException
    {

        final List<String> result = new ArrayList<String>();

        JpegUtils.Visitor visitor = new JpegUtils.Visitor() {
            // return false to exit before reading image data.
            public boolean beginSOS()
            {
                return false;
            }

            public void visitSOS(int marker, byte markerBytes[],
                    byte imageData[])
            {
            }

            // return false to exit traversal.
            public boolean visitSegment(int marker, byte markerBytes[],
                    int markerLength, byte markerLengthBytes[],
                    byte segmentData[]) throws ImageReadException, IOException
            {
                if (marker == 0xffd9)
                    return false;

                if (marker == JPEG_APP1_Marker)
                {
                    if (new JpegXmpParser().isXmpJpegSegment(segmentData))
                    {
                        result.add(new JpegXmpParser()
                                .parseXmpJpegSegment(segmentData));
                        return false;
                    }
                }

                return true;
            }
        };
        new JpegUtils().traverseJFIF(byteSource, visitor);

        if (result.size() < 1)
            return null;
        if (result.size() > 1)
            throw new ImageReadException(
                    "Jpeg file contains more than one XMP segment.");
        return result.get(0);
    }

    public JpegPhotoshopMetadata getPhotoshopMetadata(ByteSource byteSource,
            Map params) throws ImageReadException, IOException
    {
        List<Segment> segments = readSegments(byteSource,
                new int[] { JPEG_APP13_Marker, }, false);

        if ((segments == null) || (segments.size() < 1))
            return null;

        PhotoshopApp13Data photoshopApp13Data = null;

        for (int i = 0; i < segments.size(); i++)
        {
            App13Segment segment = (App13Segment) segments.get(i);

            PhotoshopApp13Data data = segment.parsePhotoshopSegment(params);
            if (data != null && photoshopApp13Data != null)
                throw new ImageReadException(
                        "Jpeg contains more than one Photoshop App13 segment.");

            photoshopApp13Data = data;
        }

        if(null==photoshopApp13Data)
            return null;
        return new JpegPhotoshopMetadata(photoshopApp13Data);
    }

    @Override
    public Dimension getImageSize(ByteSource byteSource, Map params)
            throws ImageReadException, IOException
    {
        List<Segment> segments = readSegments(byteSource, new int[] {
                // kJFIFMarker,
                SOF0Marker,

                SOF1Marker, SOF2Marker, SOF3Marker, SOF5Marker, SOF6Marker,
                SOF7Marker, SOF9Marker, SOF10Marker, SOF11Marker, SOF13Marker,
                SOF14Marker, SOF15Marker,

        }, true);

        if ((segments == null) || (segments.size() < 1))
            throw new ImageReadException("No JFIF Data Found.");

        if (segments.size() > 1)
            throw new ImageReadException("Redundant JFIF Data Found.");

        SofnSegment fSOFNSegment = (SofnSegment) segments.get(0);

        return new Dimension(fSOFNSegment.width, fSOFNSegment.height);
    }

    public byte[] embedICCProfile(byte image[], byte profile[])
    {
        return null;
    }

    @Override
    public boolean embedICCProfile(File src, File dst, byte profile[])
    {
        return false;
    }

    @Override
    public ImageInfo getImageInfo(ByteSource byteSource, Map params)
            throws ImageReadException, IOException
    {
        // List allSegments = readSegments(byteSource, null, false);

        List<Segment> SOF_segments = readSegments(byteSource, new int[] {
                // kJFIFMarker,

                SOF0Marker, SOF1Marker, SOF2Marker, SOF3Marker, SOF5Marker,
                SOF6Marker, SOF7Marker, SOF9Marker, SOF10Marker, SOF11Marker,
                SOF13Marker, SOF14Marker, SOF15Marker,

        }, false);

        if (SOF_segments == null)
            throw new ImageReadException("No SOFN Data Found.");

        // if (SOF_segments.size() != 1)
        // System.out.println("Incoherent SOFN Data Found: "
        // + SOF_segments.size());

        List<Segment> jfifSegments = readSegments(byteSource,
                new int[] { JFIFMarker, }, true);

        SofnSegment fSOFNSegment = (SofnSegment) SOF_segments.get(0);
        // SofnSegment fSOFNSegment = (SofnSegment) findSegment(segments,
        // SOFNmarkers);

        if (fSOFNSegment == null)
            throw new ImageReadException("No SOFN Data Found.");

        int Width = fSOFNSegment.width;
        int Height = fSOFNSegment.height;

        JfifSegment jfifSegment = null;

        if ((jfifSegments != null) && (jfifSegments.size() > 0))
            jfifSegment = (JfifSegment) jfifSegments.get(0);

        // JfifSegment fTheJFIFSegment = (JfifSegment) findSegment(segments,
        // kJFIFMarker);

        double x_density = -1.0;
        double y_density = -1.0;
        double units_per_inch = -1.0;
        // int JFIF_major_version;
        // int JFIF_minor_version;
        String FormatDetails;

        if (jfifSegment != null)
        {
            x_density = jfifSegment.xDensity;
            y_density = jfifSegment.yDensity;
            int density_units = jfifSegment.densityUnits;
            // JFIF_major_version = fTheJFIFSegment.JFIF_major_version;
            // JFIF_minor_version = fTheJFIFSegment.JFIF_minor_version;

            FormatDetails = "Jpeg/JFIF v." + jfifSegment.jfifMajorVersion + "."
                    + jfifSegment.jfifMinorVersion;

            switch (density_units)
            {
            case 0:
                break;
            case 1: // inches
                units_per_inch = 1.0;
                break;
            case 2: // cms
                units_per_inch = 2.54;
                break;
            default:
                break;
            }
        } else
        {
            JpegImageMetadata metadata = (JpegImageMetadata) getMetadata(
                    byteSource, params);

            if (metadata != null)
            {
                {
                    TiffField field = metadata
                            .findEXIFValue(TiffTagConstants.TIFF_TAG_XRESOLUTION);
                    if (field != null)
                        x_density = ((Number) field.getValue()).doubleValue();
                }
                {
                    TiffField field = metadata
                            .findEXIFValue(TiffTagConstants.TIFF_TAG_YRESOLUTION);
                    if (field != null)
                        y_density = ((Number) field.getValue()).doubleValue();
                }
                {
                    TiffField field = metadata
                            .findEXIFValue(TiffTagConstants.TIFF_TAG_RESOLUTION_UNIT);
                    if (field != null)
                    {
                        int density_units = ((Number) field.getValue())
                                .intValue();

                        switch (density_units)
                        {
                        case 1:
                            break;
                        case 2: // inches
                            units_per_inch = 1.0;
                            break;
                        case 3: // cms
                            units_per_inch = 2.54;
                            break;
                        default:
                            break;
                        }
                    }

                }
            }

            FormatDetails = "Jpeg/DCM";

        }

        int PhysicalHeightDpi = -1;
        float PhysicalHeightInch = -1;
        int PhysicalWidthDpi = -1;
        float PhysicalWidthInch = -1;

        if (units_per_inch > 0)
        {
            PhysicalWidthDpi = (int) Math.round(x_density / units_per_inch);
            PhysicalWidthInch = (float) (Width / (x_density * units_per_inch));
            PhysicalHeightDpi = (int) Math.round(y_density     * units_per_inch);
            PhysicalHeightInch = (float) (Height / (y_density * units_per_inch));
        }

        List<String> Comments = new ArrayList<String>();
        List<Segment> commentSegments = readSegments(byteSource,
                new int[] { COMMarker }, false);
        for (int i = 0; i < commentSegments.size(); i++)
        {
            ComSegment comSegment = (ComSegment) commentSegments.get(i);
            String comment = "";
            try {
                comment = new String(comSegment.comment, "UTF-8");
            } catch (UnsupportedEncodingException cannotHappen) {
            }
            Comments.add(comment);
        }

        int Number_of_components = fSOFNSegment.numberOfComponents;
        int Precision = fSOFNSegment.precision;

        int BitsPerPixel = Number_of_components * Precision;
        ImageFormat Format = ImageFormat.IMAGE_FORMAT_JPEG;
        String FormatName = "JPEG (Joint Photographic Experts Group) Format";
        String MimeType = "image/jpeg";
        // we ought to count images, but don't yet.
        int NumberOfImages = 1;
        // not accurate ... only reflects first
        boolean isProgressive = fSOFNSegment.marker == SOF2Marker;

        boolean isTransparent = false; // TODO: inaccurate.
        boolean usesPalette = false; // TODO: inaccurate.
        int ColorType;
        if (Number_of_components == 1)
            ColorType = ImageInfo.COLOR_TYPE_BW;
        else if (Number_of_components == 3)
            ColorType = ImageInfo.COLOR_TYPE_RGB;
        else if (Number_of_components == 4)
            ColorType = ImageInfo.COLOR_TYPE_CMYK;
        else
            ColorType = ImageInfo.COLOR_TYPE_UNKNOWN;

        String compressionAlgorithm = ImageInfo.COMPRESSION_ALGORITHM_JPEG;

        ImageInfo result = new ImageInfo(FormatDetails, BitsPerPixel, Comments,
                Format, FormatName, Height, MimeType, NumberOfImages,
                PhysicalHeightDpi, PhysicalHeightInch, PhysicalWidthDpi,
                PhysicalWidthInch, Width, isProgressive, isTransparent,
                usesPalette, ColorType, compressionAlgorithm);

        return result;
    }

    // public ImageInfo getImageInfo(ByteSource byteSource, Map params)
    // throws ImageReadException, IOException
    // {
    //
    // List allSegments = readSegments(byteSource, null, false);
    //
    // final int SOF_MARKERS[] = new int[]{
    // SOF0Marker, SOF1Marker, SOF2Marker, SOF3Marker, SOF5Marker,
    // SOF6Marker, SOF7Marker, SOF9Marker, SOF10Marker, SOF11Marker,
    // SOF13Marker, SOF14Marker, SOF15Marker,
    // };
    //
    // List sofMarkers = new ArrayList();
    // for(int i=0;i<SOF_MARKERS.length;i++)
    // sofMarkers.add(new Integer(SOF_MARKERS[i]));
    // List SOFSegments = filterSegments(allSegments, sofMarkers);
    // if (SOFSegments == null || SOFSegments.size()<1)
    // throw new ImageReadException("No SOFN Data Found.");
    //
    // List jfifMarkers = new ArrayList();
    // jfifMarkers.add(new Integer(JFIFMarker));
    // List jfifSegments = filterSegments(allSegments, jfifMarkers);
    //
    // SofnSegment firstSOFNSegment = (SofnSegment) SOFSegments.get(0);
    //
    // int Width = firstSOFNSegment.width;
    // int Height = firstSOFNSegment.height;
    //
    // JfifSegment jfifSegment = null;
    //
    // if (jfifSegments != null && jfifSegments.size() > 0)
    // jfifSegment = (JfifSegment) jfifSegments.get(0);
    //
    // double x_density = -1.0;
    // double y_density = -1.0;
    // double units_per_inch = -1.0;
    // // int JFIF_major_version;
    // // int JFIF_minor_version;
    // String FormatDetails;
    //
    // if (jfifSegment != null)
    // {
    // x_density = jfifSegment.xDensity;
    // y_density = jfifSegment.yDensity;
    // int density_units = jfifSegment.densityUnits;
    // // JFIF_major_version = fTheJFIFSegment.JFIF_major_version;
    // // JFIF_minor_version = fTheJFIFSegment.JFIF_minor_version;
    //
    // FormatDetails = "Jpeg/JFIF v." + jfifSegment.jfifMajorVersion
    // + "." + jfifSegment.jfifMinorVersion;
    //
    // switch (density_units)
    // {
    // case 0 :
    // break;
    // case 1 : // inches
    // units_per_inch = 1.0;
    // break;
    // case 2 : // cms
    // units_per_inch = 2.54;
    // break;
    // default :
    // break;
    // }
    // }
    // else
    // {
    // JpegImageMetadata metadata = (JpegImageMetadata) getMetadata(byteSource,
    // params);
    //
    // {
    // TiffField field = metadata
    // .findEXIFValue(TiffField.TIFF_TAG_XRESOLUTION);
    // if (field == null)
    // throw new ImageReadException("No XResolution");
    //
    // x_density = ((Number) field.getValue()).doubleValue();
    // }
    // {
    // TiffField field = metadata
    // .findEXIFValue(TiffField.TIFF_TAG_YRESOLUTION);
    // if (field == null)
    // throw new ImageReadException("No YResolution");
    //
    // y_density = ((Number) field.getValue()).doubleValue();
    // }
    // {
    // TiffField field = metadata
    // .findEXIFValue(TiffField.TIFF_TAG_RESOLUTION_UNIT);
    // if (field == null)
    // throw new ImageReadException("No ResolutionUnits");
    //
    // int density_units = ((Number) field.getValue()).intValue();
    //
    // switch (density_units)
    // {
    // case 1 :
    // break;
    // case 2 : // inches
    // units_per_inch = 1.0;
    // break;
    // case 3 : // cms
    // units_per_inch = 2.54;
    // break;
    // default :
    // break;
    // }
    //
    // }
    //
    // FormatDetails = "Jpeg/DCM";
    //
    // }
    //
    // int PhysicalHeightDpi = -1;
    // float PhysicalHeightInch = -1;
    // int PhysicalWidthDpi = -1;
    // float PhysicalWidthInch = -1;
    //
    // if (units_per_inch > 0)
    // {
    // PhysicalWidthDpi = (int) Math.round((double) x_density
    // / units_per_inch);
    // PhysicalWidthInch = (float) ((double) Width / (x_density *
    // units_per_inch));
    // PhysicalHeightDpi = (int) Math.round((double) y_density
    // * units_per_inch);
    // PhysicalHeightInch = (float) ((double) Height / (y_density *
    // units_per_inch));
    // }
    //
    // List Comments = new ArrayList();
    // // TODO: comments...
    //
    // int Number_of_components = firstSOFNSegment.numberOfComponents;
    // int Precision = firstSOFNSegment.precision;
    //
    // int BitsPerPixel = Number_of_components * Precision;
    // ImageFormat Format = ImageFormat.IMAGE_FORMAT_JPEG;
    // String FormatName = "JPEG (Joint Photographic Experts Group) Format";
    // String MimeType = "image/jpeg";
    // // we ought to count images, but don't yet.
    // int NumberOfImages = -1;
    // // not accurate ... only reflects first
    // boolean isProgressive = firstSOFNSegment.marker == SOF2Marker;
    //
    // boolean isTransparent = false; // TODO: inaccurate.
    // boolean usesPalette = false; // TODO: inaccurate.
    // int ColorType;
    // if (Number_of_components == 1)
    // ColorType = ImageInfo.COLOR_TYPE_BW;
    // else if (Number_of_components == 3)
    // ColorType = ImageInfo.COLOR_TYPE_RGB;
    // else if (Number_of_components == 4)
    // ColorType = ImageInfo.COLOR_TYPE_CMYK;
    // else
    // ColorType = ImageInfo.COLOR_TYPE_UNKNOWN;
    //
    // String compressionAlgorithm = ImageInfo.COMPRESSION_ALGORITHM_JPEG;
    //
    // ImageInfo result = new ImageInfo(FormatDetails, BitsPerPixel, Comments,
    // Format, FormatName, Height, MimeType, NumberOfImages,
    // PhysicalHeightDpi, PhysicalHeightInch, PhysicalWidthDpi,
    // PhysicalWidthInch, Width, isProgressive, isTransparent,
    // usesPalette, ColorType, compressionAlgorithm);
    //
    // return result;
    // }

    @Override
    public boolean dumpImageFile(PrintWriter pw, ByteSource byteSource)
            throws ImageReadException, IOException
    {
        pw.println("tiff.dumpImageFile");

        {
            ImageInfo imageInfo = getImageInfo(byteSource);
            if (imageInfo == null)
                return false;

            imageInfo.toString(pw, "");
        }

        pw.println("");

        {
            List<Segment> segments = readSegments(byteSource, null, false);

            if (segments == null)
                throw new ImageReadException("No Segments Found.");

            for (int d = 0; d < segments.size(); d++)
            {

                Segment segment = (Segment) segments.get(d);

                NumberFormat nf = NumberFormat.getIntegerInstance();
                // this.debugNumber("found, marker: ", marker, 4);
                pw.println(d + ": marker: "
                        + Integer.toHexString(segment.marker) + ", "
                        + segment.getDescription() + " (length: "
                        + nf.format(segment.length) + ")");
                segment.dump(pw);
            }

            pw.println("");
        }

        return true;
    }

}
