Package org.apache.sanselan.formats.jpeg

Source Code of org.apache.sanselan.formats.jpeg.JpegImageParser

/*
* 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.sanselan.formats.jpeg;

import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
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.sanselan.ImageFormat;
import org.apache.sanselan.ImageInfo;
import org.apache.sanselan.ImageParser;
import org.apache.sanselan.ImageReadException;
import org.apache.sanselan.common.IImageMetadata;
import org.apache.sanselan.common.byteSources.ByteSource;
import org.apache.sanselan.formats.jpeg.decoder.JpegDecoder;
import org.apache.sanselan.formats.jpeg.iptc.IPTCParser;
import org.apache.sanselan.formats.jpeg.iptc.PhotoshopApp13Data;
import org.apache.sanselan.formats.jpeg.segments.App13Segment;
import org.apache.sanselan.formats.jpeg.segments.App2Segment;
import org.apache.sanselan.formats.jpeg.segments.DQTSegment;
import org.apache.sanselan.formats.jpeg.segments.GenericSegment;
import org.apache.sanselan.formats.jpeg.segments.JFIFSegment;
import org.apache.sanselan.formats.jpeg.segments.SOFNSegment;
import org.apache.sanselan.formats.jpeg.segments.Segment;
import org.apache.sanselan.formats.jpeg.segments.UnknownSegment;
import org.apache.sanselan.formats.jpeg.xmp.JpegXmpParser;
import org.apache.sanselan.formats.tiff.TiffField;
import org.apache.sanselan.formats.tiff.TiffImageMetadata;
import org.apache.sanselan.formats.tiff.TiffImageParser;
import org.apache.sanselan.formats.tiff.constants.TiffTagConstants;
import org.apache.sanselan.util.Debug;

import com.jgraph.gaeawt.java.awt.Dimension;
import com.jgraph.gaeawt.java.awt.image.BufferedImage;

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

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

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

    public String getDefaultExtension()
    {
        return DEFAULT_EXTENSION;
    }

    private static final String DEFAULT_EXTENSION = ".jpg";

    public static final String AcceptedExtensions[] = { ".jpg", ".jpeg", };

    protected String[] getAcceptedExtensions()
    {
        return AcceptedExtensions;
    }

    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 ArrayList readSegments(ByteSource byteSource, final int markers[],
            final boolean returnAfterFirst, boolean readEverything)
            throws ImageReadException, IOException
    {
        final ArrayList result = new ArrayList();
        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));
                }

                if (returnAfterFirst)
                    return false;

                return true;
            }
        };

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

        return result;
    }

    public static final boolean permissive = true;

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

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

        int markerCount = ((App2Segment) 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(ArrayList 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 ArrayList readSegments(ByteSource byteSource, int markers[],
            boolean returnAfterFirst) throws ImageReadException, IOException
    {
        return readSegments(byteSource, markers, returnAfterFirst, false);
    }

    public byte[] getICCProfileBytes(ByteSource byteSource, Map params)
            throws ImageReadException, IOException
    {
        ArrayList segments = readSegments(byteSource,
                new int[] { JPEG_APP2_Marker, }, false);

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

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

        byte bytes[] = assembleSegments(segments);

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

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

        return (bytes);
    }

    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 ArrayList filterAPP1Segments(ArrayList v)
    {
        ArrayList result = new ArrayList();

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

        return result;
    }

    // TODO unused
    private ArrayList filterSegments(ArrayList v, List markers)
    {
        ArrayList result = new ArrayList();

        for (int i = 0; i < v.size(); i++)
        {
            Segment segment = (Segment) v.get(i);
            Integer marker = new Integer(segment.marker);
            if (markers.contains(marker))
                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
    {
        ArrayList segments = readSegments(byteSource,
                new int[] { JPEG_APP1_Marker, }, false);

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

        ArrayList 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.
     */
    public String getXmpXml(ByteSource byteSource, Map params)
            throws ImageReadException, IOException
    {

        final List result = new ArrayList();

        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 (String) result.get(0);
    }

    public JpegPhotoshopMetadata getPhotoshopMetadata(ByteSource byteSource,
            Map params) throws ImageReadException, IOException
    {
        ArrayList 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);
    }

    public Dimension getImageSize(ByteSource byteSource, Map params)
            throws ImageReadException, IOException
    {
        ArrayList 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;
    }

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

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

        ArrayList 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());

        ArrayList 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(TIFF_TAG_XRESOLUTION);
                    if (field != null)
                        x_density = ((Number) field.getValue()).doubleValue();
                }
                {
                    TiffField field = metadata
                            .findEXIFValue(TIFF_TAG_YRESOLUTION);
                    if (field != null)
                        y_density = ((Number) field.getValue()).doubleValue();
                }
                {
                    TiffField field = metadata
                            .findEXIFValue(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));
        }

        ArrayList Comments = new ArrayList();
        // TODO: comments...

        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
    // {
    //
    // ArrayList allSegments = readSegments(byteSource, null, false);
    //
    // final int SOF_MARKERS[] = new int[]{
    // SOF0Marker, SOF1Marker, SOF2Marker, SOF3Marker, SOF5Marker,
    // SOF6Marker, SOF7Marker, SOF9Marker, SOF10Marker, SOF11Marker,
    // SOF13Marker, SOF14Marker, SOF15Marker,
    // };
    //
    // ArrayList sofMarkers = new ArrayList();
    // for(int i=0;i<SOF_MARKERS.length;i++)
    // sofMarkers.add(new Integer(SOF_MARKERS[i]));
    // ArrayList 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));
    // ArrayList 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));
    // }
    //
    // ArrayList 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;
    // }

    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("");

        {
            ArrayList 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;
    }

}
TOP

Related Classes of org.apache.sanselan.formats.jpeg.JpegImageParser

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.