Package net.sourceforge.gpstools.exif

Source Code of net.sourceforge.gpstools.exif.SanselanExifWriter

package net.sourceforge.gpstools.exif;

/* gpsdings
* Copyright (C) 2006 Moritz Ringler
* $Id: GpsExifWriter.java 358 2008-11-24 19:06:17Z ringler $
*
*  This program is free software: you can redistribute it and/or modify
*  it under the terms of the GNU General Public License as published by
*  the Free Software Foundation, either version 3 of the License, or
*  (at your option) any later version.
*
*  This program is distributed in the hope that it will be useful,
*  but WITHOUT ANY WARRANTY; without even the implied warranty of
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*  GNU General Public License for more details.
*
*  You should have received a copy of the GNU General Public License
*  along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

import java.io.File;
import java.io.IOException;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.io.BufferedOutputStream;
import net.sourceforge.gpstools.gpx.Wpt;

import java.util.Date;
import java.util.Calendar;
import java.util.TimeZone;

import org.apache.sanselan.ImageReadException;
import org.apache.sanselan.ImageWriteException;
import org.apache.sanselan.formats.jpeg.exifRewrite.ExifRewriter;
import org.apache.sanselan.formats.tiff.TiffImageMetadata;
import org.apache.sanselan.formats.tiff.constants.TiffConstants;
import org.apache.sanselan.formats.tiff.constants.TagInfo;
import org.apache.sanselan.formats.tiff.write.TiffOutputDirectory;
import org.apache.sanselan.formats.tiff.write.TiffOutputField;
import org.apache.sanselan.formats.tiff.write.TiffOutputSet;


/**
Writes gps information to the GPS section of the Exif headers of
digital camera picture files.
**/
public class SanselanExifWriter implements GpsExifWriter {
    final private ExifRewriter rewriter = new ExifRewriter();

    static TiffOutputSet getExif(File jpegImageFile)
            throws IOException, ImageReadException, ImageWriteException{
        TiffImageMetadata exif = SanselanExifReader.getExif(jpegImageFile);
        TiffOutputSet outputSet = null;
        if (null != exif) {
            outputSet = exif.getOutputSet();
        }
        // if file does not contain any exif metadata, we create an empty
        // set of exif metadata.
        if (null == outputSet){
            outputSet = new TiffOutputSet();
        }
        return outputSet;
    }

    private boolean writeExif(File jpeg, TiffOutputSet outputSet)
            throws IOException, ImageReadException, ImageWriteException{
        final File dir = jpeg.getAbsoluteFile().getParentFile();
        String prefix = jpeg.getName();
        if(prefix.length() < 3){
            prefix += "___";
        }
        final File tmp = File.createTempFile(prefix, null, dir);

        OutputStream os = new FileOutputStream(tmp);
        os = new BufferedOutputStream(os);
        try {
            System.err.println("LOSSLESS?");
            rewriter.updateExifMetadataLossless(jpeg, os, outputSet);
        } finally {
            os.close();
        }

        if(!jpeg.delete() || !tmp.renameTo(jpeg)){
            System.err.println("Error renaming " + tmp + " to " + jpeg);
            return false;
        }
        return true;
    }

    /**
    Writes the GPS info from the specified GPX waypoint to the Exif
    header of <code>jpeg</code>.
    @param jpeg the jpeg file whose exif header will be modified
    @param wpt the coordinates, alitude and time to be associated with
    the jpeg.
    @param overwrite if the writer should overwrite existing gps
    information.
    @see #isAlwaysOverwrite
    **/
    @Override
    public boolean writeExifGpsInfo(File jpeg, Wpt wpt, boolean overwrite){
        try{
            TiffOutputSet outputSet = SanselanExifWriter.getExif(jpeg);
            outputSet.setGPSInDegrees(wpt.getLon().doubleValue(), wpt.getLat().doubleValue());
            TiffOutputDirectory gpsIfd = outputSet.getGPSDirectory();
            TiffOutputField field;
            final int byteOrder = outputSet.byteOrder;

            /* version */
            field = makeField(
                TiffConstants.GPS_TAG_GPS_VERSION_ID,
                new byte[]{
                (byte) 2, (byte) 2, (byte) 0, (byte) 0});
            gpsIfd.removeField(TiffConstants.GPS_TAG_GPS_VERSION_ID);
            gpsIfd.add(field);

            /* map datum */
            //System.err.println("Writing map datum.");
            field = makeField(
                TiffConstants.GPS_TAG_GPS_MAP_DATUM,
                byteOrder, "WGS-84");
            gpsIfd.removeField(TiffConstants.GPS_TAG_GPS_MAP_DATUM);
            gpsIfd.add(field);

            /* elevation */
            if(wpt.getEle() != null){
                //System.err.println("Writing ele ref.");
                double ele = wpt.getEle().doubleValue();
                final Byte eleref = new Byte(
                    (byte) ((ele < 0)
                    ? TiffConstants.GPS_TAG_GPS_ALTITUDE_REF_VALUE_BELOW_SEA_LEVEL
                    : TiffConstants.GPS_TAG_GPS_ALTITUDE_REF_VALUE_ABOVE_SEA_LEVEL)
                );
                // use custom tag info because GPS_TAG_GPS_ALTITUDE_REF has length -1
                TagInfo tag  = new TagInfo(
                    "GPS Altitude Ref",
                    0x0005,
                    TiffConstants.FIELD_TYPE_DESCRIPTION_BYTE,
                    1,
                    TiffConstants.EXIF_DIRECTORY_GPS);
                field = TiffOutputField.create(
                    tag, byteOrder, eleref);
                gpsIfd.removeField(TiffConstants.GPS_TAG_GPS_ALTITUDE_REF);
                gpsIfd.add(field);

                //System.err.println("Writing ele.");
                // use custom tag info because GPS_TAG_GPS_ALTITUDE_REF has length -1
                tag  = new TagInfo(
                    "GPS Altitude",
                    0x0006,
                    TiffConstants.FIELD_TYPE_DESCRIPTION_RATIONAL,
                    1,
                    TiffConstants.EXIF_DIRECTORY_GPS);
                field = TiffOutputField.create(
                    tag,
                    byteOrder, new Double(ele));
                gpsIfd.removeField(TiffConstants.GPS_TAG_GPS_ALTITUDE);
                gpsIfd.add(field);
            }

            /* dateTime */
            //System.err.println("Writing date/time.");
            if(wpt.getTime() != null){
                Date dateTime = wpt.getTime();
                Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
                cal.setTime(dateTime);
                field = TiffOutputField.create(
                    TiffConstants.GPS_TAG_GPS_TIME_STAMP,
                    byteOrder, new Double[]{
                        new Double(cal.get(Calendar.HOUR_OF_DAY)),
                        new Double(cal.get(Calendar.MINUTE)),
                        new Double(cal.get(Calendar.SECOND))
                    });
                gpsIfd.removeField(TiffConstants.GPS_TAG_GPS_TIME_STAMP);
                gpsIfd.add(field);

                field = makeField(
                    TiffConstants.GPS_TAG_GPS_DATE_STAMP,
                    byteOrder,
                    AbstractExecExifWriter.formatAsExifDate(dateTime));
                gpsIfd.removeField(TiffConstants.GPS_TAG_GPS_DATE_STAMP);
                gpsIfd.add(field);
            }
            return writeExif(jpeg, outputSet);
        } catch (Exception ex) {
            System.err.println(ex);
            ex.printStackTrace();
            return false;
        }
    }

    private static TiffOutputField makeField(TagInfo tag, byte[] bytes){
        return new TiffOutputField(tag, tag.dataTypes[0], tag.length, bytes);
    }

    private static TiffOutputField makeField(TagInfo tag, int byteOrder, String str) throws ImageWriteException{
        return new TiffOutputField(tag, tag.dataTypes[0], str.length() + 1,
            tag.dataTypes[0].writeData(str + (char) 0, byteOrder));
    }

    /**
    Returns whether a specific writer implementation will or will not
    overwrite existing gps information regardless of the <code>overwrite</code>
    parameter passed to {@link #writeExifGpsInfo writeExifGpsInfo}
    **/
    @Override
    public boolean isAlwaysOverwrite(){
        return true;
    }
}
TOP

Related Classes of net.sourceforge.gpstools.exif.SanselanExifWriter

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.