2 * This file is part of CameraPlus.
4 * Copyright (C) 2012-2013 Mohammed Sameer <msameer@foolab.org>
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 #include "qtcammetadata.h"
22 #include <gst/gsttaglist.h>
23 #include "qtcamdevice.h"
24 #include "qtcamdevice_p.h"
32 const char *orientations[] = {
39 class QtCamMetaDataPrivate {
41 void addTag(const char *tag, const QString& value) {
42 GstTagSetter *s = setter();
47 gst_tag_setter_add_tags(s, GST_TAG_MERGE_REPLACE, tag, value.toUtf8().data(), NULL);
52 void addTag(const char *tag, double value) {
53 GstTagSetter *s = setter();
58 gst_tag_setter_add_tags(s, GST_TAG_MERGE_REPLACE, tag, value, NULL);
63 void addTag(const char *tag, GstDateTime *value) {
64 GstTagSetter *s = setter();
69 gst_tag_setter_add_tags(s, GST_TAG_MERGE_REPLACE, tag, value, NULL);
74 GstTagSetter *setter() {
75 if (!device || !device->d_ptr->cameraBin) {
79 if (!GST_IS_TAG_SETTER(device->d_ptr->cameraBin)) {
83 return GST_TAG_SETTER(gst_object_ref(device->d_ptr->cameraBin));
86 QPointer<QtCamDevice> device;
89 QtCamMetaData::QtCamMetaData(QObject *parent) :
90 QObject(parent), d_ptr(new QtCamMetaDataPrivate) {
93 QtCamMetaData::~QtCamMetaData() {
95 delete d_ptr; d_ptr = 0;
98 void QtCamMetaData::setDevice(QtCamDevice *device) {
99 if (device != d_ptr->device) {
100 d_ptr->device = device;
104 void QtCamMetaData::setManufacturer(const QString& manufacturer) {
105 d_ptr->addTag(GST_TAG_DEVICE_MANUFACTURER, manufacturer);
108 void QtCamMetaData::setModel(const QString& model) {
109 d_ptr->addTag(GST_TAG_DEVICE_MODEL, model);
112 void QtCamMetaData::setCountry(const QString& country) {
113 d_ptr->addTag(GST_TAG_GEO_LOCATION_COUNTRY, country);
116 void QtCamMetaData::setCity(const QString& city) {
117 d_ptr->addTag(GST_TAG_GEO_LOCATION_CITY, city);
120 void QtCamMetaData::setSuburb(const QString& suburb) {
121 d_ptr->addTag(GST_TAG_GEO_LOCATION_SUBLOCATION, suburb);
124 void QtCamMetaData::setLongitude(double longitude) {
125 d_ptr->addTag(GST_TAG_GEO_LOCATION_LONGITUDE, longitude);
128 void QtCamMetaData::setLatitude(double latitude) {
129 d_ptr->addTag(GST_TAG_GEO_LOCATION_LATITUDE, latitude);
132 void QtCamMetaData::setElevation(double elevation) {
133 d_ptr->addTag(GST_TAG_GEO_LOCATION_ELEVATION, elevation);
136 void QtCamMetaData::setOrientation(Orientation orientation) {
137 int len = sizeof(orientations) / sizeof(orientations[0]);
139 if (orientation <= 0 || orientation >= len) {
140 orientation = Landscape;
143 d_ptr->addTag(GST_TAG_IMAGE_ORIENTATION, orientations[orientation]);
146 void QtCamMetaData::setArtist(const QString& artist) {
147 /* try the shortcut first */
148 if (!artist.contains('%')) {
149 d_ptr->addTag(GST_TAG_ARTIST, artist);
153 std::vector<char> result(artist.size());
158 qWarning() << "Failed to get current time";
159 d_ptr->addTag(GST_TAG_ARTIST, artist);
163 if (!localtime_r(&t, &tm)) {
164 qWarning() << "Failed to get local time";
165 d_ptr->addTag(GST_TAG_ARTIST, artist);
169 while (!strftime(result.data(), result.size(), artist.toUtf8().constData(), &tm)) {
170 result.resize(result.size() * 2);
173 d_ptr->addTag(GST_TAG_ARTIST, QString::fromUtf8(result.data()));
176 void QtCamMetaData::setDateTime(const QDateTime& dateTime) {
177 QDate d = dateTime.date();
178 QTime t = dateTime.time();
181 int month = d.month();
184 int minute = t.minute();
186 // GstDateTime seconds expects microseconds to be there too :|
187 gdouble seconds = t.second();
188 seconds += t.msec()/(1000.0);
190 // Current UTC time. Created through string so that the link between
191 // current and utc is lost and secsTo returns non-zero values.
192 QDateTime utcTime = QDateTime::fromString(dateTime.toUTC().toString());
193 gfloat tzoffset = (utcTime.secsTo(dateTime)/3600.0);
195 GstDateTime *dt = gst_date_time_new(tzoffset, year, month, day,
196 hour, minute, seconds);
198 d_ptr->addTag(GST_TAG_DATE_TIME, dt);
200 gst_date_time_unref(dt);
203 void QtCamMetaData::setCaptureDirection(double direction) {
204 d_ptr->addTag(GST_TAG_GEO_LOCATION_CAPTURE_DIRECTION, direction);
207 void QtCamMetaData::setHorizontalError(double error) {
208 d_ptr->addTag(GST_TAG_GEO_LOCATION_HORIZONTAL_ERROR, error);
211 void QtCamMetaData::reset() {
212 GstTagSetter *s = d_ptr->setter();
217 gst_tag_setter_reset_tags(s);