package net.sourceforge.gpstools.xmp;
/* gpsdings
* Copyright (C) 2007 Moritz Ringler
* $Id: XMPWriter.java 441 2010-12-13 20:04:20Z 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.RandomAccessFile;
import java.nio.channels.FileLock;
import java.nio.channels.FileChannel;
import java.nio.ByteBuffer;
import java.text.SimpleDateFormat;
import java.text.DateFormat;
import java.util.HashMap;
import java.util.TimeZone;
import java.util.Date;
import java.util.Locale;
import java.util.Map;
import net.sourceforge.gpstools.utils.*;
import net.sourceforge.gpstools.exif.*;
import net.sourceforge.gpstools.gpx.Wpt;
/** Inserts XMP APP1 marker segments into jpeg files. **/
public class XMPWriter implements GpsExifWriter{
AngleFormat cformat = new AngleFormat("DDD,MM.mmmmmm",Locale.US);
private final DateFormat XMPDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
public XMPWriter(){
XMPDateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
}
@Override
public boolean writeExifGpsInfo(File jpeg, Wpt wpt, boolean overwrite){
boolean result = false;
try{
FileChannel input = (new RandomAccessFile(jpeg, "rw")).getChannel();
FileLock lock = input.tryLock();
if(lock == null){
throw new IOException("Cannot lock input file.");
}
File tmpFile = null;
try{
XMPJpeg xmpjpg = new XMPJpeg(input, true);
ByteBuffer xmp = xmpjpg.getXMP();
int previousSize = (xmp == null)
? 0
: xmp.remaining();
XMPTree xmpEditor = (xmp == null)
? new XMPTree()
: new XMPTree(xmp);
//System.out.println(new String(xmpEditor.toUTF8Bytes(null)));
xmpEditor.setXMPProperties(XMPTree.NS_EXIF, asXMPExifProperties(wpt));
tmpFile = xmpjpg.setXMP(ByteBuffer.wrap(xmpEditor.toXPacket(previousSize)));
} finally {
lock.release();
input.close();
}
result = (tmpFile == null) || (jpeg.delete() && tmpFile.renameTo(jpeg));
if(!result){
throw new IOException("Cannot overwrite " + jpeg + " with temporary file " + tmpFile);
}
} catch (RuntimeException ex){
throw ex;
} catch (Exception ex){
ex.printStackTrace();
result = false;
}
return result;
}
protected Map<String, String> asXMPExifProperties(Wpt pt){
Map<String, String> result = new HashMap<String, String>();
result.put("GPSVersionID", "2.0.0.0");
result.put("GPSMapDatum", "WGS-84");
result.put("GPSLatitude", cformat.format(new Latitude(pt.getLat().doubleValue())));
result.put("GPSLongitude", cformat.format(new Longitude(pt.getLon().doubleValue())));
if(pt.getEle() != null){
double alti = pt.getEle().doubleValue();
result.put("GPSAltitude", (int) Math.abs(alti * 100)+"/"+100);
result.put("GPSAltitudeRef", (alti < 0)? "1" : "0");
}
final Date dateTime = pt.getTime();
if(dateTime != null){
result.put("GPSTimeStamp",XMPDateFormat.format(dateTime));
}
return result;
}
@Override
public boolean isAlwaysOverwrite(){
return true;
}
public static void main(String[] argv) throws Exception{
XMPWriter nxw = new XMPWriter();
for(String f : argv){
File ff = new File(f);
nxw.writeExifGpsInfo(ff, (new ReaderFactory()).getReader().readGPSTag(ff), true);
}
}
}