[Exif] Add libexif dependency, partial implementation of getExifInfo()
authorRafal Lelusz <r.lelusz@samsung.com>
Wed, 7 Jan 2015 13:08:06 +0000 (14:08 +0100)
committerRafal Galka <r.galka@samsung.com>
Wed, 7 Jan 2015 13:14:51 +0000 (22:14 +0900)
Change-Id: I9d4d8e95fdb8940cb1013f2bbd86359d226c441d
Signed-off-by: Rafal Lelusz <r.lelusz@samsung.com>
29 files changed:
src/exif/ExifGPSLocation.cpp [new file with mode: 0644]
src/exif/ExifGPSLocation.h [new file with mode: 0644]
src/exif/ExifInformation.cpp [new file with mode: 0644]
src/exif/ExifInformation.h [new file with mode: 0644]
src/exif/ExifTagSaver.cpp [new file with mode: 0644]
src/exif/ExifTagSaver.h [new file with mode: 0644]
src/exif/ExifUtil.cpp [new file with mode: 0644]
src/exif/ExifUtil.h [new file with mode: 0644]
src/exif/JpegFile.cpp [new file with mode: 0644]
src/exif/JpegFile.h [new file with mode: 0644]
src/exif/Rational.cpp [new file with mode: 0644]
src/exif/Rational.h [new file with mode: 0644]
src/exif/exif.gyp
src/exif/exif_api.js
src/exif/exif_instance.cc
src/exif/old/ExifGPSLocation.cpp [deleted file]
src/exif/old/ExifGPSLocation.h [deleted file]
src/exif/old/ExifGPSTime.cpp
src/exif/old/ExifGPSTime.h
src/exif/old/ExifInformation.cpp [deleted file]
src/exif/old/ExifInformation.h [deleted file]
src/exif/old/ExifTagSaver.cpp [deleted file]
src/exif/old/ExifTagSaver.h [deleted file]
src/exif/old/ExifUtil.cpp [deleted file]
src/exif/old/ExifUtil.h [deleted file]
src/exif/old/JpegFile.cpp [deleted file]
src/exif/old/JpegFile.h [deleted file]
src/exif/old/Rational.cpp [deleted file]
src/exif/old/Rational.h [deleted file]

diff --git a/src/exif/ExifGPSLocation.cpp b/src/exif/ExifGPSLocation.cpp
new file mode 100644 (file)
index 0000000..c534907
--- /dev/null
@@ -0,0 +1,302 @@
+//
+// Tizen Web Device API
+// Copyright (c) 2014 Samsung Electronics Co., Ltd.
+//
+// Licensed 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.
+//
+
+#include "ExifGPSLocation.h"
+
+#include <sstream>
+#include <math.h>
+
+#include "common/platform_exception.h"
+#include "common/logger.h"
+
+namespace extension {
+namespace exif {
+
+GCSPosition::GCSPosition()
+{
+}
+
+GCSPosition::GCSPosition(Rational _degrees, Rational _minutes, Rational _seconds) :
+    degrees(_degrees),
+    minutes(_minutes),
+    seconds(_seconds)
+{
+}
+
+bool GCSPosition::isValid() const
+{
+  if (!(degrees.isValid() && minutes.isValid() && seconds.isValid())) {
+    return false;
+  }
+
+  if ((degrees.toDouble() > 180.0f) ||
+      (minutes.toDouble() > 60.0f) ||
+      (seconds.toDouble() > 60.0f)) {
+    return false;
+  }
+
+  return toDouble() <= 180.0f;
+}
+
+double GCSPosition::toDouble() const
+{
+  const double degrees_value = degrees.toDouble();
+  const double minutes_value = minutes.toDouble();
+  const double seconds_value = seconds.toDouble();
+  return (degrees_value + (minutes_value/60.0) + (seconds_value/3600.0));
+}
+
+Rationals GCSPosition::toRationalsVector() const
+{
+  Rationals vec;
+  vec.push_back(degrees);
+  vec.push_back(minutes);
+  vec.push_back(seconds);
+  return vec;
+}
+
+std::string GCSPosition::toDebugString() const
+{
+  std::stringstream ss;
+  ss << degrees.toString() << "d ";
+  ss << minutes.toString() << "m ";
+  ss << seconds.toString() << "s";
+  return ss.str();
+}
+
+GCSPosition GCSPosition::createFromDouble(double value)
+{
+  LoggerD("Entered value:%f");
+  if (value < 0) {
+       LoggerW("Trying to create GCSPosition with double < 0: %f", value);
+    return GCSPosition();
+  }
+
+  if (value > 180.0) {
+       LoggerW("Trying to create GCSPosition with double > 180.0: %f", value);
+    return GCSPosition();
+  }
+
+  const double d_degrees = floor(value);
+  double left = value - d_degrees;
+
+  const double d_minutes = floor(left * 60.0);
+  left -= d_minutes / 60.0;
+
+  const double d_seconds = left * 3600.0;
+
+  LOGD("d_degrees:%f d_minutes:%f d_seconds:%f", d_degrees, d_minutes, d_seconds);
+
+  GCSPosition pos;
+  pos.degrees = Rational(static_cast<ExifLong>(d_degrees), 1);
+  pos.minutes = Rational(static_cast<ExifLong>(d_minutes), 1);
+  pos.seconds = Rational::createFromDouble(d_seconds);
+  return pos;
+}
+
+ExifGPSLocation::ExifGPSLocation() :
+    m_longitude_ref(GPS_LOCATION_WEST),
+    m_latitude_ref(GPS_LOCATION_NORTH)
+{
+  for(int i = 0; i < EXIF_GPS_LOCATION_ATTRIBUTE_NUMBER_OF_ATTRIBUTES; ++i) {
+    m_is_set[i] = false;
+  }
+  LoggerE("ExifGPSLocation::ExifGPSLocation()");
+}
+
+void ExifGPSLocation::setLongitude(const GCSPosition& longitude)
+{
+  if (!longitude.isValid()) {
+       LoggerW("longitude is not valid!");
+    return;
+  }
+
+  m_is_set[EXIF_GPS_LOCATION_ATTRIBUTE_LONGITUDE] = true;
+  m_longitude = longitude;
+}
+
+const GCSPosition& ExifGPSLocation::getLongitude() const
+{
+  return m_longitude;
+}
+
+void ExifGPSLocation::setLongitudeRef(GPSLocationDirectionLongitude ref)
+{
+  m_is_set[EXIF_GPS_LOCATION_ATTRIBUTE_LONGITUDE_REF] = true;
+  m_longitude_ref = ref;
+}
+
+GPSLocationDirectionLongitude ExifGPSLocation::getLongitudeRef() const
+{
+  return m_longitude_ref;
+}
+
+void ExifGPSLocation::setLatitude(const GCSPosition& latitude)
+{
+  if (!latitude.isValid()) {
+    LOGW("latitude is not valid!");
+    return;
+  }
+
+  m_is_set[EXIF_GPS_LOCATION_ATTRIBUTE_LATITUDE] = true;
+  m_latitude = latitude;
+}
+
+const GCSPosition& ExifGPSLocation::getLatitude() const
+{
+  return m_latitude;
+}
+
+void ExifGPSLocation::setLatitudeRef(GPSLocationDirectionLatitude ref)
+{
+  m_is_set[EXIF_GPS_LOCATION_ATTRIBUTE_LATITUDE_REF] = true;
+  m_latitude_ref = ref;
+}
+
+GPSLocationDirectionLatitude ExifGPSLocation::getLatitudeRef() const
+{
+  return m_latitude_ref;
+}
+
+bool ExifGPSLocation::isSet(ExifGPSLocationAttributes attribute) const
+{
+  return m_is_set[attribute];
+}
+
+void ExifGPSLocation::unset(ExifGPSLocationAttributes attribute)
+{
+  m_is_set[attribute] = false;
+}
+
+void ExifGPSLocation::unsetAll()
+{
+  m_is_set[EXIF_GPS_LOCATION_ATTRIBUTE_LONGITUDE] = false;
+  m_is_set[EXIF_GPS_LOCATION_ATTRIBUTE_LONGITUDE_REF] = false;
+  m_longitude =  GCSPosition();
+
+  m_is_set[EXIF_GPS_LOCATION_ATTRIBUTE_LATITUDE] = false;
+  m_is_set[EXIF_GPS_LOCATION_ATTRIBUTE_LATITUDE_REF] = false;
+  m_latitude = GCSPosition();
+}
+
+bool ExifGPSLocation::isComplete() const
+{
+  return m_is_set[EXIF_GPS_LOCATION_ATTRIBUTE_LONGITUDE] &&
+      m_is_set[EXIF_GPS_LOCATION_ATTRIBUTE_LONGITUDE_REF] &&
+      m_is_set[EXIF_GPS_LOCATION_ATTRIBUTE_LATITUDE] &&
+      m_is_set[EXIF_GPS_LOCATION_ATTRIBUTE_LATITUDE_REF];
+}
+
+
+bool ExifGPSLocation::isValid() const
+{
+  return isComplete() && m_latitude.isValid() && m_longitude.isValid();
+}
+/*
+Tizen::SimpleCoordinatesPtr ExifGPSLocation::getSimpleCoordinates() const
+{
+  if (!isComplete()) {
+    LoggerW("Some attributes are not set!");
+    return Tizen::SimpleCoordinatesPtr();
+  }
+
+  if (!isValid()) {
+    LoggerW("Some attributes are not valid!");
+    return Tizen::SimpleCoordinatesPtr();
+  }
+
+  const double cur_latitude = getLatitudeValue();
+  const double cur_longitude = getLongitudeValue();
+
+  return Tizen::SimpleCoordinatesPtr(
+    new Tizen::SimpleCoordinates(cur_latitude, cur_longitude));
+}*/
+
+double ExifGPSLocation::getLongitudeValue() const
+{
+  const double longitude_dir = (m_longitude_ref == GPS_LOCATION_WEST) ? -1.0f : 1.0f;
+  const double longitude = m_longitude.toDouble() * longitude_dir;
+  return longitude;
+}
+
+double ExifGPSLocation::getLatitudeValue() const
+{
+  const double latitude_dir = (m_latitude_ref == GPS_LOCATION_SOUTH) ? -1.0f : 1.0f;
+  const double latitude = m_latitude.toDouble() * latitude_dir;
+  return latitude;
+}
+/*
+bool ExifGPSLocation::set(Tizen::SimpleCoordinatesPtr scoords)
+{
+  LoggerD("Entered");
+  if (!scoords) {
+    LOGW("Trying to set null SimpleCoordinates!");
+    return false;
+  }
+
+  const double longitude = scoords->getLongitude();
+  const double latitude = scoords->getLatitude();
+  bool updateLongitude = true;
+  bool updateLatitude = true;
+
+  if(isComplete()) {
+    updateLatitude = getLatitudeValue() != latitude;
+    updateLongitude = getLongitudeValue() != longitude;
+  }
+
+  LoggerD("latitude:%f longitude:%f", latitude, longitude);
+
+  GCSPosition gcs_longitude = GCSPosition::createFromDouble(fabs(longitude));
+  LOGD("gcs_longitude deg:%s min:%s sec:%s", gcs_longitude.degrees.toString().c_str(),
+      gcs_longitude.minutes.toString().c_str(),
+      gcs_longitude.seconds.toString().c_str());
+
+  GCSPosition gcs_latitude = GCSPosition::createFromDouble(fabs(latitude));
+  LoggerD("gcs_latitude deg:%s min:%s sec:%s", gcs_latitude.degrees.toString().c_str(),
+      gcs_latitude.minutes.toString().c_str(),
+      gcs_latitude.seconds.toString().c_str());
+
+  if (!gcs_latitude.isValid() || !gcs_longitude.isValid()) {
+    return false;
+  }
+
+  if(updateLongitude) {
+    setLongitude(gcs_longitude);
+    if (longitude >= 0.0) {
+      setLongitudeRef(GPS_LOCATION_EAST);
+    }
+    else {
+      setLongitudeRef(GPS_LOCATION_WEST);
+    }
+  }
+
+  if(updateLatitude) {
+    setLatitude(gcs_latitude);
+    if (latitude >= 0.0) {
+      setLatitudeRef(GPS_LOCATION_NORTH);
+    }
+    else {
+      setLatitudeRef(GPS_LOCATION_SOUTH);
+    }
+  }
+
+  return true;
+}
+*/
+
+} // exif
+} // extension
diff --git a/src/exif/ExifGPSLocation.h b/src/exif/ExifGPSLocation.h
new file mode 100644 (file)
index 0000000..4c5103c
--- /dev/null
@@ -0,0 +1,149 @@
+//
+// Tizen Web Device API
+// Copyright (c) 2014 Samsung Electronics Co., Ltd.
+//
+// Licensed 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.
+//
+
+#ifndef __TIZEN_EXIF_EXIF_GPS_LOCATION_H_
+#define __TIZEN_EXIF_EXIF_GPS_LOCATION_H_
+
+#include <string>
+#include <vector>
+
+//#include <SimpleCoordinates.h>
+
+#include "ExifUtil.h"
+#include "Rational.h"
+
+namespace extension {
+namespace exif {
+
+enum GPSLocationDirectionLongitude {
+  GPS_LOCATION_WEST,
+  GPS_LOCATION_EAST
+};
+
+enum GPSLocationDirectionLatitude {
+  GPS_LOCATION_NORTH,
+  GPS_LOCATION_SOUTH
+};
+
+enum ExifGPSLocationAttributes {
+  EXIF_GPS_LOCATION_ATTRIBUTE_LONGITUDE = 0,
+  EXIF_GPS_LOCATION_ATTRIBUTE_LONGITUDE_REF,
+  EXIF_GPS_LOCATION_ATTRIBUTE_LATITUDE,
+  EXIF_GPS_LOCATION_ATTRIBUTE_LATITUDE_REF,
+  EXIF_GPS_LOCATION_ATTRIBUTE_NUMBER_OF_ATTRIBUTES
+};
+
+/**
+ * This class represents Global Coordinate System using
+ * three Rational numbers (as stored in Exif)
+ */
+struct GCSPosition
+{
+  GCSPosition();
+  GCSPosition(Rational degrees, Rational minutes, Rational seconds);
+
+  /**
+   * Create GCSPosition from degrees represented as double value
+   */
+  static GCSPosition createFromDouble(double value);
+
+  /**
+   * Verify that all components are valid Rational numbers and
+   * each component is within valid range. Sum of degrees,
+   * minutes and seconds should not be bigger then 180.0
+   */
+  bool isValid() const;
+
+  /**
+   * Return position in degrees
+   */
+  double toDouble() const;
+
+  /**
+   * Return vector of three rationals: degrees, minutes, seconds
+   */
+  Rationals toRationalsVector() const;
+
+  /**
+   * Return string for debugging purposes
+   */
+  std::string toDebugString() const;
+
+  Rational degrees;
+  Rational minutes;
+  Rational seconds;
+};
+
+class ExifGPSLocation
+{
+public:
+  ExifGPSLocation();
+
+  void setLongitude(const GCSPosition& longitude);
+  const GCSPosition& getLongitude() const;
+
+  void setLongitudeRef(GPSLocationDirectionLongitude ref);
+  GPSLocationDirectionLongitude getLongitudeRef() const;
+
+  void setLatitude(const GCSPosition& latitude);
+  const GCSPosition& getLatitude() const;
+
+  void setLatitudeRef(GPSLocationDirectionLatitude ref);
+  GPSLocationDirectionLatitude getLatitudeRef() const;
+
+  bool isSet(ExifGPSLocationAttributes attribute) const;
+  void unset(ExifGPSLocationAttributes attribute);
+  void unsetAll();
+
+  /**
+   * Returns true only if all components are set.
+   */
+  bool isComplete() const;
+
+  /**
+   * Returns true only if all components are set and valid.
+   */
+  bool isValid() const;
+
+  /**
+   * Returns null pointer if any information is missing or incorrect
+   */
+  //Tizen::SimpleCoordinatesPtr getSimpleCoordinates() const;
+
+  /**
+   * Return true if scoords has been set
+   */
+  //bool set(Tizen::SimpleCoordinatesPtr scoords);
+
+private:
+
+  double getLongitudeValue() const;
+  double getLatitudeValue() const;
+
+  GCSPosition m_longitude;
+  GPSLocationDirectionLongitude m_longitude_ref;
+
+  GCSPosition m_latitude;
+  GPSLocationDirectionLatitude m_latitude_ref;
+
+  bool m_is_set[EXIF_GPS_LOCATION_ATTRIBUTE_NUMBER_OF_ATTRIBUTES];
+};
+
+} // exif
+} // extension
+
+#endif // __TIZEN_EXIF_EXIF_GPS_LOCATION_H_
diff --git a/src/exif/ExifInformation.cpp b/src/exif/ExifInformation.cpp
new file mode 100644 (file)
index 0000000..a5223e6
--- /dev/null
@@ -0,0 +1,1340 @@
+//
+// Tizen Web Device API
+// Copyright (c) 2014 Samsung Electronics Co., Ltd.
+//
+// Licensed 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.
+//
+
+#include "ExifInformation.h"
+
+#include <memory>
+#include <math.h>
+
+#include "ExifTagSaver.h"
+#include "ExifUtil.h"
+#include "JpegFile.h"
+
+#include "common/platform_exception.h"
+#include "common/logger.h"
+
+namespace extension {
+namespace exif {
+
+const size_t EXIF_UNDEFINED_TYPE_LENGTH = 8;
+const std::string EXIF_UNDEFINED_TYPE_ASCII =
+    std::string("ASCII\0\0\0", EXIF_UNDEFINED_TYPE_LENGTH);
+const std::string EXIF_UNDEFINED_TYPE_JIS =
+    std::string("JIS\0\0\0\0\0", EXIF_UNDEFINED_TYPE_LENGTH);
+const std::string EXIF_UNDEFINED_TYPE_UNICODE =
+    std::string("UNICODE\0", EXIF_UNDEFINED_TYPE_LENGTH);
+const std::string EXIF_UNDEFINED_TYPE_UNDEFINED =
+    std::string("\0\0\0\0\0\0\0\0", EXIF_UNDEFINED_TYPE_LENGTH);
+
+ExifInformation::ExifInformation()
+{
+  for (int attr = 0; attr < EXIF_INFORMATION_ATTRIBUTE_NUMBER_OF_ATTRIBUTES; attr++) {
+    unset(static_cast<ExifInformationAttribute>(attr));
+  }
+}
+
+ExifInformation::~ExifInformation() { }
+
+const std::string& ExifInformation::getUri()
+{
+  LoggerD("Entered");
+  return m_uri;
+}
+
+void ExifInformation::setUri(const std::string& uri)
+{
+  LoggerD("Entered");
+  m_is_set[EXIF_INFORMATION_ATTRIBUTE_URI] = true;
+  m_uri = uri;
+}
+
+unsigned long ExifInformation::getWidth() const
+{
+  LoggerD("Entered");
+  return m_width;
+}
+
+void ExifInformation::setWidth(unsigned long width)
+{
+  LoggerD("Entered");
+  m_is_set[EXIF_INFORMATION_ATTRIBUTE_WIDTH] = true;
+  m_width = width;
+}
+
+unsigned long ExifInformation::getHeight() const
+{
+  LoggerD("Entered");
+  return m_height;
+}
+
+void ExifInformation::setHeight(unsigned long height)
+{
+  LoggerD("Entered");
+  m_is_set[EXIF_INFORMATION_ATTRIBUTE_HEIGHT] = true;
+  m_height = height;
+}
+
+const std::string& ExifInformation::getDeviceMaker()
+{
+  LoggerD("Entered");
+  return m_device_maker;
+}
+
+void ExifInformation::setDeviceMaker(const std::string& device_maker)
+{
+  LoggerD("Entered");
+  m_is_set[EXIF_INFORMATION_ATTRIBUTE_DEVICE_MAKER] = true;
+  m_device_maker = device_maker;
+}
+
+const std::string& ExifInformation::getDeviceModel()
+{
+  LoggerD("Entered");
+  return m_device_model;
+}
+
+void ExifInformation::setDeviceModel(const std::string& device_model)
+{
+  LoggerD("Entered");
+  m_is_set[EXIF_INFORMATION_ATTRIBUTE_DEVICE_MODEL] = true;
+  m_device_model = device_model;
+}
+
+time_t ExifInformation::getOriginalTime() const
+{
+  LoggerD("Entered");
+  return m_original_time;
+}
+
+void ExifInformation::setOriginalTime(time_t original_time)
+{
+  LoggerD("Entered");
+  m_is_set[EXIF_INFORMATION_ATTRIBUTE_ORIGINAL_TIME] = true;
+  m_original_time = original_time;
+}
+
+ImageOrientation ExifInformation::getOrientation() const
+{
+  LoggerD("Entered");
+  return m_orientation;
+}
+
+void ExifInformation::setOrientation(ImageOrientation orientation)
+{
+  LoggerD("Entered");
+  if(EXIF_ORIENTATION_NOT_VALID == orientation) {
+    LOGW("Trying to set NOT VALID orientation");
+    return;
+  }
+
+  m_is_set[EXIF_INFORMATION_ATTRIBUTE_ORIENTATION] = true;
+  m_orientation = orientation;
+}
+
+const Rational& ExifInformation::getFNumber() const
+{
+  LoggerD("Entered");
+  return m_f_number;
+}
+
+void ExifInformation::setFNumber(Rational f_number)
+{
+  LoggerD("Entered");
+  if (!f_number.isValid()) {
+    LoggerW("Trying to set invalid F-Number: %s", f_number.toString().c_str());
+    return;
+  }
+
+  m_is_set[EXIF_INFORMATION_ATTRIBUTE_FNUMBER] = true;
+  m_f_number = f_number;
+}
+/*
+Common::JSLongLongVector ExifInformation::getIsoSpeedRatings()
+{
+  LoggerD("Entered");
+  return m_iso_speed_ratings;
+}*/
+/*
+void ExifInformation::setIsoSpeedRatings(
+    const std::vector<long long int>& iso_speed_ratings)
+{
+  LoggerD("Entered");
+  m_is_set[EXIF_INFORMATION_ATTRIBUTE_ISO_SPEED_RATINGS] = true;
+  m_iso_speed_ratings = iso_speed_ratings;
+}*/
+
+void ExifInformation::appendIsoSpeedRatings(long long int iso_speed_rating)
+{
+  m_is_set[EXIF_INFORMATION_ATTRIBUTE_ISO_SPEED_RATINGS] = true;
+  //m_iso_speed_ratings.push_back(iso_speed_rating);
+}
+
+const Rational& ExifInformation::getExposureTime()
+{
+  LoggerD("Entered");
+  return m_exposure_time;
+}
+
+void ExifInformation::setExposureTime(const Rational& exposure_time)
+{
+  LoggerD("Entered");
+  if (!exposure_time.isValid() || 0 == exposure_time.nominator) {
+    LoggerW("Trying to set invalid exposure time: [%s]",
+        exposure_time.toString().c_str());
+    return;
+  }
+
+  m_is_set[EXIF_INFORMATION_ATTRIBUTE_EXPOSURE_TIME] = true;
+  m_exposure_time = exposure_time;
+}
+
+ExposureProgram ExifInformation::getExposureProgram()
+{
+  LoggerD("Entered");
+  return m_exposure_program;
+}
+
+void ExifInformation::setExposureProgram(ExposureProgram exposure_program)
+{
+  LoggerD("Entered");
+  if (EXIF_EXPOSURE_PROGRAM_NOT_VALID == exposure_program) {
+    LOGW("Trying to set NOT VALID exposure program");
+    return;
+  }
+
+  m_is_set[EXIF_INFORMATION_ATTRIBUTE_EXPOSURE_PROGRAM] = true;
+  m_exposure_program = exposure_program;
+}
+
+bool ExifInformation::getFlash() const
+{
+  LoggerD("Entered");
+  return m_flash;
+}
+
+void ExifInformation::setFlash(bool flash)
+{
+  LoggerD("Entered");
+  m_is_set[EXIF_INFORMATION_ATTRIBUTE_FLASH] = true;
+  m_flash = flash;
+}
+
+const Rational& ExifInformation::getFocalLength() const
+{
+  LoggerD("Entered");
+  return m_focal_length;
+}
+
+void ExifInformation::setFocalLength(Rational focal_length)
+{
+  LoggerD("Entered");
+  if(!focal_length.isValid()) {
+    LoggerW("Trying to set invalid focal length: %s", focal_length.toString().c_str());
+    return;
+  }
+
+  m_is_set[EXIF_INFORMATION_ATTRIBUTE_FOCAL_LENGTH] = true;
+  m_focal_length = focal_length;
+}
+
+WhiteBalanceMode ExifInformation::getWhiteBalanceMode() const
+{
+  LoggerD("Entered");
+  return m_white_balance;
+}
+
+void ExifInformation::setWhiteBalanceMode(WhiteBalanceMode white_balance)
+{
+  LoggerD("Entered");
+  if (EXIF_WHITE_BALANCE_MODE_NOT_VALID == white_balance) {
+    LOGW("Trying to set NOT VALID white balance mode");
+    return;
+  }
+
+  m_is_set[EXIF_INFORMATION_ATTRIBUTE_WHITE_BALANCE] = true;
+  m_white_balance = white_balance;
+}
+
+ExifGPSLocation& ExifInformation::getGPSExifLocation()
+{
+  return m_exif_gps_location;
+}
+/*
+Tizen::SimpleCoordinatesPtr ExifInformation::getGPSLocation()
+{
+  if(m_gps_location) {
+    return m_gps_location;
+  }
+
+
+  Tizen::SimpleCoordinatesPtr nscoords = m_exif_gps_location.getSimpleCoordinates();
+  if(!nscoords) {
+    return nscoords;
+  }
+
+  m_gps_location = nscoords;
+  return m_gps_location;
+}*/
+/*
+void ExifInformation::setGPSLocation(Tizen::SimpleCoordinatesPtr gps_location)
+{
+  if(!gps_location) {
+    LoggerW("Trying to set NULL gps location!");
+    return;
+  }
+
+  m_gps_location = gps_location;
+}*/
+
+void ExifInformation::unsetGPSLocation()
+{
+  //m_gps_location = Tizen::SimpleCoordinatesPtr();
+  m_exif_gps_location.unsetAll();
+}
+
+const Rational& ExifInformation::getGpsAltitude() const
+{
+  LoggerD("Entered");
+  return m_gps_altitude;
+}
+
+void ExifInformation::setGpsAltitude(Rational gps_altitude)
+{
+  LoggerD("Entered");
+  if (!gps_altitude.isValid()) {
+    LoggerW("Trying to set invalid gps altitude: %s", gps_altitude.toString().c_str());
+    return;
+  }
+
+  m_is_set[EXIF_INFORMATION_ATTRIBUTE_GPS_ALTITUDE] = true;
+  m_gps_altitude = gps_altitude;
+}
+
+GpsAltitudeRef ExifInformation::getGpsAltitudeRef() const
+{
+  LoggerD("Entered");
+  return m_gps_altitude_ref;
+}
+
+void ExifInformation::setGpsAltitudeRef(const GpsAltitudeRef ref)
+{
+  LoggerD("Entered");
+  m_is_set[EXIF_INFORMATION_ATTRIBUTE_GPS_ALTITUDE_REF] = true;
+  m_gps_altitude_ref = ref;
+}
+
+void ExifInformation::setGpsAltitudeWithRef(double gps_altitude)
+{
+  LoggerD("Entered");
+  setGpsAltitude(Rational::createFromDouble(fabs(gps_altitude)));
+
+  if(gps_altitude >= 0.0) {
+    setGpsAltitudeRef(GPS_ALTITUDE_REF_ABOVE_SEA);
+  } else {
+    setGpsAltitudeRef(GPS_ALTITUDE_REF_BELOW_SEA);
+  }
+
+}
+
+double ExifInformation::getGpsAltitudeWithRef() const
+{
+  LoggerD("Entered");
+
+  if (!m_is_set[EXIF_INFORMATION_ATTRIBUTE_GPS_ALTITUDE_REF] ||
+      GPS_ALTITUDE_REF_ABOVE_SEA == m_gps_altitude_ref) {
+    return m_gps_altitude.toDouble();
+  } else {
+    return -1.0 * m_gps_altitude.toDouble();
+  }
+}
+
+const std::string& ExifInformation::getGpsProcessingMethod() const
+{
+  LoggerD("Entered");
+  return m_gps_processing_method;
+}
+
+const std::string& ExifInformation::getGpsProcessingMethodType() const
+{
+  LoggerD("Entered");
+  return m_gps_processing_method_type;
+}
+
+void ExifInformation::setGpsProcessingMethod(const std::string& type,
+    const std::string& processing_method)
+{
+  LoggerD("Entered");
+  if (type != EXIF_UNDEFINED_TYPE_ASCII &&
+      type != EXIF_UNDEFINED_TYPE_JIS &&
+      type != EXIF_UNDEFINED_TYPE_UNICODE &&
+      type != EXIF_UNDEFINED_TYPE_UNDEFINED) {
+    LoggerW("Trying to set invalid GPSProcessingMethod type: [%s] len:%d",
+        type.c_str(), type.length());
+    return;
+  }
+
+  m_is_set[EXIF_INFORMATION_ATTRIBUTE_GPS_PROCESSING_METHOD] = true;
+  m_gps_processing_method = processing_method;
+  m_gps_processing_method_type = type;
+}
+/*
+ExifGPSTime& ExifInformation::getExifGpsTime()
+{
+  return m_exif_gps_time;
+}*/
+/*
+const ExifGPSTime& ExifInformation::getExifGpsTime() const
+{
+  return m_exif_gps_time;
+}*/
+
+/*
+Time::TZDatePtr ExifInformation::getGpsTime()
+{
+  if(m_gps_time) {
+    return m_gps_time;
+  }
+
+  if(!m_exif_gps_time.isValid()) {
+    return Time::TZDatePtr();
+  }
+
+
+  m_gps_time = m_exif_gps_time.getTZDate();
+  return m_gps_time;
+}*/
+/*
+void ExifInformation::setGpsTime(Time::TZDatePtr new_time)
+{
+  if(!new_time) {
+    LoggerW("Trying to set null new_time!");
+    return;
+  }
+
+  m_gps_time = new_time;
+}*/
+
+void ExifInformation::unsetGPStime()
+{
+  //m_exif_gps_time.unsetAll();
+  //m_gps_time = NULL;
+}
+
+
+const std::string& ExifInformation::getUserComment()
+{
+  LoggerD("Entered");
+  return m_user_comment;
+}
+
+const std::string& ExifInformation::getUserCommentType()
+{
+  LoggerD("Entered");
+  return m_user_comment_type;
+}
+
+void ExifInformation::setUserComment(const std::string& type,
+    const std::string& user_comment)
+{
+  LoggerD("Entered");
+  if (type != EXIF_UNDEFINED_TYPE_ASCII &&
+      type != EXIF_UNDEFINED_TYPE_JIS &&
+      type != EXIF_UNDEFINED_TYPE_UNICODE &&
+      type != EXIF_UNDEFINED_TYPE_UNDEFINED) {
+       LoggerW("Trying to set invalid user comment type: [%s] len:%d",
+        type.c_str(), type.length());
+    return;
+  }
+
+  m_is_set[EXIF_INFORMATION_ATTRIBUTE_USER_COMMENT] = true;
+  m_user_comment_type = type;
+  m_user_comment = user_comment;
+}
+
+bool ExifInformation::isSet(ExifInformationAttribute attribute) const
+{
+  LoggerD("Entered");
+  return m_is_set[attribute];
+}
+
+void ExifInformation::unset(ExifInformationAttribute attribute)
+{
+  LoggerD("Entered");
+  if (attribute >= EXIF_INFORMATION_ATTRIBUTE_NUMBER_OF_ATTRIBUTES) {
+    return;
+  }
+
+  m_is_set[attribute] = false;
+  switch (attribute) {
+    case EXIF_INFORMATION_ATTRIBUTE_URI:
+      m_uri = std::string();
+      break;
+    case EXIF_INFORMATION_ATTRIBUTE_WIDTH:
+      m_width = 0;
+      break;
+    case EXIF_INFORMATION_ATTRIBUTE_HEIGHT:
+      m_height = 0;
+      break;
+    case EXIF_INFORMATION_ATTRIBUTE_DEVICE_MAKER:
+      m_device_maker = std::string();
+      break;
+    case EXIF_INFORMATION_ATTRIBUTE_DEVICE_MODEL:
+      m_device_model = std::string();
+      break;
+    case EXIF_INFORMATION_ATTRIBUTE_ORIGINAL_TIME:
+      m_original_time = 0;
+      break;
+    case EXIF_INFORMATION_ATTRIBUTE_ORIENTATION:
+      m_orientation = EXIF_ORIENTATION_NOT_VALID;
+      break;
+    case EXIF_INFORMATION_ATTRIBUTE_FNUMBER:
+      m_f_number = Rational::createInvalid();
+      break;
+    case EXIF_INFORMATION_ATTRIBUTE_ISO_SPEED_RATINGS:
+      //m_iso_speed_ratings = std::vector<long long int>();
+      break;
+    case EXIF_INFORMATION_ATTRIBUTE_EXPOSURE_TIME:
+      m_exposure_time = Rational::createInvalid();
+      break;
+    case EXIF_INFORMATION_ATTRIBUTE_EXPOSURE_PROGRAM:
+      m_exposure_program = EXIF_EXPOSURE_PROGRAM_NOT_VALID;
+      break;
+    case EXIF_INFORMATION_ATTRIBUTE_FLASH:
+      m_flash = false;
+      break;
+    case EXIF_INFORMATION_ATTRIBUTE_FOCAL_LENGTH:
+      m_focal_length = Rational::createInvalid();
+      break;
+    case EXIF_INFORMATION_ATTRIBUTE_WHITE_BALANCE:
+      m_white_balance = EXIF_WHITE_BALANCE_MODE_NOT_VALID;
+      break;
+    case EXIF_INFORMATION_ATTRIBUTE_GPS_ALTITUDE:
+      m_gps_altitude = Rational::createInvalid();
+      break;
+    case EXIF_INFORMATION_ATTRIBUTE_GPS_ALTITUDE_REF:
+      m_gps_altitude_ref = GPS_ALTITUDE_REF_ABOVE_SEA;
+      break;
+    case EXIF_INFORMATION_ATTRIBUTE_GPS_PROCESSING_METHOD:
+      m_gps_processing_method = std::string();
+      m_gps_processing_method_type = EXIF_UNDEFINED_TYPE_ASCII;
+      break;
+    case EXIF_INFORMATION_ATTRIBUTE_USER_COMMENT:
+      m_user_comment = std::string();
+      m_user_comment_type = EXIF_UNDEFINED_TYPE_ASCII;
+      break;
+    default:
+      break;
+  }
+}
+
+bool getGCSPositionFromEntry(ExifEntry *entry, ExifData* exif_data, GCSPosition& out_pos)
+{
+  //RATIONAL - 3
+  if (EXIF_FORMAT_RATIONAL == entry->format &&
+      entry->components >= 3 &&
+      entry->data) {
+    const ExifByteOrder order = exif_data_get_byte_order(exif_data);
+    out_pos.degrees = Rational(exif_get_rational(entry->data, order));
+    out_pos.minutes = Rational(exif_get_rational(
+        entry->data +   ExifTypeInfo::RationalSize, order));
+    out_pos.seconds = Rational(exif_get_rational(
+        entry->data + 2*ExifTypeInfo::RationalSize, order));
+    return true;
+  }
+  else {
+    return false;
+  }
+}
+
+bool getRationalsFromEntry(ExifEntry *entry, ExifData* exif_data,
+      unsigned long required_count, Rationals& out_rationals)
+{
+  if (EXIF_FORMAT_RATIONAL == entry->format &&
+      entry->components >= required_count &&
+      entry->data) {
+    const ExifByteOrder order = exif_data_get_byte_order(exif_data);
+    unsigned char* ptr = entry->data;
+
+    for(unsigned long i = 0; i < required_count; ++i) {
+      out_rationals.push_back(Rational(exif_get_rational(ptr, order)));
+      ptr += ExifTypeInfo::RationalSize;
+    }
+
+    return true;
+  }
+  else {
+    return false;
+  }
+}
+
+Rational getRationalFromEntry(ExifEntry *entry, ExifData* exif_data)
+{
+  if (EXIF_FORMAT_RATIONAL == entry->format && entry->components >= 1 && entry->data) {
+    const ExifByteOrder order = exif_data_get_byte_order(exif_data);
+    return Rational(exif_get_rational(entry->data, order));
+  }
+  else {
+    return Rational::createInvalid();
+  }
+}
+
+bool decomposeExifUndefined(ExifEntry* entry, std::string& type, std::string& value)
+{
+  if(!entry || !entry->data) {
+    LoggerW("exif entry is NULL/empty");
+    return false;
+  }
+
+  if(entry->size < EXIF_UNDEFINED_TYPE_LENGTH) {
+    LoggerW("entry size is invalid %d < EXIF_UNDEFINED_TYPE_LENGTH", entry->size);
+    return false;
+  }
+
+  const char* ptr = reinterpret_cast<const char*>(entry->data);
+  type = std::string(ptr, EXIF_UNDEFINED_TYPE_LENGTH);
+  ptr += EXIF_UNDEFINED_TYPE_LENGTH;
+  value = std::string(ptr, entry->size - EXIF_UNDEFINED_TYPE_LENGTH);
+  return true;
+}
+
+void ExifInformation::processEntry(ExifEntry* entry, ExifData* exif_data)
+{
+  char buf[2000];
+  exif_entry_get_value(entry, buf, sizeof(buf));
+  ExifUtil::printExifEntryInfo(entry, exif_data);
+
+  const ExifIfd cur_ifd = exif_entry_get_ifd(entry);
+  if (EXIF_IFD_INTEROPERABILITY == cur_ifd || EXIF_IFD_1 == cur_ifd) {
+    return;
+  }
+
+  switch (static_cast<unsigned int>(entry->tag)) {
+    case EXIF_TAG_IMAGE_WIDTH: {
+      //SHORT or LONG - 1
+      exif_entry_get_value(entry, buf, sizeof(buf));
+      LoggerD( "Setting ExifInformation width to: [%s]", buf );
+      setWidth(atol(buf));
+      break;
+    }
+    case EXIF_TAG_IMAGE_LENGTH: {
+      //SHORT or LONG - 1
+      exif_entry_get_value(entry, buf, sizeof(buf));
+      LoggerD( "Setting ExifInformation height to: [%s]", buf );
+      setHeight(atol(buf));
+      break;
+    }
+    case EXIF_TAG_MAKE: {
+      //ASCII - Any
+      exif_entry_get_value(entry, buf, sizeof(buf));
+      LoggerD( "Setting ExifInformation maker to: [%s]", buf );
+      setDeviceMaker(std::string(buf));
+      break;
+    }
+    case EXIF_TAG_MODEL: {
+      //ASCII - Any
+      exif_entry_get_value(entry, buf, sizeof(buf));
+      LoggerD( "Setting ExifInformation model to: [%s]", buf );
+      setDeviceModel(std::string(buf));
+      break;
+    }
+    case EXIF_TAG_DATE_TIME_ORIGINAL: {
+      //ASCII - 20
+      exif_entry_get_value(entry, buf, sizeof(buf));
+      const time_t time = ExifUtil::exifDateTimeOriginalToTimeT(
+          reinterpret_cast<const char*>(entry->data));
+      LoggerD( "Setting ExifInformation time original to: [%s] time_t:%d", buf,
+          (int)time);
+      setOriginalTime(time);
+    }
+    case EXIF_TAG_ORIENTATION: {
+      //SHORT - 1
+      exif_entry_get_value(entry, buf, sizeof(buf));
+      const ExifByteOrder order = exif_data_get_byte_order(exif_data);
+      const ExifShort orient(exif_get_short(entry->data, order));
+
+      if(orient < EXIF_ORIENTATION_NORMAL || orient >= EXIF_ORIENTATION_NOT_VALID) {
+        LoggerW("Couldn't set ExifInformation - orientation is not valid: %d (%s)",
+            orient, buf);
+      }
+      else {
+        LoggerD("Setting ExifInformation orientation to: %d [%s]", orient, buf);
+        setOrientation(static_cast<ImageOrientation>(orient));
+      }
+      break;
+    }
+    case EXIF_TAG_FNUMBER:
+    {
+      //RATIONAL - 1
+      Rational fnumber = getRationalFromEntry(entry, exif_data);
+      if(fnumber.isValid()) {
+        LOGD("Setting ExifInformation fnumber to: %f (%s)", fnumber.toDouble(),
+          fnumber.toString().c_str());
+        setFNumber(fnumber);
+      }
+      else {
+        LOGW("Couldn't set ExifInformation - fnumber is not valid: %s",
+            fnumber.toString().c_str());
+      }
+      break;
+    }
+    case EXIF_TAG_ISO_SPEED_RATINGS: {
+      //SHORT - Any
+      if (EXIF_FORMAT_SHORT == entry->format &&
+          entry->components > 0 &&
+          entry->data) {
+        const ExifByteOrder order = exif_data_get_byte_order(exif_data);
+        unsigned char* read_ptr = entry->data;
+        const size_t size_per_member =
+            ExifUtil::getSizeOfExifFormatType(entry->format);
+
+        for(unsigned long i = 0; i < entry->components; ++i) {
+          ExifShort iso_rating = exif_get_short(read_ptr, order);
+          appendIsoSpeedRatings(iso_rating);
+
+          LoggerD("Appending ExifInformation speed ratings with: %d",
+              static_cast<int>(iso_rating));
+
+          read_ptr += size_per_member;
+        }
+      }
+      else {
+        LoggerE("iso speed ratings: format or components count is invalid!");
+      }
+      break;
+    }
+    case EXIF_TAG_EXPOSURE_TIME: {
+      //RATIONAL - 1
+      if (EXIF_FORMAT_RATIONAL == entry->format &&
+          entry->components > 0 &&
+          entry->data) {
+
+        const ExifByteOrder order = exif_data_get_byte_order(exif_data);
+        const Rational exp_time(exif_get_rational(entry->data, order));
+
+        if (exp_time.isValid()) {
+          LoggerD("Setting ExifInformation exposure time to: %s (%s)",
+              exp_time.toString().c_str(),
+              exp_time.toExposureTimeString().c_str());
+          setExposureTime(exp_time);
+        }
+        else {
+          LoggerD("Couldn't set ExifInformation - exposure time is not valid: %s",
+              exp_time.toString().c_str());
+        }
+      }
+      else {
+        LoggerE("exposure time: format or components count is invalid!");
+      }
+      break;
+    }
+    case EXIF_TAG_EXPOSURE_PROGRAM: {
+      //SHORT - 1
+      exif_entry_get_value(entry, buf, sizeof(buf));
+
+      const ExifByteOrder order = exif_data_get_byte_order(exif_data);
+      const ExifShort exp_program = exif_get_short(entry->data, order);
+      if(exp_program >= EXIF_EXPOSURE_PROGRAM_NOT_VALID) {
+        LoggerW("ExposureProgram: %d (%s) is not valid!", exp_program, buf);
+      }
+      else {
+        LoggerD("Setting ExifInformation exposure program to: %d [%s]",
+            exp_program, buf );
+        setExposureProgram(static_cast<ExposureProgram>(exp_program));
+      }
+      break;
+    }
+    case EXIF_TAG_FLASH: {
+      //SHORT - 1
+      exif_entry_get_value(entry, buf, sizeof(buf));
+
+      const ExifByteOrder order = exif_data_get_byte_order(exif_data);
+      const ExifShort flash = exif_get_short(entry->data, order);
+
+      LoggerD( "Setting ExifInformation flash to: [%s] flash=%d", buf, flash);
+      setFlash(flash != 0);
+      break;
+    }
+    case EXIF_TAG_FOCAL_LENGTH: {
+      //RATIONAL - 1
+      Rational flength = getRationalFromEntry(entry, exif_data);
+      if(flength.isValid()) {
+        LoggerD("Setting ExifInformation focal length to: %f (%s)",
+            flength.toDouble(), flength.toString().c_str());
+        setFocalLength(flength);
+      }
+      else {
+        LoggerW("Couldn't set ExifInformation - focal length is not valid: %s",
+            flength.toString().c_str());
+      }
+      break;
+    }
+    case EXIF_TAG_WHITE_BALANCE: {
+      //SHORT - 1
+      exif_entry_get_value(entry, buf, sizeof(buf));
+      LoggerD( "Setting ExifInformation white balance to: [%s]", buf );
+      if (entry->data[0]) {
+        setWhiteBalanceMode(EXIF_WHITE_BALANCE_MODE_MANUAL);
+      }
+      else {
+        setWhiteBalanceMode(EXIF_WHITE_BALANCE_MODE_AUTO);
+      }
+      break;
+    }
+    case EXIF_TAG_GPS_LONGITUDE: {
+      //RATIONAL - 3
+      GCSPosition longitude;
+      if (getGCSPositionFromEntry(entry, exif_data, longitude)) {
+        m_exif_gps_location.setLongitude(longitude);
+        LoggerD("Setting ExifInformation gps longitude to: %s; %s; %s valid:%d",
+            longitude.degrees.toString().c_str(),
+            longitude.minutes.toString().c_str(),
+            longitude.seconds.toString().c_str(),
+            longitude.isValid());
+      }
+      else {
+        exif_entry_get_value(entry, buf, sizeof(buf));
+        LoggerW("Couldn't set longitude pos - data is not valid: [%s]", buf);
+      }
+      break;
+    }
+    case EXIF_TAG_GPS_LONGITUDE_REF: {
+      //ASCII - 2
+      if(entry->size < 1) {
+        LoggerW("Longtitude ref entry do not contain enought data!");
+        break;
+      }
+
+      const char ref = static_cast<char>(entry->data[0]);
+      if ('E' == ref || 'e' == ref) {      //East
+        m_exif_gps_location.setLongitudeRef(GPS_LOCATION_EAST);
+        LoggerD("Setting ExifInformation gps longitude REF to: EAST");
+      }
+      else if ('W' == ref || 'w' == ref) {   //West
+        m_exif_gps_location.setLongitudeRef(GPS_LOCATION_WEST);
+        LoggerD("Setting ExifInformation gps longitude REF to: WEST");
+      }
+      else {
+        LoggerW("Unknown longitude ref: %c (0x%x)", ref, static_cast<int>(ref));
+      }
+      break;
+    }
+    case EXIF_TAG_GPS_LATITUDE: {
+      //RATIONAL - 3
+      exif_entry_get_value(entry, buf, sizeof(buf));
+      LoggerD( "Setting ExifInformation latitude to: [%s], tag->%s",
+          buf, exif_tag_get_name(entry->tag) );
+
+      GCSPosition latitude;
+      if (getGCSPositionFromEntry(entry, exif_data, latitude)) {
+        m_exif_gps_location.setLatitude(latitude);
+        LoggerD("Setting ExifInformation gps latitude to: %s; %s; %s valid:%d",
+            latitude.degrees.toString().c_str(),
+            latitude.minutes.toString().c_str(),
+            latitude.seconds.toString().c_str(),
+            latitude.isValid());
+      }
+      else {
+        LoggerW("Couldn't set latitude pos - data is not valid!");
+      }
+      break;
+    }
+    case EXIF_TAG_GPS_LATITUDE_REF: {
+      //ASCII - 2
+      if(entry->size < 1) {
+        LoggerW("Latitude ref entry do not contain enought data!");
+        break;
+      }
+
+      const char ref = static_cast<char>(entry->data[0]);
+      if ('N' == ref || 'n' == ref) {      //North
+        m_exif_gps_location.setLatitudeRef(GPS_LOCATION_NORTH);
+        LoggerD("Setting ExifInformation gps latitude REF to: NORTH");
+      }
+      else if ('S' == ref || 's' == ref) {   //South
+        m_exif_gps_location.setLatitudeRef(GPS_LOCATION_SOUTH);
+        LoggerD("Setting ExifInformation gps latitude REF to: SOUTH");
+      }
+      else {
+        LoggerW("Unknown latitude ref: %c (0x%x)", ref, static_cast<int>(ref));
+      }
+      break;
+    }
+    case EXIF_TAG_GPS_ALTITUDE: {
+      //RATIONAL - 1
+      Rational gps_altitude = getRationalFromEntry(entry, exif_data);
+      if(gps_altitude.isValid()) {
+        LoggerD("Setting ExifInformation gps altitude to: %f (%s)",
+            gps_altitude.toDouble(), gps_altitude.toString().c_str());
+        setGpsAltitude(gps_altitude);
+      }
+      else {
+        LoggerW("Couldn't set ExifInformation - gps altitude is not valid: %s",
+            gps_altitude.toString().c_str());
+      }
+      break;
+    }
+    case EXIF_TAG_GPS_ALTITUDE_REF: {
+      //BYTE - 1
+      const ExifByte altitude_ref = static_cast<ExifByte>(entry->data[0]);
+      if(static_cast<ExifByte>(GPS_ALTITUDE_REF_ABOVE_SEA) == altitude_ref ||
+          static_cast<ExifByte>(GPS_ALTITUDE_REF_BELOW_SEA) == altitude_ref) {
+        setGpsAltitudeRef(static_cast<GpsAltitudeRef>(altitude_ref));
+        LoggerD( "Setting ExifInformation gps altitude ref to: %d (%s)",
+            static_cast<int>(altitude_ref),
+            (altitude_ref > 0) ? "below sea" : "above sea");
+      } else {
+        LoggerW("GPS altitude ref is invalid:%d should be 0 or 1!",
+            static_cast<int>(altitude_ref));
+      }
+      break;
+    }
+    case EXIF_TAG_GPS_PROCESSING_METHOD: {
+      //UNDEFINED - Any
+      std::string type, value;
+      if(decomposeExifUndefined(entry, type, value)) {
+        LoggerD("Extracted GPSProcessingMethod: [%s], len:%d, type:%s",
+            value.c_str(), value.length(), type.c_str());
+        setGpsProcessingMethod(type, value);
+
+        LoggerD("Setting ExifInformation processing method to: [%s], len:%d, type:%s",
+            m_gps_processing_method.c_str(),
+            m_gps_processing_method.length(),
+            m_gps_processing_method_type.c_str());
+      }
+      else {
+        LoggerW("GPSProcessingMethod tag contains invalid values!");
+      }
+      break;
+    }
+    case EXIF_TAG_GPS_DATE_STAMP: {
+      //ASCII - 11
+      exif_entry_get_value(entry, buf, sizeof(buf));
+      LoggerD( "Setting ExifInformation gps date stamp to: [%s]", buf );
+      //m_exif_gps_time.setDate(buf);
+      break;
+    }
+    case EXIF_TAG_GPS_TIME_STAMP: {
+      //Rational - 3
+      exif_entry_get_value(entry, buf, sizeof(buf));
+      LoggerD( "Setting ExifInformation gps time stamp to: [%s]", buf);
+
+      Rationals time;
+      if (getRationalsFromEntry(entry, exif_data, 3, time)) {
+        //m_exif_gps_time.setTime(time);
+      }
+      break;
+    }
+    case EXIF_TAG_USER_COMMENT: {
+      //UNDEFINED - Any
+      std::string type, value;
+      if(decomposeExifUndefined(entry, type, value)) {
+        LoggerD("Extracted UserComment: [%s], len:%d, type:%s",
+            value.c_str(), value.length(), type.c_str());
+        setUserComment(type, value);
+
+        LoggerD("Setting ExifInformation user comment to: [%s], len:%d, type:%s",
+            m_user_comment.c_str(),
+            m_user_comment.length(),
+            m_user_comment_type.c_str());
+      }
+      else {
+        LoggerW("UserComment tag contains invalid values!");
+      }
+
+      break;
+    }
+    default:
+      LoggerD("Field of tag:%x.H [%s] is not supported, value: [%s]", entry->tag,
+          exif_tag_get_name_in_ifd(entry->tag, cur_ifd),
+          exif_entry_get_value(entry, buf, sizeof(buf)));
+  }
+}
+
+struct ExifInfoAndDataHolder {
+  ExifInformationPtr exif_info;
+  ExifData* exif_data;
+};
+
+void ExifInformation::contentForeachFunctionProxy(ExifEntry *entry, void *user_data)
+{
+  ExifInfoAndDataHolder* holder = static_cast<ExifInfoAndDataHolder*>(user_data);
+  if (!holder) {
+    LoggerE("holder is NULL");
+  }
+
+  if (!holder->exif_info) {
+    LoggerE("exif_info is NULL!");
+    return;
+  }
+
+  if (!holder->exif_data) {
+    LoggerE("exif_data is NULL!");
+    return;
+  }
+
+  try {
+    holder->exif_info->processEntry(entry, holder->exif_data);
+  }
+  /*catch(const BasePlatformException &err) {
+    LoggerE("processEntry thrown exception: %s : %s", err.getName().c_str(),
+          err.getMessage().c_str());
+  }*/
+  catch(...) {
+    LoggerE("Unsupported error while processing Exif entry.");
+  }
+}
+
+void ExifInformation::dataForeachFunction(ExifContent *content, void *user_data)
+{
+  exif_content_foreach_entry(content, contentForeachFunctionProxy, user_data);
+}
+
+
+ExifInformationPtr ExifInformation::loadFromURI(const std::string& uri)
+{
+  ExifInformationPtr exif_info(new ExifInformation());
+  exif_info->setUri(uri);
+
+  const std::string file_path = ExifUtil::convertUriToPath(uri);
+  ExifData* ed = exif_data_new_from_file (file_path.c_str());
+  if (!ed) {
+    LoggerE("Error reading exif from file %s", file_path.c_str());
+    LoggerE("Error reading exif from file %s", file_path.c_str());
+    //throw NotFoundException("Error reading exif from file");
+  }
+
+  LoggerD("exif_data_foreach_content START");
+
+  ExifInfoAndDataHolder holder;
+  holder.exif_info = exif_info;
+  holder.exif_data = ed;
+  exif_data_foreach_content(ed, dataForeachFunction, static_cast<void*>(&holder));
+
+  LoggerD("exif_data_foreach_content END");
+
+  exif_data_unref(ed);
+  ed = NULL;
+
+  return exif_info;
+}
+
+
+void ExifInformation::removeNulledAttributesFromExifData(ExifData* exif_data)
+{
+  LOGD("Entered");
+  if(!exif_data) {
+    LoggerE("exif_data is NULL");
+    throw common::UnknownException("Invalid Exif provided");
+  }
+
+  if (!isSet(EXIF_INFORMATION_ATTRIBUTE_WIDTH)) {
+    LoggerD("Removing width");
+    ExifTagSaver::removeExifEntryWithTag(EXIF_TAG_IMAGE_WIDTH, exif_data);
+  }
+  if (!isSet(EXIF_INFORMATION_ATTRIBUTE_HEIGHT)) {
+    LoggerD("Removing height");
+    ExifTagSaver::removeExifEntryWithTag(EXIF_TAG_IMAGE_LENGTH, exif_data);
+  }
+  if (!isSet(EXIF_INFORMATION_ATTRIBUTE_DEVICE_MAKER)) {
+    LoggerD("Removing device maker");
+    ExifTagSaver::removeExifEntryWithTag(EXIF_TAG_MAKE, exif_data);
+  }
+  if (!isSet(EXIF_INFORMATION_ATTRIBUTE_ORIENTATION)) {
+    LoggerD("Removing orientation");
+    ExifTagSaver::removeExifEntryWithTag(EXIF_TAG_ORIENTATION, exif_data);
+  }
+  if (!isSet(EXIF_INFORMATION_ATTRIBUTE_EXPOSURE_PROGRAM)) {
+    LoggerD("Removing exposure program");
+    ExifTagSaver::removeExifEntryWithTag(EXIF_TAG_EXPOSURE_PROGRAM, exif_data);
+  }
+  if (!isSet(EXIF_INFORMATION_ATTRIBUTE_ISO_SPEED_RATINGS)) {
+    LoggerD("Removing iso speed ratings");
+    ExifTagSaver::removeExifEntryWithTag(EXIF_TAG_ISO_SPEED_RATINGS, exif_data);
+  }
+  if (!isSet(EXIF_INFORMATION_ATTRIBUTE_WHITE_BALANCE)) {
+    LoggerD("Removing white balance");
+    ExifTagSaver::removeExifEntryWithTag(EXIF_TAG_WHITE_BALANCE, exif_data);
+  }
+  if (!isSet(EXIF_INFORMATION_ATTRIBUTE_DEVICE_MODEL)) {
+    LoggerD("Removing device model");
+    ExifTagSaver::removeExifEntryWithTag(EXIF_TAG_MODEL, exif_data);
+  }
+  if (!isSet(EXIF_INFORMATION_ATTRIBUTE_ORIGINAL_TIME)) {
+    LoggerD("Removing original time");
+    ExifTagSaver::removeExifEntryWithTag(EXIF_TAG_DATE_TIME_ORIGINAL, exif_data);
+  }
+  if (!isSet(EXIF_INFORMATION_ATTRIBUTE_EXPOSURE_TIME)) {
+    LoggerD("Removing exposure time");
+    ExifTagSaver::removeExifEntryWithTag(EXIF_TAG_EXPOSURE_TIME, exif_data);
+  }
+  if (!isSet(EXIF_INFORMATION_ATTRIBUTE_FNUMBER)) {
+    LoggerD("Removing f-number");
+    ExifTagSaver::removeExifEntryWithTag(EXIF_TAG_FNUMBER, exif_data);
+  }
+  if (!isSet(EXIF_INFORMATION_ATTRIBUTE_FLASH)) {
+    LoggerD("Removing flash");
+    ExifTagSaver::removeExifEntryWithTag(EXIF_TAG_FLASH, exif_data);
+  }
+  if (!isSet(EXIF_INFORMATION_ATTRIBUTE_FOCAL_LENGTH)) {
+    LoggerD("Removing focal length");
+    ExifTagSaver::removeExifEntryWithTag(EXIF_TAG_FOCAL_LENGTH, exif_data);
+  }
+  if (!isSet(EXIF_INFORMATION_ATTRIBUTE_GPS_ALTITUDE)) {
+    LoggerD("Removing gps altitude");
+    ExifTagSaver::removeExifEntryWithTag(
+      static_cast<ExifTag>(EXIF_TAG_GPS_ALTITUDE), exif_data);
+  }
+  if (!isSet(EXIF_INFORMATION_ATTRIBUTE_GPS_ALTITUDE_REF)) {
+    LoggerD("Removing gps altitude ref");
+    ExifTagSaver::removeExifEntryWithTag(
+        static_cast<ExifTag>(EXIF_TAG_GPS_ALTITUDE_REF), exif_data);
+  }
+  if (!isSet(EXIF_INFORMATION_ATTRIBUTE_GPS_PROCESSING_METHOD)) {
+    LoggerD("Removing gps processing method");
+    ExifTagSaver::removeExifEntryWithTag(
+        static_cast<ExifTag>(EXIF_TAG_GPS_PROCESSING_METHOD), exif_data);
+  }
+  if (!isSet(EXIF_INFORMATION_ATTRIBUTE_USER_COMMENT)) {
+    LoggerD("Removing user comment");
+    ExifTagSaver::removeExifEntryWithTag(EXIF_TAG_USER_COMMENT, exif_data);
+  }
+
+  if (!m_exif_gps_location.isSet(EXIF_GPS_LOCATION_ATTRIBUTE_LATITUDE)) {
+    LoggerD("Removing latitude");
+    ExifTagSaver::removeExifEntryWithTag(
+        static_cast<ExifTag>(EXIF_TAG_GPS_LATITUDE), exif_data);
+  }
+  if (!m_exif_gps_location.isSet(EXIF_GPS_LOCATION_ATTRIBUTE_LATITUDE_REF)) {
+    LoggerD("Removing latitude ref");
+    ExifTagSaver::removeExifEntryWithTag(
+        static_cast<ExifTag>(EXIF_TAG_GPS_LATITUDE_REF), exif_data);
+  }
+  if (!m_exif_gps_location.isSet(EXIF_GPS_LOCATION_ATTRIBUTE_LONGITUDE)) {
+    LoggerD("Removing longitude");
+    ExifTagSaver::removeExifEntryWithTag(
+        static_cast<ExifTag>(EXIF_TAG_GPS_LONGITUDE), exif_data);
+  }
+  if (!m_exif_gps_location.isSet(EXIF_GPS_LOCATION_ATTRIBUTE_LONGITUDE_REF)) {
+    LoggerD("Removing longitude ref");
+    ExifTagSaver::removeExifEntryWithTag(
+        static_cast<ExifTag>(EXIF_TAG_GPS_LONGITUDE_REF), exif_data);
+  }
+/*
+  if (!m_exif_gps_time.isTimeSet()) {
+    LoggerD("Removing gps time");
+    ExifTagSaver::removeExifEntryWithTag(
+        static_cast<ExifTag>(EXIF_TAG_GPS_TIME_STAMP), exif_data);
+  }
+  if (!m_exif_gps_time.isDateSet()) {
+    LoggerD("Removing gps date");
+    ExifTagSaver::removeExifEntryWithTag(
+        static_cast<ExifTag>(EXIF_TAG_GPS_DATE_STAMP), exif_data);
+  }*/
+}
+
+void ExifInformation::updateAttributesInExifData(ExifData* exif_data)
+{
+  LOGD("Entered");
+  if(!exif_data) {
+    LoggerE("exif_data is NULL");
+    throw common::UnknownException("Invalid Exif provided");
+  }
+
+  if (isSet(EXIF_INFORMATION_ATTRIBUTE_WIDTH)) {
+    LoggerD("Saving width: %d", getWidth());
+    ExifTagSaver::saveToExif(getWidth(),
+        EXIF_TAG_IMAGE_WIDTH, exif_data);
+  }
+  if (isSet(EXIF_INFORMATION_ATTRIBUTE_HEIGHT)) {
+    LoggerD("Saving height: %d", getHeight());
+    ExifTagSaver::saveToExif(getHeight(),
+        EXIF_TAG_IMAGE_LENGTH, exif_data);
+  }
+  if (isSet(EXIF_INFORMATION_ATTRIBUTE_DEVICE_MAKER)) {
+    LoggerD("Saving device maker: %s", getDeviceMaker().c_str());
+    ExifTagSaver::saveToExif(getDeviceMaker(),
+        EXIF_TAG_MAKE, exif_data);
+  }
+  if (isSet(EXIF_INFORMATION_ATTRIBUTE_ORIENTATION)) {
+    LoggerD("Saving orientation: %d", static_cast<int>(getOrientation()));
+    ExifTagSaver::saveToExif(static_cast<long int>(getOrientation()),
+        EXIF_TAG_ORIENTATION, exif_data);
+  }
+  if (isSet(EXIF_INFORMATION_ATTRIBUTE_EXPOSURE_PROGRAM)) {
+    LoggerD("Saving exposure program: %d", static_cast<int>(getExposureProgram()));
+    ExifTagSaver::saveToExif(getExposureProgram(),
+        EXIF_TAG_EXPOSURE_PROGRAM, exif_data);
+  }
+  if (isSet(EXIF_INFORMATION_ATTRIBUTE_ISO_SPEED_RATINGS)) {
+    //std::vector<long long int> iso_ratings = getIsoSpeedRatings();
+    //LoggerD("Saving iso speed ratings count:%d", iso_ratings.size());
+    //ExifTagSaver::saveToExif(iso_ratings, EXIF_FORMAT_SHORT,
+    //    EXIF_TAG_ISO_SPEED_RATINGS, exif_data);
+  }
+  if (isSet(EXIF_INFORMATION_ATTRIBUTE_WHITE_BALANCE)) {
+    LoggerD("Saving white balance: %d", static_cast<int>(getWhiteBalanceMode()));
+    ExifTagSaver::saveToExif(getWhiteBalanceMode(),
+        EXIF_TAG_WHITE_BALANCE, exif_data);
+  }
+  if (isSet(EXIF_INFORMATION_ATTRIBUTE_DEVICE_MODEL)) {
+    LoggerD("Saving device model: %s", getDeviceModel().c_str());
+    ExifTagSaver::saveToExif(getDeviceModel(),
+        EXIF_TAG_MODEL, exif_data);
+  }
+  if (isSet(EXIF_INFORMATION_ATTRIBUTE_ORIGINAL_TIME)) {
+    const time_t o_time = getOriginalTime();
+    const std::string o_time_str = ExifUtil::timeTToExifDateTimeOriginal(o_time);
+    LoggerD("Saving original time time_t:%d, format:%s", static_cast<int>(o_time),
+        o_time_str.c_str());
+
+    ExifTagSaver::saveToExif(o_time_str,
+        EXIF_TAG_DATE_TIME_ORIGINAL, exif_data);
+  }
+  if (isSet(EXIF_INFORMATION_ATTRIBUTE_EXPOSURE_TIME)) {
+    Rational exposure_time = getExposureTime();
+    if (exposure_time.isValid()) {
+      LoggerD("Saving exposure time: %s (%s)",
+          exposure_time.toString().c_str(),
+          exposure_time.toExposureTimeString().c_str());
+
+      ExifTagSaver::saveToExif(exposure_time,
+          EXIF_TAG_EXPOSURE_TIME, exif_data);
+    }
+  }
+  if (isSet(EXIF_INFORMATION_ATTRIBUTE_FNUMBER)) {
+    auto f_number = getFNumber();
+    LoggerD("Saving f-number: %f (%s)", f_number.toDouble(),
+        f_number.toString().c_str());
+    ExifTagSaver::saveToExif(f_number,
+        EXIF_TAG_FNUMBER, exif_data);
+  }
+  if (isSet(EXIF_INFORMATION_ATTRIBUTE_FLASH)) {
+    LoggerD("Saving flash: %s", getFlash() ? "ON" : "OFF");
+    ExifTagSaver::saveToExif(getFlash(),
+        EXIF_TAG_FLASH, exif_data);
+  }
+  if (isSet(EXIF_INFORMATION_ATTRIBUTE_FOCAL_LENGTH)) {
+    auto f_length = getFocalLength();
+    LoggerD("Saving focal length:%f (%s)", f_length.toDouble(),
+        f_length.toString().c_str());
+    ExifTagSaver::saveToExif(f_length,
+        EXIF_TAG_FOCAL_LENGTH, exif_data);
+  }
+  if (isSet(EXIF_INFORMATION_ATTRIBUTE_GPS_ALTITUDE)) {
+    LoggerD("Saving gps altitude:%f (%s)", m_gps_altitude.toDouble(),
+         m_gps_altitude.toString().c_str());
+    ExifTagSaver::saveToExif(m_gps_altitude,
+        static_cast<ExifTag>(EXIF_TAG_GPS_ALTITUDE), exif_data);
+  }
+  if (isSet(EXIF_INFORMATION_ATTRIBUTE_GPS_ALTITUDE_REF)) {
+    //Exif spec:
+    //0 = Sea level
+    //1 = Sea level reference (negative value)
+    LoggerD("Saving gps altitude ref:%d (%s)", static_cast<int>(m_gps_altitude_ref),
+        (m_gps_altitude_ref > 0) ? "below sea" : "above sea");
+    ExifTagSaver::saveToExif(static_cast<long int>(m_gps_altitude_ref),
+        static_cast<ExifTag>(EXIF_TAG_GPS_ALTITUDE_REF), exif_data);
+  }
+  if (isSet(EXIF_INFORMATION_ATTRIBUTE_GPS_PROCESSING_METHOD)) {
+    LoggerD("Saving gps processing method: [%s] type:%s",
+        getGpsProcessingMethod().c_str(), getGpsProcessingMethodType().c_str());
+
+    const std::string joined = getGpsProcessingMethodType() + getGpsProcessingMethod();
+    LoggerD("joined: [%s]", joined.c_str());
+
+    ExifTagSaver::saveToExif(joined,
+        static_cast<ExifTag>(EXIF_TAG_GPS_PROCESSING_METHOD), exif_data, false);
+  }
+  if (isSet(EXIF_INFORMATION_ATTRIBUTE_USER_COMMENT)) {
+    LoggerD("Saving user comment: %s (type:%s)", getUserComment().c_str(),
+      getUserCommentType().c_str());
+
+    const std::string joined = getUserCommentType() + getUserComment();
+    LoggerD("joined: [%s]", joined.c_str());
+
+    ExifTagSaver::saveToExif(joined,
+        EXIF_TAG_USER_COMMENT, exif_data, false);
+  }
+
+  //if(m_gps_location) {
+  //  m_exif_gps_location.set(m_gps_location);
+   // }
+  //ExifTagSaver::saveGpsLocationToExif(m_exif_gps_location, exif_data);
+
+/*  if(m_gps_time) {
+    m_exif_gps_time.setDateAndTime(m_gps_time);
+  }
+  ExifTagSaver::saveGpsTimeToExif(m_exif_gps_time, exif_data);*/
+}
+
+void ExifInformation::saveToFile(const std::string& file_path)
+{
+  LoggerD("Entered");
+  LoggerD("Using JpegFile to read: [%s] and Exif if present", file_path.c_str());
+
+  bool exif_data_is_new = false;
+  JpegFilePtr jpg_file = JpegFile::loadFile(file_path);
+  ExifData* exif_data = jpg_file->getExifData();
+
+  //Exif is not present in file - create new ExifData
+  if (!exif_data) {
+    LoggerD("Exif is not present in file: [%s] creating new", file_path.c_str());
+
+    exif_data = exif_data_new();
+    exif_data_set_option(exif_data, EXIF_DATA_OPTION_FOLLOW_SPECIFICATION);
+    exif_data_set_data_type(exif_data, EXIF_DATA_TYPE_COMPRESSED);
+    exif_data_set_byte_order(exif_data, EXIF_BYTE_ORDER_MOTOROLA);
+    exif_data_is_new = true;
+  }
+
+  if (!exif_data) {
+    LoggerE("Couldn't allocate new ExifData");
+    throw common::UnknownException("Memory allocation failed");
+  }
+
+  LoggerD("Exif data type: %d", exif_data_get_data_type(exif_data) );
+  LoggerD("Exif byte order: %d", exif_data_get_byte_order(exif_data) );
+  exif_data_set_option(exif_data, EXIF_DATA_OPTION_FOLLOW_SPECIFICATION);
+
+  try {
+    //If we have created new ExifData there is nothing to remove
+    if(!exif_data_is_new) {
+      //Remove attributes that have been nulled
+      removeNulledAttributesFromExifData(exif_data);
+    }
+
+    updateAttributesInExifData(exif_data);
+
+    LOGD("Using JpegFile to save new Exif in: [%s]", file_path.c_str());
+    if(exif_data_is_new) {
+      jpg_file->setNewExifData(exif_data);
+    }
+
+    jpg_file->saveToFile(file_path);
+  }
+  catch (...) {
+    exif_data_unref(exif_data);
+    exif_data = NULL;
+    throw;
+  }
+
+  exif_data_unref(exif_data);
+  exif_data = NULL;
+}
+
+} // exif
+} // extension
diff --git a/src/exif/ExifInformation.h b/src/exif/ExifInformation.h
new file mode 100644 (file)
index 0000000..a1fa343
--- /dev/null
@@ -0,0 +1,210 @@
+//
+// Tizen Web Device API
+// Copyright (c) 2014 Samsung Electronics Co., Ltd.
+//
+// Licensed 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.
+//
+
+#ifndef __TIZEN_EXIF_EXIFINFORMATION_H_
+#define __TIZEN_EXIF_EXIFINFORMATION_H_
+
+#include <libexif/exif-loader.h>
+#include <string>
+
+//#include <JSVector.h>
+//#include <TimeDuration.h>
+
+#include "ExifGPSLocation.h"
+//#include "ExifGPSTime.h"
+
+namespace extension {
+namespace exif {
+
+class ExifInformation;
+typedef std::shared_ptr<ExifInformation> ExifInformationPtr;
+
+extern const size_t EXIF_UNDEFINED_TYPE_LENGTH;
+extern const std::string EXIF_UNDEFINED_TYPE_ASCII;
+extern const std::string EXIF_UNDEFINED_TYPE_JIS;
+extern const std::string EXIF_UNDEFINED_TYPE_UNICODE;
+extern const std::string EXIF_UNDEFINED_TYPE_UNDEFINED;
+
+enum ExifInformationAttribute{
+  EXIF_INFORMATION_ATTRIBUTE_URI,
+  EXIF_INFORMATION_ATTRIBUTE_WIDTH,
+  EXIF_INFORMATION_ATTRIBUTE_HEIGHT,
+  EXIF_INFORMATION_ATTRIBUTE_DEVICE_MAKER,
+  EXIF_INFORMATION_ATTRIBUTE_DEVICE_MODEL,
+  EXIF_INFORMATION_ATTRIBUTE_ORIGINAL_TIME,
+  EXIF_INFORMATION_ATTRIBUTE_ORIENTATION,
+  EXIF_INFORMATION_ATTRIBUTE_FNUMBER,
+  EXIF_INFORMATION_ATTRIBUTE_ISO_SPEED_RATINGS,
+  EXIF_INFORMATION_ATTRIBUTE_EXPOSURE_TIME,
+  EXIF_INFORMATION_ATTRIBUTE_EXPOSURE_PROGRAM,
+  EXIF_INFORMATION_ATTRIBUTE_FLASH,
+  EXIF_INFORMATION_ATTRIBUTE_FOCAL_LENGTH,
+  EXIF_INFORMATION_ATTRIBUTE_WHITE_BALANCE,
+  EXIF_INFORMATION_ATTRIBUTE_GPS_ALTITUDE,
+  EXIF_INFORMATION_ATTRIBUTE_GPS_ALTITUDE_REF,
+  EXIF_INFORMATION_ATTRIBUTE_GPS_PROCESSING_METHOD,
+  EXIF_INFORMATION_ATTRIBUTE_USER_COMMENT,
+  EXIF_INFORMATION_ATTRIBUTE_NUMBER_OF_ATTRIBUTES
+};
+
+enum GpsAltitudeRef {
+  GPS_ALTITUDE_REF_ABOVE_SEA = 0,
+  GPS_ALTITUDE_REF_BELOW_SEA = 1
+};
+
+class ExifInformation
+{
+public:
+  ExifInformation();
+  ~ExifInformation();
+
+  static ExifInformationPtr loadFromURI(const std::string& uri);
+  void saveToFile(const std::string& file_path);
+
+  const std::string& getUri();
+  void setUri(const std::string& uri);
+
+  unsigned long getWidth() const;
+  void setWidth(unsigned long width);
+
+  unsigned long getHeight() const;
+  void setHeight(unsigned long height);
+
+  const std::string& getDeviceMaker();
+  void setDeviceMaker(const std::string& device_maker);
+
+  const std::string& getDeviceModel();
+  void setDeviceModel(const std::string& device_model);
+
+  time_t getOriginalTime() const;
+  void setOriginalTime(time_t original_time);
+
+  ImageOrientation getOrientation() const;
+  void setOrientation(ImageOrientation orientation);
+
+  const Rational& getFNumber() const;
+  void setFNumber(Rational f_number);
+
+  //Common::JSLongLongVector getIsoSpeedRatings();
+  //void setIsoSpeedRatings(const std::vector<long long int>& iso_speed_ratings);
+  void appendIsoSpeedRatings(long long int iso_speed_rating);
+
+  const Rational& getExposureTime();
+  void setExposureTime(const Rational& exposure_time);
+
+  ExposureProgram getExposureProgram();
+  void setExposureProgram(ExposureProgram exposure_program );
+
+  bool getFlash() const;
+  void setFlash(bool flash);
+
+  const Rational& getFocalLength() const;
+  void setFocalLength(Rational focal_length);
+
+  WhiteBalanceMode getWhiteBalanceMode() const;
+  void setWhiteBalanceMode(WhiteBalanceMode white_balance);
+
+  ExifGPSLocation& getGPSExifLocation();
+  //Tizen::SimpleCoordinatesPtr getGPSLocation();
+  //void setGPSLocation(Tizen::SimpleCoordinatesPtr gps_location);
+  void unsetGPSLocation();
+
+  const Rational& getGpsAltitude() const;
+  void setGpsAltitude(Rational gps_altitude);
+
+  GpsAltitudeRef getGpsAltitudeRef() const;
+  void setGpsAltitudeRef(const GpsAltitudeRef ref);
+
+  /**
+   * gps_altitude can be negative and positive:
+   * if gps_altitude < 0.0 GPS_ALTITUDE_REF_BELOW_SEA is set
+   * if gps_altitude >= 0.0 GPS_ALTITUDE_REF_ABOVE_SEA is set
+   */
+  void setGpsAltitudeWithRef(double gps_altitude);
+
+  /**
+   * Return gps altitude which can be negative (below sea level) and positive (above sea
+   * level)
+   */
+  double getGpsAltitudeWithRef() const;
+
+  const std::string& getGpsProcessingMethod() const;
+  const std::string& getGpsProcessingMethodType() const;
+  void setGpsProcessingMethod(const std::string& type,
+      const std::string& processing_method);
+
+  //ExifGPSTime& getExifGpsTime();
+  //const ExifGPSTime& getExifGpsTime() const;
+  //Time::TZDatePtr getGpsTime();
+  //void setGpsTime(Time::TZDatePtr new_time);
+  void unsetGPStime();
+
+  const std::string& getUserComment();
+  const std::string& getUserCommentType();
+  void setUserComment(const std::string& type,
+      const std::string& user_comment);
+
+  bool isSet(ExifInformationAttribute attribute) const;
+  void unset(ExifInformationAttribute attribute);
+
+private:
+  void processEntry(ExifEntry* entry, ExifData* exif_data);
+  static void contentForeachFunctionProxy(ExifEntry* entry, void* user_data);
+  static void dataForeachFunction(ExifContent* content, void* user_data);
+
+  void removeNulledAttributesFromExifData(ExifData* exif_data);
+  void updateAttributesInExifData(ExifData* exif_data);
+
+  std::string m_uri;
+  unsigned long m_width;
+  unsigned long m_height;
+  std::string m_device_maker;
+  std::string m_device_model;
+
+  time_t m_original_time;
+
+  ImageOrientation m_orientation;
+  Rational m_f_number;
+  //Common::JSLongLongVector m_iso_speed_ratings;
+  Rational m_exposure_time;
+  ExposureProgram m_exposure_program;
+  bool m_flash;
+  Rational m_focal_length;
+  WhiteBalanceMode m_white_balance;
+
+  ExifGPSLocation m_exif_gps_location;
+  //Tizen::SimpleCoordinatesPtr m_gps_location;
+
+  Rational m_gps_altitude;
+  GpsAltitudeRef m_gps_altitude_ref;
+
+  std::string m_gps_processing_method;
+  std::string m_gps_processing_method_type;
+
+  //ExifGPSTime m_exif_gps_time;
+  //Time::TZDatePtr m_gps_time;
+
+  std::string m_user_comment;
+  std::string m_user_comment_type;
+
+  bool m_is_set[EXIF_INFORMATION_ATTRIBUTE_NUMBER_OF_ATTRIBUTES];
+};
+
+} // exif
+} // extension
+
+#endif // __TIZEN_EXIF_EXIFINFORMATION_H_
diff --git a/src/exif/ExifTagSaver.cpp b/src/exif/ExifTagSaver.cpp
new file mode 100644 (file)
index 0000000..ae1baaa
--- /dev/null
@@ -0,0 +1,412 @@
+//
+// Tizen Web Device API
+// Copyright (c) 2014 Samsung Electronics Co., Ltd.
+//
+// Licensed 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.
+//
+
+#include "ExifTagSaver.h"
+
+#include <libexif/exif-format.h>
+#include <sstream>
+#include <cstring>
+
+#include "common/platform_exception.h"
+#include "common/logger.h"
+
+#include "ExifUtil.h"
+
+namespace extension {
+namespace exif {
+
+void ExifTagSaver::removeExifEntryWithTag(const ExifTag tag, ExifData* exif_data)
+{
+  LoggerD("Entered tag:%d (0x%x)", tag, tag);
+  ExifEntry* exif_entry = exif_data_get_entry(exif_data, tag);
+  if (!exif_entry) {
+    LoggerE("Exif entry with tag:%d (0x%x) is not present", tag, tag);
+    return;
+  }
+
+  exif_content_remove_entry(exif_entry->parent, exif_entry);
+}
+
+void ExifTagSaver::saveToExif(long int value, ExifTag tag, ExifData* exif_data)
+{
+  ExifEntry* entry = prepareEntry(exif_data, tag);
+  ExifByteOrder order = exif_data_get_byte_order(exif_data);
+
+  switch (entry->format) {
+    case EXIF_FORMAT_BYTE:
+      entry->data[0] = static_cast<unsigned char>(value);
+      break;
+    case EXIF_FORMAT_SHORT:
+      exif_set_short (entry->data, order, value);
+      break;
+    case EXIF_FORMAT_LONG:
+      exif_set_long (entry->data, order, value);
+      break;
+    case EXIF_FORMAT_SLONG:
+      exif_set_slong (entry->data, order, value);
+      break;
+    default:
+      LoggerE("Error: wrong format: %d \n", entry->format );
+  }
+}
+
+void ExifTagSaver::saveToExif(const std::string& value, ExifTag tag, ExifData* exif_data,
+    bool add_zero_character)
+{
+  ExifEntry* entry = prepareEntry(exif_data, tag);
+  if (!value.empty()) {
+
+    if (entry->data) {
+      free(entry->data);
+      entry->data = NULL;
+    }
+
+    size_t new_len = value.length();
+    if (add_zero_character) {
+      ++new_len;
+    }
+
+    entry->size = new_len;
+    entry->components = new_len;
+
+    entry->data = static_cast<unsigned char*>(malloc(entry->size));
+    memcpy(entry->data, value.c_str(), value.length());
+    if (add_zero_character) {
+      entry->data[value.length()] = '\0';
+    }
+  }
+}
+
+void ExifTagSaver::saveToExif(const Rational& value, ExifTag tag, ExifData* exif_data)
+{
+  ExifEntry* entry = prepareEntry(exif_data, tag);
+  entry->format = EXIF_FORMAT_RATIONAL;
+
+  if (ExifTypeInfo::RationalSize != entry->size) {
+    if (entry->data) {
+      free(entry->data);
+      entry->data = NULL;
+    }
+
+    entry->size = ExifTypeInfo::RationalSize;
+    entry->data = static_cast<unsigned char*>(malloc(entry->size));
+    memset(entry->data, 0, entry->size);
+  }
+
+  entry->components = 1;
+
+  ExifByteOrder order = exif_data_get_byte_order(exif_data);
+  ExifRational r;
+  r.numerator = value.nominator;
+  r.denominator = value.denominator;
+  exif_set_rational(entry->data, order, r);
+}
+
+void ExifTagSaver::saveToExif(const Rationals& value, ExifTag tag, ExifData* exif_data)
+{
+  ExifEntry* entry = prepareEntry(exif_data, tag);
+  ExifByteOrder order = exif_data_get_byte_order(exif_data);
+  entry->format = EXIF_FORMAT_RATIONAL;
+
+  const unsigned int required_size = ExifTypeInfo::RationalSize * value.size();
+  if (required_size != entry->size) {
+    if (entry->data) {
+      free(entry->data);
+      entry->data = NULL;
+    }
+
+    entry->size = required_size;
+    entry->data = static_cast<unsigned char*>(malloc(entry->size));
+    memset(entry->data, 0, entry->size);
+  }
+
+  entry->components = value.size();
+  for (size_t i = 0; i < value.size(); ++i)
+  {
+    ExifRational r;
+    r.numerator = value[i].nominator;
+    r.denominator = value[i].denominator;
+    exif_set_rational(entry->data + i * ExifTypeInfo::RationalSize, order, r);
+  }
+}
+
+void ExifTagSaver::saveToExif(std::vector<long long int>& value, ExifFormat store_as,
+      ExifTag tag, ExifData* exif_data)
+{
+  ExifEntry* entry = prepareEntry(exif_data, tag);
+  const ExifByteOrder order = exif_data_get_byte_order(exif_data);
+
+  const size_t size_per_member = ExifUtil::getSizeOfExifFormatType(store_as);
+  switch (store_as) {
+    case EXIF_FORMAT_BYTE:
+    case EXIF_FORMAT_SHORT:
+    case EXIF_FORMAT_SSHORT:
+    case EXIF_FORMAT_LONG:
+    case EXIF_FORMAT_SLONG:
+      break;
+    default:
+      LoggerE("output ExifFormat: %d is not supported!");
+      return;
+  }
+  entry->format = store_as;
+
+  const size_t num_elements = value.size();
+  const unsigned int required_size = size_per_member * num_elements;
+  if (required_size != entry->size) {
+    if (entry->data) {
+      free(entry->data);
+      entry->data = NULL;
+    }
+
+    entry->size = required_size;
+    entry->data = static_cast<unsigned char*>(malloc(entry->size));
+    memset(entry->data, 0, entry->size);
+  }
+  entry->components = num_elements;
+
+
+  switch (store_as) {
+    case EXIF_FORMAT_BYTE: {
+      for(size_t i = 0; i < num_elements; ++i) {
+        entry->data[i] = static_cast<ExifByte>(value[i]);
+      }
+      break;
+    }
+
+    case EXIF_FORMAT_SHORT: {
+      for (size_t i = 0; i < num_elements; ++i) {
+        exif_set_short(entry->data + i * size_per_member, order,
+            static_cast<ExifShort>(value[i]));
+      }
+      break;
+    }
+
+    case EXIF_FORMAT_SSHORT: {
+      for (size_t i = 0; i < num_elements; ++i) {
+        exif_set_sshort(entry->data + i * size_per_member, order,
+            static_cast<ExifSShort>(value[i]));
+      }
+      break;
+    }
+
+    case EXIF_FORMAT_LONG: {
+      for (size_t i = 0; i < num_elements; ++i) {
+        exif_set_long(entry->data + i * size_per_member, order,
+            static_cast<ExifLong>(value[i]));
+      }
+      break;
+    }
+
+    case EXIF_FORMAT_SLONG: {
+      for(size_t i = 0; i < num_elements; ++i) {
+        exif_set_slong(entry->data + i * size_per_member, order,
+            static_cast<ExifSLong>(value[i]));
+      }
+      break;
+    }
+
+    default:
+      break;
+  }
+
+
+  LoggerD("entry after save:");
+  ExifUtil::printExifEntryInfo(entry, exif_data);
+}
+
+void ExifTagSaver::saveGpsLocationToExif(const ExifGPSLocation& gps_info,
+    ExifData* exif_data)
+{
+  if (gps_info.isSet(EXIF_GPS_LOCATION_ATTRIBUTE_LATITUDE)) {
+    auto latitude = gps_info.getLatitude();
+    LoggerD("Saving latitude: %s", latitude.toDebugString().c_str());
+    saveToExif(latitude.toRationalsVector(),
+        static_cast<ExifTag>(EXIF_TAG_GPS_LATITUDE), exif_data);
+  }
+
+  if (gps_info.isSet(EXIF_GPS_LOCATION_ATTRIBUTE_LATITUDE_REF)) {
+    std::string lat_ref =
+        (gps_info.getLatitudeRef() == GPS_LOCATION_NORTH) ? "N" : "S";
+    LoggerD("Saving latitude ref: %s", lat_ref.c_str());
+    saveToExif(lat_ref, static_cast<ExifTag>(EXIF_TAG_GPS_LATITUDE_REF), exif_data);
+  }
+
+  if (gps_info.isSet(EXIF_GPS_LOCATION_ATTRIBUTE_LONGITUDE)) {
+
+    auto longitude = gps_info.getLongitude();
+    LoggerD("Saving longitude: %s", longitude.toDebugString().c_str());
+    saveToExif(longitude.toRationalsVector(),
+        static_cast<ExifTag>(EXIF_TAG_GPS_LONGITUDE), exif_data);
+  }
+
+  if (gps_info.isSet(EXIF_GPS_LOCATION_ATTRIBUTE_LONGITUDE_REF)) {
+    std::string long_ref =
+        (gps_info.getLongitudeRef() == GPS_LOCATION_WEST) ? "W" : "E";
+    LoggerD("Saving longitude ref: %s", long_ref.c_str());
+    saveToExif(long_ref, static_cast<ExifTag>(EXIF_TAG_GPS_LONGITUDE_REF), exif_data);
+  }
+}
+/*
+void ExifTagSaver::saveGpsTimeToExif(const ExifGPSTime& gps_time,
+      ExifData* exif_data)
+{
+  if (gps_time.isTimeSet()) {
+    const Rationals& time = gps_time.getTime();
+    LoggerD("Saving gps time: [%s]h [%s]m [%s]d",
+        time[0].toString().c_str(),
+        time[1].toString().c_str(),
+        time[2].toString().c_str());
+
+    saveToExif(time, static_cast<ExifTag>(EXIF_TAG_GPS_TIME_STAMP), exif_data);
+  }
+
+  if (gps_time.isDateSet()) {
+    std::string date = gps_time.getDate();
+    LoggerD("Saving gps date: [%s]", date.c_str());
+
+    saveToExif(date, static_cast<ExifTag>(EXIF_TAG_GPS_DATE_STAMP), exif_data);
+  }
+}
+*/
+ExifEntry* ExifTagSaver::prepareEntry(ExifData* exif_data, ExifTag tag)
+{
+  LoggerD("Entered m_tag:%d", tag);
+
+  ExifEntry* exif_entry = exif_data_get_entry(exif_data, tag);
+  if (!exif_entry) {
+    exif_entry = createNewTag(exif_data, deduceIfdSection(tag),
+        deduceDataFormat(tag), tag );
+  }
+
+  if (!exif_entry) {
+    LoggerE("Couldn't create new Exif tag");
+    //throw UnknownException("Could not save Exif to file");
+  }
+
+  exif_entry_initialize(exif_entry, tag);
+
+  return exif_entry;
+}
+
+ExifEntry* ExifTagSaver::createNewTag(ExifData* exif_data, ExifIfd ifd,
+    ExifFormat format, ExifTag tag)
+{
+  LoggerD("Creating new tag: %d", tag);
+
+  ExifEntry* new_entry = exif_entry_new();
+  new_entry->tag = tag;
+  new_entry->format = format;
+  exif_content_add_entry(exif_data->ifd[ifd], new_entry);
+  exif_entry_initialize(new_entry, tag);
+  return new_entry;
+}
+
+ExifIfd ExifTagSaver::deduceIfdSection(ExifTag tag)
+{
+  switch (static_cast<unsigned int>(tag)) {
+    //Tags in IFD_0 Section
+    case EXIF_TAG_MAKE:
+    case EXIF_TAG_MODEL:
+    case EXIF_TAG_IMAGE_WIDTH:
+    case EXIF_TAG_IMAGE_LENGTH:
+    case EXIF_TAG_ORIENTATION:
+      return EXIF_IFD_0;
+
+    //Tags in IFD_EXIF Section
+    case EXIF_TAG_USER_COMMENT:
+    case EXIF_TAG_DATE_TIME_ORIGINAL:
+    case EXIF_TAG_EXPOSURE_TIME:
+    case EXIF_TAG_FNUMBER:
+    case EXIF_TAG_EXPOSURE_PROGRAM:
+    case EXIF_TAG_ISO_SPEED_RATINGS:
+    case EXIF_TAG_WHITE_BALANCE:
+    case EXIF_TAG_FLASH:
+    case EXIF_TAG_FOCAL_LENGTH:
+      return EXIF_IFD_EXIF;
+
+    //Tags in IFD_GPS Section
+    case EXIF_TAG_GPS_LATITUDE_REF:
+    case EXIF_TAG_GPS_LONGITUDE_REF:
+    case EXIF_TAG_GPS_LATITUDE:
+    case EXIF_TAG_GPS_LONGITUDE:
+    case EXIF_TAG_GPS_ALTITUDE:
+    case EXIF_TAG_GPS_ALTITUDE_REF:
+    case EXIF_TAG_GPS_TIME_STAMP:
+    case EXIF_TAG_GPS_PROCESSING_METHOD:
+    case EXIF_TAG_GPS_DATE_STAMP:
+      return EXIF_IFD_GPS;
+
+    //Tags in other sections
+    default:
+      LoggerE("Unsupported tag: %d", tag);
+      //throw UnknownException("Unsupported tag");
+  }
+}
+
+ExifFormat ExifTagSaver::deduceDataFormat(ExifTag tag)
+{
+  switch (static_cast<unsigned int>(tag)) {
+    //Tags with byte type:
+    case EXIF_TAG_GPS_ALTITUDE_REF:
+      return EXIF_FORMAT_BYTE;
+
+    //Tags with long type:
+    case EXIF_TAG_IMAGE_WIDTH:
+    case EXIF_TAG_IMAGE_LENGTH:
+      return EXIF_FORMAT_LONG;
+
+    //Tags with short type:
+    case EXIF_TAG_ORIENTATION:
+    case EXIF_TAG_EXPOSURE_PROGRAM:
+    case EXIF_TAG_WHITE_BALANCE:
+    case EXIF_TAG_FLASH:
+      return EXIF_FORMAT_SHORT;
+
+    //Tags with ASCII type:
+    case EXIF_TAG_MAKE:
+    case EXIF_TAG_MODEL:
+    case EXIF_TAG_DATE_TIME_ORIGINAL:
+    case EXIF_TAG_GPS_LATITUDE_REF:
+    case EXIF_TAG_GPS_LONGITUDE_REF:
+    case EXIF_TAG_GPS_DATE_STAMP:
+      return EXIF_FORMAT_ASCII;
+
+    //Tags with rational type:
+    case EXIF_TAG_EXPOSURE_TIME:
+    case EXIF_TAG_FNUMBER:
+    case EXIF_TAG_FOCAL_LENGTH:
+    case EXIF_TAG_GPS_LATITUDE:
+    case EXIF_TAG_GPS_LONGITUDE:
+    case EXIF_TAG_GPS_ALTITUDE:
+    case EXIF_TAG_GPS_TIME_STAMP:
+    case EXIF_TAG_ISO_SPEED_RATINGS:
+      return EXIF_FORMAT_RATIONAL;
+
+    //Tags with undefined type:
+    case EXIF_TAG_USER_COMMENT:
+    case EXIF_TAG_GPS_PROCESSING_METHOD:
+      return EXIF_FORMAT_UNDEFINED;
+
+    //Unsupported tags:
+    default:
+      LoggerE("Unsupported tag: %d", tag);
+      //throw UnknownException("Unsupported tag");
+  }
+}
+
+} // exif
+} // extension
diff --git a/src/exif/ExifTagSaver.h b/src/exif/ExifTagSaver.h
new file mode 100644 (file)
index 0000000..fc07eaf
--- /dev/null
@@ -0,0 +1,62 @@
+//
+// Tizen Web Device API
+// Copyright (c) 2014 Samsung Electronics Co., Ltd.
+//
+// Licensed 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.
+//
+
+/**
+ * @file  ExifTagSaver.h
+ */
+
+#ifndef __TIZEN_EXIF_EXIF_TAG_SAVER_H__
+#define __TIZEN_EXIF_EXIF_TAG_SAVER_H__
+
+#include <string>
+#include <libexif/exif-data.h>
+
+#include "ExifGPSLocation.h"
+//#include "ExifGPSTime.h"
+
+namespace extension {
+namespace exif {
+
+class ExifTagSaver
+{
+public:
+  static void removeExifEntryWithTag(const ExifTag tag, ExifData* exif_data);
+
+  static void saveToExif(long int value, ExifTag tag, ExifData* exif_data);
+  static void saveToExif(const std::string& value, ExifTag tag, ExifData* exif_data,
+      bool add_zero_character = true);
+  static void saveToExif(const Rational& value, ExifTag tag, ExifData* exif_data);
+  static void saveToExif(const Rationals& value, ExifTag tag, ExifData* exif_data);
+  static void saveToExif(std::vector<long long int>& value, ExifFormat store_as,
+      ExifTag tag, ExifData* exif_data);
+  static void saveGpsLocationToExif(const ExifGPSLocation& gps_info,
+      ExifData* exif_data);
+  //static void saveGpsTimeToExif(const ExifGPSTime& gps_time,
+      //ExifData* exif_data);
+
+private:
+  static ExifEntry* prepareEntry(ExifData* exif_data, ExifTag tag);
+  static ExifIfd deduceIfdSection(ExifTag tag);
+  static ExifFormat deduceDataFormat(ExifTag tag);
+  static ExifEntry* createNewTag(ExifData* exif_data, ExifIfd ifd,
+    ExifFormat format, ExifTag tag);
+};
+
+} // exif
+} // extension
+
+#endif // __TIZEN_EXIF_EXIF_TAG_SAVER_H__
diff --git a/src/exif/ExifUtil.cpp b/src/exif/ExifUtil.cpp
new file mode 100644 (file)
index 0000000..7f86335
--- /dev/null
@@ -0,0 +1,431 @@
+//
+// Tizen Web Device API
+// Copyright (c) 2014 Samsung Electronics Co., Ltd.
+//
+// Licensed 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.
+//
+
+#include "ExifUtil.h"
+
+#include <iomanip>
+#include <sstream>
+
+#include "common/platform_exception.h"
+#include "common/logger.h"
+
+namespace extension {
+namespace exif {
+
+namespace {
+const std::string ORIENTATION_NORMAL = "NORMAL";
+const std::string ORIENTATION_FLIP_HORIZONTAL = "FLIP_HORIZONTAL";
+const std::string ORIENTATION_ROTATE_180 = "ROTATE_180";
+const std::string ORIENTATION_FLIP_VERTICAL = "FLIP_VERTICAL";
+const std::string ORIENTATION_TRANSPOSE = "TRANSPOSE";
+const std::string ORIENTATION_ROTATE_90 = "ROTATE_90";
+const std::string ORIENTATION_TRANSVERSE = "TRANSVERSE";
+const std::string ORIENTATION_ROTATE_270 = "ROTATE_270";
+
+const std::string WHITE_BALANCE_MODE_AUTO = "AUTO";
+const std::string WHITE_BALANCE_MODE_MANUAL = "MANUAL";
+
+const std::string EXPOSURE_PROGRAM_NOT_DEFINED = "NOT_DEFINED";
+const std::string EXPOSURE_PROGRAM_MANUAL = "MANUAL";
+const std::string EXPOSURE_PROGRAM_NORMAL = "NORMAL";
+const std::string EXPOSURE_PROGRAM_APERTURE_PRIORITY = "APERTURE_PRIORITY";
+const std::string EXPOSURE_PROGRAM_SHUTTER_PRIORITY = "SHUTTER_PRIORITY";
+const std::string EXPOSURE_PROGRAM_CREATIVE_PROGRAM = "CREATIVE_PROGRAM";
+const std::string EXPOSURE_PROGRAM_ACTION_PROGRAM = "ACTION_PROGRAM";
+const std::string EXPOSURE_PROGRAM_PORTRAIT_MODE = "PORTRAIT_MODE";
+const std::string EXPOSURE_PROGRAM_LANDSCAPE_MODE = "LANDSCAPE_MODE";
+
+const std::string DUMMY = ""; // For unexpected input handling
+
+const std::string URI_PREFIX = "file://";
+const std::string URI_ABSOLUTE_PREFIX = "file:///";
+}
+
+const size_t ExifTypeInfo::ByteSize = 1;
+const size_t ExifTypeInfo::ASCIISize = 1;
+const size_t ExifTypeInfo::ShortSize = 2;
+const size_t ExifTypeInfo::LongSize = 4;
+const size_t ExifTypeInfo::RationalSize = 8;
+const size_t ExifTypeInfo::UndefinedSize = 1;
+const size_t ExifTypeInfo::SLongSize = 4;
+const size_t ExifTypeInfo::SRationalSize = 8;
+
+const ExifByte ExifTypeInfo::ByteId = 1;
+const ExifByte ExifTypeInfo::ASCIIId = 2;
+const ExifByte ExifTypeInfo::ShortId = 3;
+const ExifByte ExifTypeInfo::LongId = 4;
+const ExifByte ExifTypeInfo::RationalId = 5;
+const ExifByte ExifTypeInfo::UndefinedId = 7;
+const ExifByte ExifTypeInfo::SLongId = 9;
+const ExifByte ExifTypeInfo::SRationalId = 10;
+
+ExifUtil::ExifUtil()
+{
+}
+
+ExifUtil::~ExifUtil()
+{
+}
+
+ImageOrientation ExifUtil::stringToOrientation(const std::string& orientation)
+{
+  LoggerD("Entered");
+  if (ORIENTATION_NORMAL == orientation) {
+    return ImageOrientation::EXIF_ORIENTATION_NORMAL;
+  }
+  if (ORIENTATION_FLIP_HORIZONTAL == orientation) {
+    return ImageOrientation::EXIF_ORIENTATION_FLIP_HORIZONTAL;
+  }
+  if (ORIENTATION_ROTATE_180 == orientation) {
+    return ImageOrientation::EXIF_ORIENTATION_ROTATE_180;
+  }
+  if (ORIENTATION_FLIP_VERTICAL == orientation) {
+    return ImageOrientation::EXIF_ORIENTATION_FLIP_VERTICAL;
+  }
+  if (ORIENTATION_TRANSPOSE == orientation) {
+    return ImageOrientation::EXIF_ORIENTATION_TRANSPOSE;
+  }
+  if (ORIENTATION_ROTATE_90 == orientation) {
+    return ImageOrientation::EXIF_ORIENTATION_ROTATE_90;
+  }
+  if (ORIENTATION_TRANSVERSE == orientation) {
+    return ImageOrientation::EXIF_ORIENTATION_TRANSVERSE;
+  }
+  if (ORIENTATION_ROTATE_270 == orientation) {
+    return ImageOrientation::EXIF_ORIENTATION_ROTATE_270;
+  }
+  return ImageOrientation::EXIF_ORIENTATION_NOT_VALID;
+}
+
+const std::string& ExifUtil::orientationToString(ImageOrientation orientation)
+{
+  LoggerD("Entered");
+  switch (orientation) {
+    case ImageOrientation::EXIF_ORIENTATION_NORMAL:
+      return ORIENTATION_NORMAL;
+    case ImageOrientation::EXIF_ORIENTATION_FLIP_HORIZONTAL:
+      return ORIENTATION_FLIP_HORIZONTAL;
+    case ImageOrientation::EXIF_ORIENTATION_ROTATE_180:
+      return ORIENTATION_ROTATE_180;
+    case ImageOrientation::EXIF_ORIENTATION_FLIP_VERTICAL:
+      return ORIENTATION_FLIP_VERTICAL;
+    case ImageOrientation::EXIF_ORIENTATION_TRANSPOSE:
+      return ORIENTATION_TRANSPOSE;
+    case ImageOrientation::EXIF_ORIENTATION_ROTATE_90:
+      return ORIENTATION_ROTATE_90;
+    case ImageOrientation::EXIF_ORIENTATION_TRANSVERSE:
+      return ORIENTATION_TRANSVERSE;
+    case ImageOrientation::EXIF_ORIENTATION_ROTATE_270:
+      return ORIENTATION_ROTATE_270;
+    default:
+      return DUMMY;
+  }
+}
+
+WhiteBalanceMode ExifUtil::stringToWhiteBalance(const std::string& white_balance)
+{
+  LoggerD("Entered");
+  if (WHITE_BALANCE_MODE_AUTO == white_balance) {
+    return WhiteBalanceMode::EXIF_WHITE_BALANCE_MODE_AUTO;
+  }
+  if (WHITE_BALANCE_MODE_MANUAL == white_balance) {
+    return WhiteBalanceMode::EXIF_WHITE_BALANCE_MODE_MANUAL;
+  }
+  return WhiteBalanceMode::EXIF_WHITE_BALANCE_MODE_NOT_VALID;
+}
+
+const std::string& ExifUtil::whiteBalanceToString(WhiteBalanceMode value)
+{
+  LoggerD("Entered");
+  switch (value) {
+    case WhiteBalanceMode::EXIF_WHITE_BALANCE_MODE_AUTO:
+      return WHITE_BALANCE_MODE_AUTO;
+    case WhiteBalanceMode::EXIF_WHITE_BALANCE_MODE_MANUAL:
+      return WHITE_BALANCE_MODE_MANUAL;
+    default:
+      return DUMMY;
+  }
+}
+
+ExposureProgram ExifUtil::stringToExposureProgram(
+    const std::string& exposure_program)
+{
+  LoggerD("Entered");
+  if (EXPOSURE_PROGRAM_NOT_DEFINED == exposure_program) {
+    return EXIF_EXPOSURE_PROGRAM_NOT_DEFINED;
+  }
+  if (EXPOSURE_PROGRAM_MANUAL == exposure_program) {
+    return EXIF_EXPOSURE_PROGRAM_MANUAL;
+  }
+  if (EXPOSURE_PROGRAM_NORMAL == exposure_program) {
+    return EXIF_EXPOSURE_PROGRAM_NORMAL;
+  }
+  if (EXPOSURE_PROGRAM_APERTURE_PRIORITY == exposure_program) {
+    return EXIF_EXPOSURE_PROGRAM_APERTURE_PRIORITY;
+  }
+  if (EXPOSURE_PROGRAM_SHUTTER_PRIORITY == exposure_program) {
+    return EXIF_EXPOSURE_PROGRAM_SHUTTER_PRIORITY;
+  }
+  if (EXPOSURE_PROGRAM_CREATIVE_PROGRAM == exposure_program) {
+    return EXIF_EXPOSURE_PROGRAM_CREATIVE_PROGRAM;
+  }
+  if (EXPOSURE_PROGRAM_ACTION_PROGRAM == exposure_program) {
+    return EXIF_EXPOSURE_PROGRAM_ACTION_PROGRAM;
+  }
+  if (EXPOSURE_PROGRAM_PORTRAIT_MODE == exposure_program) {
+    return EXIF_EXPOSURE_PROGRAM_PORTRAIT_MODE;
+  }
+  if (EXPOSURE_PROGRAM_LANDSCAPE_MODE == exposure_program) {
+    return EXIF_EXPOSURE_PROGRAM_LANDSCAPE_MODE;
+  }
+  return EXIF_EXPOSURE_PROGRAM_NOT_VALID;
+}
+
+const std::string& ExifUtil::exposureProgramToString(ExposureProgram value)
+{
+  LoggerD("Entered");
+  switch (value) {
+    case ExposureProgram::EXIF_EXPOSURE_PROGRAM_NOT_DEFINED:
+      return EXPOSURE_PROGRAM_NOT_DEFINED;
+    case ExposureProgram::EXIF_EXPOSURE_PROGRAM_MANUAL:
+      return EXPOSURE_PROGRAM_MANUAL;
+    case ExposureProgram::EXIF_EXPOSURE_PROGRAM_NORMAL:
+      return EXPOSURE_PROGRAM_NORMAL;
+    case ExposureProgram::EXIF_EXPOSURE_PROGRAM_APERTURE_PRIORITY:
+      return EXPOSURE_PROGRAM_APERTURE_PRIORITY;
+    case ExposureProgram::EXIF_EXPOSURE_PROGRAM_SHUTTER_PRIORITY:
+      return EXPOSURE_PROGRAM_SHUTTER_PRIORITY;
+    case ExposureProgram::EXIF_EXPOSURE_PROGRAM_CREATIVE_PROGRAM:
+      return EXPOSURE_PROGRAM_CREATIVE_PROGRAM;
+    case ExposureProgram::EXIF_EXPOSURE_PROGRAM_ACTION_PROGRAM:
+      return EXPOSURE_PROGRAM_ACTION_PROGRAM;
+    case ExposureProgram::EXIF_EXPOSURE_PROGRAM_PORTRAIT_MODE:
+      return EXPOSURE_PROGRAM_PORTRAIT_MODE;
+    case ExposureProgram::EXIF_EXPOSURE_PROGRAM_LANDSCAPE_MODE:
+      return EXPOSURE_PROGRAM_LANDSCAPE_MODE;
+    default:
+      return DUMMY;
+  }
+}
+
+bool ExifUtil::isValidAbsoluteURI(const std::string& uri)
+{
+  return 0 == uri.find(URI_ABSOLUTE_PREFIX);
+}
+
+void ExifUtil::getURIInfo(const std::string& uri,
+    //const Filesystem::NodeType expected_type,
+    const std::string& required_permission,
+    bool& out_exists,
+    //Filesystem::NodeType& out_type,
+    bool& out_permission_granted)
+{
+  const std::string absolute_path = ExifUtil::convertUriToPath(uri);
+  out_exists = false;
+  out_permission_granted = false;
+
+  try {
+    //Filesystem::PathPtr path = Filesystem::Path::create(absolute_path);
+    //Filesystem::NodePtr node = Filesystem::Node::resolve(path);
+    //out_type = node->getType();
+    //out_exists = true;
+
+    //if (expected_type == out_type) {
+    //  out_permission_granted = node->checkPermission(path, required_permission,
+    //      expected_type);
+    //}
+  }
+  /*catch (const common::BasePlatformException &err) {
+    LoggerE("Couldn't resolve path: %s, got:%s (%s)", absolute_path.c_str(),
+        (err.getName()).c_str(), (err.getMessage()).c_str());
+  }*/
+  catch(...) {
+    LoggerE("Couldn't resolve path: %s", absolute_path.c_str());
+  }
+}
+
+// Example:
+// in: uri = file:///opt/usr/media/Images/exif.jpg
+// out: path = /opt/usr/media/Images/exif.jpg
+std::string ExifUtil::convertUriToPath(const std::string& str)
+{
+  std::string path = ltrim(str);
+  std::string prefix = path.substr(0, URI_PREFIX.size());
+
+  if (prefix == URI_PREFIX) {
+    return path.substr(URI_PREFIX.size());
+  }
+  else {
+    return path;
+  }
+}
+
+std::string ExifUtil::ltrim(const std::string& s)
+{
+  std::string str = s;
+  std::string::iterator i;
+  for (i = str.begin(); i != str.end(); i++) {
+    if (!isspace(*i)) {
+      break;
+    }
+  }
+  if (i == str.end()) {
+    str.clear();
+  }
+  else {
+    str.erase(str.begin(), i);
+  }
+  return str;
+}
+
+time_t ExifUtil::exifDateTimeOriginalToTimeT(const char* string)
+{
+  int year, month, day, hour, min, sec;
+  if (sscanf(string, "%d:%d:%d %d:%d:%d",
+        &year, &month, &day, &hour, &min, &sec) >= 6) {
+    return convertToTimeT(year, month, day, hour, min, sec);
+  }
+
+  return 0;
+}
+
+std::string ExifUtil::timeTToExifDateTimeOriginal(time_t time)
+{
+  int year, month, day, hour, min, sec;
+  extractFromTimeT(time, year, month, day, hour, min, sec);
+
+  std::ostringstream ss;
+  ss << std::setfill('0') << std::setw(4) << year << ':' ;
+  ss << std::setfill('0') << std::setw(2) << month << ':' ;
+  ss << std::setfill('0') << std::setw(2) << day << ' ' ;
+
+  ss << std::setfill('0') << std::setw(2) << hour << ':' ;
+  ss << std::setfill('0') << std::setw(2) << min << ':' ;
+  ss << std::setfill('0') << std::setw(2) << sec;
+  return ss.str();
+}
+
+size_t  ExifUtil::getSizeOfExifFormatType(ExifFormat format)
+{
+  size_t size_per_member = 0;
+  switch (format) {
+    case EXIF_FORMAT_BYTE:
+      size_per_member = 1;
+      break;
+
+    case EXIF_FORMAT_SHORT:
+    case EXIF_FORMAT_SSHORT:
+      size_per_member = 2;
+      break;
+
+    case EXIF_FORMAT_LONG:
+    case EXIF_FORMAT_SLONG:
+      size_per_member = 4;
+      break;
+
+    case EXIF_FORMAT_RATIONAL:
+    case EXIF_FORMAT_SRATIONAL:
+      size_per_member = 8;
+      break;
+
+    default:
+      LoggerE("output ExifFormat: %d is not supported!");
+      return 0;
+  }
+
+  return size_per_member;
+}
+
+void ExifUtil::printExifEntryInfo(ExifEntry* entry, ExifData* exif_data)
+{
+  char buf[2000];
+  std::stringstream ss;
+
+  if (!entry) {
+    LoggerE("entry is null");
+    return;
+  }
+
+  if (!entry->data) {
+    LoggerE("entry data is null");
+    return;
+  }
+
+  unsigned char* read_buf_ptr = entry->data;
+
+  size_t size_per_member = getSizeOfExifFormatType(entry->format);
+  if (0 == size_per_member) {
+    size_per_member = 1;  //display as array of bytes
+  }
+
+  for(unsigned long compi = 0; compi < entry->components; ++compi) {
+
+    if (compi > 0) {
+      ss << " ";
+    }
+
+    for(size_t i = 0; i < size_per_member; ++i) {
+      unsigned int value = read_buf_ptr[i];
+      ss << std::hex << std::setw(2) << std::setfill('0') << value;
+    }
+
+    read_buf_ptr += size_per_member;
+  }
+
+  LoggerD("Entry{name:%s type:%s size:%d components:%d value:%s RAW DATA:[%s]}",
+      exif_tag_get_name(entry->tag),
+      exif_format_get_name(entry->format),
+      (int)entry->size,
+      (int)entry->components,
+      exif_entry_get_value(entry, buf, sizeof(buf)),
+      ss.str().c_str());
+}
+
+void ExifUtil::extractFromTimeT(const time_t time,
+      int& out_year, int& out_month, int& out_day,
+      int& out_hour, int& out_min, int& out_sec)
+{
+  struct tm* utc = gmtime(&time);
+
+  out_year = utc->tm_year + 1900;
+  out_month = utc->tm_mon + 1;
+  out_day = utc->tm_mday;
+  out_hour = utc->tm_hour;
+  out_min = utc->tm_min;
+  out_sec = utc->tm_sec;
+}
+
+time_t ExifUtil::convertToTimeT(int year, int month, int day,
+      int hour, int min, int sec)
+{
+  time_t tmp_time = 0;
+  struct tm* timeinfo = localtime(&tmp_time);
+  timeinfo->tm_year = year - 1900;
+  timeinfo->tm_mon = month - 1;
+  timeinfo->tm_mday = day;
+
+  timeinfo->tm_hour = hour;
+  timeinfo->tm_min = min;
+  timeinfo->tm_sec = sec;
+
+  //From mktime documentation:
+  //"The values of the members tm_wday and tm_yday of timeptr are ignored"
+  return timegm(timeinfo);
+}
+
+} // exif
+} // extension
diff --git a/src/exif/ExifUtil.h b/src/exif/ExifUtil.h
new file mode 100644 (file)
index 0000000..dfa0190
--- /dev/null
@@ -0,0 +1,153 @@
+//
+// Tizen Web Device API
+// Copyright (c) 2014 Samsung Electronics Co., Ltd.
+//
+// Licensed 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.
+//
+
+
+#ifndef __TIZEN_EXIF_EXIFUTIL_H_
+#define __TIZEN_EXIF_EXIFUTIL_H_
+
+#include <libexif/exif-data.h>
+#include <libexif/exif-entry.h>
+#include <libexif/exif-utils.h>
+#include <string>
+#include <vector>
+
+//#include <Node.h>
+//#include <Path.h>
+//#include <TZDate.h>
+
+//#include "Rational.h"
+
+namespace extension {
+namespace exif {
+
+enum ImageOrientation {
+  EXIF_ORIENTATION_NORMAL = 1,
+  EXIF_ORIENTATION_FLIP_HORIZONTAL = 2,
+  EXIF_ORIENTATION_ROTATE_180 = 3,
+  EXIF_ORIENTATION_FLIP_VERTICAL = 4,
+  EXIF_ORIENTATION_TRANSPOSE = 5,
+  EXIF_ORIENTATION_ROTATE_90 = 6,
+  EXIF_ORIENTATION_TRANSVERSE = 7,
+  EXIF_ORIENTATION_ROTATE_270 = 8,
+  EXIF_ORIENTATION_NOT_VALID,
+};
+
+enum WhiteBalanceMode {
+  EXIF_WHITE_BALANCE_MODE_AUTO = 0,
+  EXIF_WHITE_BALANCE_MODE_MANUAL = 1,
+  EXIF_WHITE_BALANCE_MODE_NOT_VALID
+};
+
+enum ExposureProgram {
+  EXIF_EXPOSURE_PROGRAM_NOT_DEFINED = 0,
+  EXIF_EXPOSURE_PROGRAM_MANUAL = 1,
+  EXIF_EXPOSURE_PROGRAM_NORMAL = 2,
+  EXIF_EXPOSURE_PROGRAM_APERTURE_PRIORITY = 3,
+  EXIF_EXPOSURE_PROGRAM_SHUTTER_PRIORITY = 4,
+  EXIF_EXPOSURE_PROGRAM_CREATIVE_PROGRAM = 5,
+  EXIF_EXPOSURE_PROGRAM_ACTION_PROGRAM = 6,
+  EXIF_EXPOSURE_PROGRAM_PORTRAIT_MODE = 7,
+  EXIF_EXPOSURE_PROGRAM_LANDSCAPE_MODE = 8,
+  EXIF_EXPOSURE_PROGRAM_NOT_VALID
+};
+
+/**
+ * From Exif 2.2 specification:
+ *  The following types are used in Exif:
+ *  1 = BYTE An 8-bit unsigned integer.,
+ *  2 = ASCII An 8-bit byte containing one 7-bit ASCII code. The final byte is terminated
+ *    with NULL.,
+ *  3 = SHORT A 16-bit (2-byte) unsigned integer,
+ *  4 = LONG A 32-bit (4-byte) unsigned integer,
+ *  5 = RATIONAL Two LONGs. The first LONG is the numerator and the second LONG expresses
+ *    the denominator.,
+ *  7 = UNDEFINED An 8-bit byte that can take any value depending on the field definition,
+ *  9 = SLONG A 32-bit (4-byte) signed integer (2's complement notation),
+ * 10 = SRATIONAL Two SLONGs. The first SLONG is the numerator and the second SLONG is the
+ *    denominator.
+ */
+struct ExifTypeInfo {
+
+  /**
+   * Number of bytes used by each exif type
+   */
+  static const size_t ByteSize;     //1 byte
+  static const size_t ASCIISize;    //1 byte (*N)
+  static const size_t ShortSize;    //2 bytes
+  static const size_t LongSize;     //4 bytes
+  static const size_t RationalSize;   //8 bytes
+  static const size_t UndefinedSize;  //1 byte (*N)
+  static const size_t SLongSize;    //4 bytes
+  static const size_t SRationalSize;  //8 bytes
+
+  /**
+   * Id values used by Exif to identify type
+   */
+  static const ExifByte ByteId;     // 1
+  static const ExifByte ASCIIId;    // 2
+  static const ExifByte ShortId;    // 3
+  static const ExifByte LongId;     // 4
+  static const ExifByte RationalId;   // 5
+  static const ExifByte UndefinedId;  // 7
+  static const ExifByte SLongId;    // 9
+  static const ExifByte SRationalId;  //10
+};
+
+class ExifUtil
+{
+public:
+  ExifUtil();
+  virtual ~ExifUtil();
+
+  static ImageOrientation stringToOrientation(const std::string& orientation);
+  static const std::string& orientationToString(ImageOrientation value);
+
+  static WhiteBalanceMode stringToWhiteBalance(const std::string& white_balance);
+  static const std::string& whiteBalanceToString(WhiteBalanceMode value);
+
+  static ExposureProgram stringToExposureProgram(const std::string& exposure_program);
+  static const std::string& exposureProgramToString(ExposureProgram value);
+
+  static bool isValidAbsoluteURI(const std::string& uri);
+  static void getURIInfo(const std::string& uri,
+      //const Filesystem::NodeType expected_type,
+      const std::string& required_permission,
+      bool& out_exists,
+      //Filesystem::NodeType& out_type,
+      bool& out_permission_granted);
+
+  static std::string convertUriToPath(const std::string& str);
+  static std::string ltrim(const std::string& s);
+
+  static time_t exifDateTimeOriginalToTimeT(const char* string);
+  static std::string timeTToExifDateTimeOriginal(time_t time);
+
+  static size_t getSizeOfExifFormatType(ExifFormat format);
+  static void  printExifEntryInfo(ExifEntry* entry, ExifData* exif_data);
+
+  static void extractFromTimeT(const time_t time,
+      int& out_year, int& out_month, int& out_day,
+      int& out_hour, int& out_min, int& out_sec);
+
+  static time_t convertToTimeT(int year, int month, int day,
+      int hour, int min, int sec);
+};
+
+} // exif
+} // extension
+
+#endif // __TIZEN_EXIF_EXIFUTIL_H_
diff --git a/src/exif/JpegFile.cpp b/src/exif/JpegFile.cpp
new file mode 100644 (file)
index 0000000..8542dff
--- /dev/null
@@ -0,0 +1,729 @@
+//
+// Tizen Web Device API
+// Copyright (c) 2014 Samsung Electronics Co., Ltd.
+//
+// Licensed 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.
+//
+
+//
+// For details of JPEG file format see:
+// http://www.media.mit.edu/pia/Research/deepview/exif.html
+
+#include "JpegFile.h"
+
+#include <iomanip>
+#include <limits>
+#include <stdio.h>
+#include <sstream>
+
+#include "common/platform_exception.h"
+#include "common/logger.h"
+
+namespace extension {
+namespace exif {
+
+/**
+ * Size of maximal JPEG's section data length
+ * (since it is stored as unsigned short limit is 2^16 -1)
+ */
+const unsigned int MAX_JPEG_SECTION_DATA_SIZE = 65535;
+
+/**
+ * JPEG's section data length includes 2 bytes for length therefore we need to
+ * substract 2 from MAX_JPEG_SECTION_DATA_SIZE
+ */
+const unsigned int MAX_AVAILABLE_JPEG_SECTION_DATA_SIZE = MAX_JPEG_SECTION_DATA_SIZE - 2;
+
+bool isJpegMarker(const int value)
+{
+  return value >= JPEG_MARKER_LOWEST_ID && value <= JPEG_MARKER_HIGHEST_ID;
+}
+
+JpegMarker castToJpegMarker(const unsigned char byte)
+{
+  if (byte < JPEG_MARKER_LOWEST_ID || byte > JPEG_MARKER_HIGHEST_ID) {
+    return JPEG_MARKER_UNKNOWN;
+  }
+
+  return static_cast<JpegMarker>(byte);
+}
+
+long readUShortBE(unsigned char* src)
+{
+  return ((static_cast<long>(src[0]) << 8) | static_cast<long>(src[1]));
+}
+
+void writeUShortBE(unsigned short value, unsigned char* buffer)
+{
+  buffer[0] = static_cast<unsigned char>(value >> 8);
+  buffer[1] = static_cast<unsigned char>(value);
+}
+
+struct CArrayDeleter {
+  void operator()(void* buffer) { free(buffer); }
+};
+
+JpegFile::JpegFile() :
+  m_in_data(NULL),
+  m_in_data_size(0),
+  m_image_data(NULL),
+  m_image_size(0),
+  m_padding_data(NULL),
+  m_padding_data_size(0),
+  m_in_file(NULL),
+  m_out_file(NULL)
+{
+
+}
+
+JpegFile::~JpegFile()
+{
+  delete [] m_in_data;
+  m_in_data = NULL;
+  m_in_data_size = 0;
+
+  m_padding_data = NULL;
+  m_padding_data_size = 0;
+
+  for(SectionsVec::iterator it = m_sections.begin(); it != m_sections.end(); ++it) {
+    JpegFileSectionPtr cur = *it;
+
+    if (cur->exif_data) {
+      exif_data_unref(cur->exif_data);
+      cur->exif_data = NULL;
+    }
+
+    cur->data_ptr = NULL;
+    cur->size = 0;
+    cur->type = JPEG_MARKER_UNKNOWN;
+  }
+
+  m_image_data = NULL;
+  m_image_size = 0;
+
+  if (m_in_file) {
+    fclose(m_in_file);
+    m_in_file = NULL;
+  }
+
+  if (m_out_file) {
+    fclose(m_out_file);
+    m_out_file = NULL;
+  }
+}
+
+JpegFilePtr JpegFile::loadFile(const std::string& path)
+{
+  JpegFile* new_jpg = new (std::nothrow) JpegFile();
+  if (!new_jpg) {
+    LoggerE("Couldn't allocate Jpegfile!");
+    throw common::UnknownException("Memory allocation failed");
+  }
+
+  JpegFilePtr jpg_ptr(new_jpg);
+  jpg_ptr->load(path);
+  return jpg_ptr;
+}
+
+void JpegFile::load(const std::string& path)
+{
+  LoggerD("Entered file:%s", path.c_str());
+
+  m_source_file_path = path;
+
+  m_in_file = fopen(path.c_str(), "rb");
+  if (!m_in_file) {
+    LoggerE("Couldn't open Jpeg file: [%s]", path.c_str());
+    throw common::NotFoundException("Could not open JPG file");
+  }
+
+  fseek(m_in_file, 0, SEEK_END);
+  const size_t in_file_size = static_cast<size_t>(ftell(m_in_file));
+  fseek(m_in_file, 0, SEEK_SET);
+  LoggerD("JPEG file: [%s] size:%d", path.c_str(), in_file_size);
+  if (0 == in_file_size) {
+    LoggerE("Input file [%s] is empty!", path.c_str());
+    throw common::UnknownException("JPEG file is invalid");
+  }
+
+  m_in_data = new (std::nothrow) unsigned char[in_file_size];
+  if (!m_in_data) {
+    LoggerE("Couldn't allocate buffer with size: %d", in_file_size);
+    throw common::UnknownException("Memory allocation failed");
+  }
+
+  m_in_data_size = in_file_size;
+
+  const size_t read_bytes = fread(m_in_data, 1, m_in_data_size, m_in_file);
+  if (read_bytes != m_in_data_size) {
+    LoggerE("Couldn't read all: %d bytes. Read only: %d bytes!", m_in_data_size,
+        read_bytes);
+    throw common::UnknownException("Could not read JPEG file");
+  }
+
+  if (fclose(m_in_file) == EOF) {
+    LoggerE("Couldn't close input file: %s!", path.c_str());
+  }
+  m_in_file = NULL;
+
+  generateListOfSections();
+}
+
+std::string JpegFile::getPartOfFile(const size_t offset,
+    const size_t num_bytes_before,
+    const size_t num_bytes_after)
+{
+  long long int start = static_cast<long long int>(offset) - num_bytes_before;
+  if (start < 0) {
+    start = 0;
+  }
+
+  long long int end = static_cast<long long int>(offset) + num_bytes_after;
+  if (end >= m_in_data_size) {
+    end = m_in_data_size - 1;
+  }
+
+  std::stringstream ss;
+  ss << std::setfill('0') << std::setw(2) << std::hex;
+  for(long long int i = start; i <= end; ++i) {
+    ss << static_cast<int>(m_in_data[i]);
+  }
+  return ss.str();
+}
+
+
+void JpegFile::generateListOfSections()
+{
+  LoggerD("Entered");
+
+  //JPEG starts with:
+  //FFD8 (2 bytes) - SOI Marker
+  //
+  //then:
+  //N sections - format of section:
+  //0xFF(1 byte) + Marker Number(1 byte) + Data size(2 bytes) + Data
+  //
+  //then:
+  //SOS 0xFF(1 byte) + Marker Number(1 byte) + Data size(2 bytes) + Data
+  //
+  //Image data
+  //
+  //FFD9 (2 bytes) - EOI Marker
+  //
+  //Warning: some images taken on Android contains some extra data at the end
+  //we will keep it in m_padding_data
+
+  m_padding_data = NULL;
+  m_padding_data_size = 0;
+
+  for(size_t offset = 0, iterration = 0; offset < m_in_data_size;++iterration) {
+
+    LoggerD("offset:%d | Starting iteration: %d", offset, iterration);
+    const size_t search_len = 10;
+    size_t search_offset = 0;
+    for(search_offset = 0; search_offset < search_len; ++search_offset) {
+      //Skip bytes until first no 0xff
+      unsigned char& tmp_marker = m_in_data[offset + search_offset];
+      if (tmp_marker != 0xff) {
+        break;
+      }
+    }
+
+    if (search_len == search_offset) {
+      LoggerE("offset:%d | Couldn't find marker! RAW DATA:{%s}", offset,
+          getPartOfFile(offset, 0, 10).c_str());
+      throw common::UnknownException("JPEG file is invalid");
+    }
+
+    const size_t section_offset = offset + search_offset - 1;
+    unsigned char* section_begin = m_in_data + section_offset;
+
+    offset = section_offset;  //Move to section begin
+    LoggerD("offset:%d | Moved to section begin", offset);
+
+    if (!isJpegMarker(section_begin[1])) {
+      LoggerE("offset:%d | Is not valid marker: 0x%x RAW DATA:{%s}", offset,
+          section_begin[1], getPartOfFile(section_offset,0,4).c_str());
+      throw common::UnknownException("JPEG file is invalid");
+    }
+
+    const JpegMarker cur_marker = castToJpegMarker(section_begin[1]);
+    LoggerD("offset:%d | Found valid marker: 0x%x RAW DATA:{%s}", offset,
+        cur_marker,
+        getPartOfFile(section_offset,0,4).c_str());
+
+    offset += 2;  //Read 0xffxx marker tag - 2 bytes
+
+    JpegFileSectionPtr section;
+    {
+      JpegFileSection* sec = new (std::nothrow) JpegFileSection();
+      if (!sec) {
+        LoggerE("Couldn't allocate JpegFileSection");
+        throw common::UnknownException("Memory allocation failed");
+      }
+
+      section = JpegFileSectionPtr(sec);
+    }
+
+    section->type = cur_marker;
+    m_sections.push_back(section);
+    if (cur_marker == JPEG_MARKER_SOI ||
+      cur_marker == JPEG_MARKER_EOI) {
+      LoggerD("offset:%d | Found: %s marker, moving to next marker at:%d",
+          section_offset, ((cur_marker == JPEG_MARKER_SOI) ? "SOI" : "EOI"),
+          offset);
+
+      if (cur_marker == JPEG_MARKER_EOI && m_padding_data != NULL) {
+        LoggerW("Padding data have been found - do not try to parse end of file");
+        break;
+      }
+    }
+    else {
+      //From JPEG/EXIF info:
+      // Please notice that "Data" contains Data size descriptor, if there is
+      // a Marker like this;
+      //
+      // FF C1 00 0C
+      // It means this Marker(0xFFC1) has 0x000C(equal 12)bytes of data. But the
+      // data size '12' includes "Data size" descriptor, it follows only 10 bytes of
+      // data after 0x000C.
+      //
+
+      const long total_section_len = readUShortBE(section_begin + 2); //Include data
+                                      //size 2 bytes
+
+      const long section_data_len = total_section_len - 2;      //Exclude data
+                                      //size 2 bytes
+
+      LoggerD("offset:%d tag:0x%x | Read total_section_len:%d (data len:%d)",
+          section_offset, cur_marker, total_section_len, section_data_len);
+
+      offset += 2;  //Read data size - 2 bytes
+
+      if (total_section_len < 0) {
+        LoggerE("offset:%d tag:0x%x | Error: total_section_len is: %d < 0", offset,
+            cur_marker, total_section_len);
+        throw common::UnknownException("JPEG file is invalid");
+      }
+
+      if (section_offset + 2 + total_section_len > m_in_data_size) {
+        LoggerE("offset:%d tag:0x%x | Error: current section offset:%d"
+            " + 2 + total_section_len:%d = %d is greater then file size:%d",
+            offset, cur_marker,
+            section_offset, total_section_len,
+            section_offset + total_section_len, m_in_data_size);
+        throw common::UnknownException("JPEG file is invalid");
+      }
+
+      if (JPEG_MARKER_APP1 == cur_marker) {
+        //TODO: verify this
+        //-4 --> 0xFF(1 byte)+Marker Number(1 byte)+Data size(2 bytes))
+        //const unsigned int exif_data_size = section_length - 4;
+
+        const unsigned int exif_data_size = total_section_len + 2;
+        section->exif_data = exif_data_new_from_data (section_begin,
+            exif_data_size);
+
+        LoggerD("offset:%d tag:0x%x | Loading exif from offset:%d"
+            " len:%d exif_data_new_from_data returned: %p",
+            offset, cur_marker, section_offset, exif_data_size,
+            section->exif_data);
+
+        if (!section->exif_data) {
+          LoggerW("offset:%d tag:0x%x | Couldn't load Exif!", offset, cur_marker);
+        }
+      }
+
+      //This just saves pointer not copying data
+      section->data_ptr = section_begin + 2 + 2; //2 bytes marker + 2 bytes data size
+      section->size = section_data_len;  //Exclude data size
+
+      if (JPEG_MARKER_SOS == cur_marker) {
+        //Calculate offset of first image data which is just after this SOS section
+        const size_t image_data_offset = section_offset + 2 + total_section_len;
+
+        //Calculate size of image data from start to expected EOI at end of file.
+        //
+        //-2 (exclude ending EOI marker (2 bytes)
+        size_t image_size = m_in_data_size - image_data_offset - 2;
+        LoggerW("offset:%d tag:0x%x | Image data offset:%d Estimated image size:%d",
+            offset, cur_marker, image_data_offset, image_size);
+
+        m_image_data = m_in_data + image_data_offset;
+
+        size_t eoi_tag_index = 0;
+        bool found_eoi_tag = searchForTagInBuffer(m_in_data + image_data_offset,
+            m_in_data + m_in_data_size, JPEG_MARKER_EOI, eoi_tag_index);
+        if (!found_eoi_tag) {
+          LoggerE("Could not find EOI tag! Assume that there is no EOI and rest of "
+              "JPEG file contains image data stream: image_size+= 2");
+          image_size += 2; //Skip expected EOI tag which is not present
+        } else {
+          LoggerD("EOI tag found at offset: %d from SOS data", eoi_tag_index);
+
+          if(eoi_tag_index != image_size) {
+            LoggerW("Estimated image size:%d doesn't match EOI tag index:%d"
+                " delta:%d", image_size, eoi_tag_index,
+                image_size - eoi_tag_index);
+
+            LoggerW("Setting image_size to EOI tag: %d", eoi_tag_index);
+            image_size = eoi_tag_index;
+
+            m_padding_data = m_image_data + image_size + 2; //(skip EOI tag)
+            m_padding_data_size = (m_in_data + m_in_data_size) - m_padding_data;
+            LoggerW("Saving padding data from offset:%d with size:%d",
+              m_padding_data - m_in_data, m_padding_data_size);
+          }
+        }
+
+        m_image_size = image_size;
+
+        offset = image_data_offset + image_size;
+        LoggerD("offset:%d tag:0x%x | SOS Offset moved to next marker", offset,
+            cur_marker);
+      }
+      else {
+        offset += section_data_len;
+        LoggerD("offset:%d tag:0x%x | Offset moved to next marker", offset, cur_marker);
+      }
+    }
+  }
+}
+
+bool JpegFile::searchForTagInBuffer(const unsigned char* buffer_start,
+    const unsigned char* buffer_end,
+    const JpegMarker marker,
+    size_t& out_index)
+{
+  LoggerD("Entered start:%p end:%p marker:0x%x", buffer_start, buffer_end, marker);
+
+  if(!buffer_start) {
+    LoggerE("buffer_start is NULL");
+    return false;
+  }
+
+  if(!buffer_end) {
+    LoggerE("buffer_end is NULL");
+    return false;
+  }
+
+  if(buffer_end <= buffer_start) {
+    LoggerE("buffer_end: %p <= buffer_start: %p", buffer_end, buffer_start);
+    return false;
+  }
+
+  LoggerD("Bytes to scan: %d", static_cast<size_t>(buffer_end - buffer_start));
+  const unsigned char marker_uchar = static_cast<unsigned char>(marker);
+
+  for(const unsigned char* ptr = buffer_start; ptr < buffer_end; ++ptr) {
+
+    if((0xff == *ptr) && (ptr+1 < buffer_end)) {
+      if(marker_uchar == *(ptr+1)) {
+        out_index = static_cast<size_t>(ptr - buffer_start);
+        return true;
+      }
+    }
+  }
+
+  out_index = 0;
+  return false;
+}
+
+void JpegFile::setNewExifData(ExifData* new_exif_data)
+{
+  if (!new_exif_data) {
+    LoggerE("Trying to set NULL exif_data!");
+    throw common::UnknownException("Could not save Exif in JPEG file");
+  }
+
+  JpegFileSectionPtr exif = getExifSection();
+  if (!exif) {
+    LoggerW("Could't find Exif section - creating new one");
+    {
+      JpegFileSection* new_sec = new (std::nothrow) JpegFileSection();
+      if (!new_sec) {
+        LoggerE("Couldn't allocate JpegFileSection");
+        throw common::UnknownException("Memory allocation failed");
+      }
+      new_sec->type = JPEG_MARKER_APP1;
+
+      exif = JpegFileSectionPtr(new_sec);
+    }
+
+    SectionsVec::iterator insert_it = m_sections.begin();
+    bool soi_is_present = false;
+
+    if (insert_it != m_sections.end()) {
+      if ((*insert_it)->type != JPEG_MARKER_SOI) {
+        LoggerW("First section is not SOI - Start Of Image!");
+      }
+      else {
+        soi_is_present = true;
+      }
+    }
+
+    if (!soi_is_present) {
+      LoggerW("SOI section is missing");
+      throw common::UnknownException("JPEG file is invalid");
+    }
+
+    //Insert new Exif sections just after SOI
+    ++insert_it;
+    if (insert_it != m_sections.begin()) {
+      m_sections.insert(insert_it, exif);
+    }
+    else {
+      //This shouldn't happen since we at lest need SOS and EOI sections
+      m_sections.push_back(exif);
+    }
+  }
+
+  //We don't want to save old data
+  exif->data_ptr = NULL;
+  exif->size = 0;
+
+  exif_data_unref(exif->exif_data);
+  exif_data_ref (new_exif_data);
+  exif->exif_data = new_exif_data;
+}
+
+ExifData* JpegFile::getExifData()
+{
+  JpegFileSectionPtr exif = getExifSection();
+  if (!exif) {
+    return NULL;
+  }
+
+  exif_data_ref(exif->exif_data);
+  return exif->exif_data;
+}
+
+void JpegFile::saveToFile(const std::string& out_path)
+{
+  LoggerD("Entered out_path:%s", out_path.c_str());
+  try {
+    saveToFilePriv(out_path);
+  }
+  catch (...) {
+    LoggerE("Exception occured during saveToFilePriv "
+        "original file: [%] new: [%s]",
+        m_source_file_path.c_str(),
+        out_path.c_str());
+
+    if (out_path == m_source_file_path) {
+
+      LoggerD("Trying to recover broken JPEG file: [%s]", out_path.c_str());
+      //We were writing to source file and since something went wrong let's
+      //restore old file - we have it in m_in_data
+
+      FILE* outf = fopen(out_path.c_str(), "wb");
+      if (!outf) {
+        LoggerE("Couldn't open output file: [%s] - JPEG file will not be restored!");
+      }
+      else {
+        size_t bytes_wrote = fwrite(m_in_data, 1, m_in_data_size, outf);
+        if (bytes_wrote != m_in_data_size) {
+          LoggerE("Couldn't restore whole JPEG! "
+              "Only %d of %d bytes have been wrote!",
+              bytes_wrote, m_in_data_size);
+        }
+        if (EOF == fclose(outf)) {
+          LoggerE("Couldn't close restore output file: [%s]", out_path.c_str());
+        }
+      }
+    }
+
+    throw;
+  }
+}
+
+void JpegFile::saveToFilePriv(const std::string& out_path)
+{
+  LoggerD("Entered out_path:%s", out_path.c_str());
+
+  m_out_file = fopen(out_path.c_str(), "wb");
+  if (!m_out_file) {
+    LoggerE("Couldn't open output file: %s", out_path.c_str());
+    throw common::UnknownException("Could not write JPEG file");
+  }
+
+  unsigned char tmp_buf[128];
+  size_t offset = 0;
+
+  int section_index = 0;
+  for(SectionsVec::iterator it = m_sections.begin();
+      it != m_sections.end();
+      ++it, ++ section_index) {
+
+    JpegFileSectionPtr cur = *it;
+    const JpegMarker cur_marker = cur->type;
+
+    LoggerD("offset:%d | Section: %d marker 0x%x", offset, section_index, cur_marker);
+
+    size_t bytes_to_write = 0;
+    size_t bytes_wrote = 0;
+
+    tmp_buf[0] = 0xff;
+    tmp_buf[1] = cur_marker;
+    bytes_to_write += 2;
+
+    bool write_section_data = false;
+
+    bool write_exif_data = false;
+
+    std::unique_ptr<unsigned char, CArrayDeleter> exif_output_data;
+    unsigned int exif_output_size = 0;
+
+    if (cur_marker != JPEG_MARKER_SOI &&
+        cur_marker != JPEG_MARKER_EOI) {
+
+      unsigned short section_size = 2;
+      if (JPEG_MARKER_APP1 && cur->exif_data) {
+
+        unsigned char* tmp = NULL;
+        exif_data_save_data (cur->exif_data, &tmp, &exif_output_size);
+        if (!tmp || 0 == exif_output_size) {
+          LoggerE("Couldn't generate RAW Exif data!");
+          throw common::UnknownException("Could not save Exif in JPEG file");
+        }
+
+        LoggerD("offset:%d | Generated Exif RAW Data length:%d", offset,
+            exif_output_size);
+
+        exif_output_data.reset(tmp);
+
+        if (exif_output_size > MAX_AVAILABLE_JPEG_SECTION_DATA_SIZE) {
+          LoggerE("exif_output_size:%d is greater then maximum JPEG section"
+              "data block size: %d", exif_output_size,
+              MAX_AVAILABLE_JPEG_SECTION_DATA_SIZE);
+          throw common::UnknownException("Exif data is to big to be saved in JPEG file");
+        }
+        section_size += exif_output_size;
+        write_exif_data = true;
+      }
+      else {
+        section_size += cur->size;
+        write_section_data = true;
+      }
+
+      writeUShortBE(section_size, tmp_buf + bytes_to_write);
+      bytes_to_write += 2;
+    }
+
+    LoggerD("offset:%d | Writing section: marker:0x%x size:%d", offset, cur_marker,
+        cur->size);
+
+    bytes_wrote = fwrite(tmp_buf, 1, bytes_to_write, m_out_file);
+    offset += bytes_wrote;
+
+    if (bytes_wrote != bytes_to_write) {
+      LoggerE("Couldn't wrote %d bytes! Only %d bytes wrote", bytes_to_write,
+          bytes_wrote);
+      throw common::UnknownException("Could not write JPEG file");
+    }
+
+    if (write_section_data && cur->size > 0) {
+      LoggerD("offset:%d | Writing data with length:%d", offset, cur->size);
+
+      bytes_to_write = cur->size;
+      bytes_wrote = fwrite(cur->data_ptr, 1, bytes_to_write, m_out_file);
+      offset += bytes_wrote;
+
+      if (bytes_wrote != bytes_to_write) {
+        LoggerE("Couldn't wrote %d bytes! Only %d bytes wrote", bytes_to_write,
+            bytes_wrote);
+        throw common::UnknownException("Could not write JPEG file");
+      }
+    }
+
+    if (write_exif_data && exif_output_data && exif_output_size > 0) {
+      LoggerD("offset:%d | Writing new exif data with length:%d", offset,
+          exif_output_size);
+
+      bytes_to_write = exif_output_size;
+      bytes_wrote = fwrite(exif_output_data.get(), 1, bytes_to_write, m_out_file);
+      offset += bytes_wrote;
+
+      if (bytes_wrote != bytes_to_write) {
+        LoggerE("Couldn't wrote %d bytes! Only %d bytes wrote", bytes_to_write,
+            bytes_wrote);
+        throw common::UnknownException("Could not write JPEG file");
+      }
+    }
+
+    if (JPEG_MARKER_SOS == cur_marker) {
+      LoggerD("offset:%d | Writing image data stream with lenght:%d", offset,
+          m_image_size);
+
+      bytes_to_write = m_image_size;
+      bytes_wrote = fwrite(m_image_data, 1, bytes_to_write, m_out_file);
+      offset += bytes_wrote;
+
+      if (bytes_wrote != bytes_to_write) {
+        LoggerE("Couldn't wrote %d bytes! Only %d bytes wrote", bytes_to_write,
+            bytes_wrote);
+        throw common::UnknownException("Could not write JPEG file");
+      }
+    }
+  }
+
+  if (m_padding_data && m_padding_data_size > 0) {
+    LoggerD("Padding data exists and contains:%d bytes saving to JPEG file");
+    const size_t bytes_wrote = fwrite(m_image_data, 1, m_padding_data_size,
+        m_out_file);
+
+    if (bytes_wrote != m_padding_data_size) {
+      LoggerE("Couldn't wrote %d bytes! Only %d bytes wrote", m_padding_data_size,
+          bytes_wrote);
+      throw common::UnknownException("Could not write JPEG file");
+    }
+  }
+
+  if (fclose(m_out_file) == EOF) {
+    LoggerE("Couldn't close output file: %s", out_path.c_str());
+    m_out_file = NULL;
+  }  else {
+    m_out_file = NULL;
+    LoggerD("Closed output file: %s wrote:%d bytes: %d", out_path.c_str(), offset);
+  }
+}
+
+JpegFileSectionPtr JpegFile::getExifSection()
+{
+  size_t num_exif_sections = 0;
+  JpegFileSectionPtr first_exif_section;
+
+  for (SectionsVec::iterator it = m_sections.begin(); it != m_sections.end(); ++it) {
+    JpegFileSectionPtr cur = *it;
+
+    if (JPEG_MARKER_APP1 == cur->type) {
+      if (!cur->exif_data) {
+        LoggerW("Warning: found APP1 section but exif_data is NULL (Not Exif?)");
+        continue;
+      }
+
+      ++num_exif_sections;
+      if (!first_exif_section) {
+        first_exif_section = cur;
+      }
+      else {
+        LoggerW("Warning: found %d APP1/Exif sections - only first is currently supported!");
+      }
+    }
+  }
+
+  return first_exif_section;
+}
+
+} // namespace exif
+} // namespace extension
diff --git a/src/exif/JpegFile.h b/src/exif/JpegFile.h
new file mode 100644 (file)
index 0000000..4eb2b1f
--- /dev/null
@@ -0,0 +1,138 @@
+//
+// Tizen Web Device API
+// Copyright (c) 2014 Samsung Electronics Co., Ltd.
+//
+// Licensed 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.
+//
+
+
+#ifndef __TIZEN_EXIF_JPEG_FILE_H_
+#define __TIZEN_EXIF_JPEG_FILE_H_
+
+#include <memory>
+#include <string>
+#include <vector>
+#include <stdio.h>
+#include <map>
+#include <libexif/exif-data.h>
+#include <libexif/exif-entry.h>
+#include <libexif/exif-utils.h>
+
+namespace extension {
+namespace exif {
+
+enum JpegMarker{
+  JPEG_MARKER_UNKNOWN   = 0x00,
+  JPEG_MARKER_LOWEST_ID   = 0xc0,
+  JPEG_MARKER_SOI     = 0xd8, //Start Of Image
+  JPEG_MARKER_EOI     = 0xd9, //End Of Image
+  JPEG_MARKER_SOS     = 0xda, //Start Of Stream
+  JPEG_MARKER_APP1    = 0xe1, //Application Data 1 - for Exif
+  JPEG_MARKER_HIGHEST_ID  = 0xfe
+};
+
+struct JpegFileSection;
+typedef std::shared_ptr<JpegFileSection> JpegFileSectionPtr;
+
+struct JpegFileSection
+{
+  JpegFileSection() :
+    type(JPEG_MARKER_UNKNOWN),
+    data_ptr(NULL),
+    size(0),
+    exif_data(NULL) {};
+
+  JpegMarker type;
+  unsigned char* data_ptr;
+  unsigned short size;
+
+  ExifData* exif_data;
+};
+
+
+class JpegFile;
+typedef std::shared_ptr<JpegFile> JpegFilePtr;
+
+class JpegFile {
+public:
+  static JpegFilePtr loadFile(const std::string& path);
+  ~JpegFile();
+
+  void setNewExifData(ExifData* new_exif_data);
+
+  /**
+   * You are responsible to unreference returned data with: exif_data_unref(...)
+   * Example:
+   *   ExifData* ed = jpeg.getExifData();
+   *   if(ed) {
+   *     doSth(ed);
+   *     exif_data_unref(ed);
+   *   }
+   */
+  ExifData* getExifData();
+
+  void saveToFile(const std::string& out_path);
+
+private:
+  JpegFile();
+  void load(const std::string& path);
+  void generateListOfSections();
+
+  std::string getPartOfFile(const size_t offset,
+      const size_t num_bytes_before = 10,
+      const size_t num_bytes_after = 10);
+
+  JpegFileSectionPtr getExifSection();
+  void saveToFilePriv(const std::string& out_path);
+
+  /**
+   * Search for first occurence of specific tag inside buffer.
+   *
+   * buffer_end is the first byte that should not be checked:
+   * [buffer_start ... buffer_end)
+   *
+   * For example EOI - search for first 'ffd9' in buffer
+   */
+  static bool searchForTagInBuffer(const unsigned char* buffer_start,
+      const unsigned char* buffer_end,
+      const JpegMarker marker,
+      size_t& out_index);
+
+  std::string m_source_file_path;
+
+  unsigned char* m_in_data;
+  size_t m_in_data_size;
+
+  unsigned char* m_image_data;
+  size_t m_image_size;
+
+  /**
+   * This contains any bytes after EOI.
+   * Usually there should be no extra bytes after EOI unfortunately
+   * some cameras saves extra bytes (for example Android).
+   */
+  unsigned char* m_padding_data;
+  size_t m_padding_data_size;
+
+  FILE* m_in_file;
+  FILE* m_out_file;
+
+  typedef std::vector<JpegFileSectionPtr> SectionsVec;
+  SectionsVec m_sections;
+};
+
+
+} // namespace exif
+} // namespace extension
+
+#endif // __TIZEN_EXIF_JPEG_FILE_H_
diff --git a/src/exif/Rational.cpp b/src/exif/Rational.cpp
new file mode 100644 (file)
index 0000000..bde7a09
--- /dev/null
@@ -0,0 +1,275 @@
+//
+// Tizen Web Device API
+// Copyright (c) 2014 Samsung Electronics Co., Ltd.
+//
+// Licensed 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.
+//
+
+#include "Rational.h"
+
+#include "math.h"
+
+#include "common/platform_exception.h"
+#include "common/logger.h"
+
+#include <sstream>
+
+namespace extension {
+namespace exif {
+
+namespace {
+const double DOUBLE_ERROR_REPRESENTATION = static_cast<double>(0x7FFFFFFF);
+} //anonymous namespace
+
+Rational::Rational() :
+    nominator(0),
+    denominator(0)
+{
+}
+
+Rational::Rational(ExifLong nom, ExifLong denom) :
+    nominator(nom),
+    denominator(denom)
+{
+}
+
+Rational::Rational(const ExifRational& exif_rational) :
+    nominator(exif_rational.numerator),
+    denominator(exif_rational.denominator)
+{
+}
+
+Rational Rational::createFromDouble(const double value, const long precision)
+{
+  LoggerD("Entered value:%f precision:%d", value, precision);
+  if (value < 0.0) {
+    LoggerW("Trying to create negative Rational: %f!", value);
+    return Rational();
+  }
+
+  if (value < 0.000000001) {
+    LoggerD("Skipping calculation returning: Rational(0,1)");
+    return Rational(0,1);
+  }
+
+  long m[2][2];
+  double x, startx;
+  long ai;
+
+  startx = x = value;
+
+  // initialize matrix
+  m[0][0] = m[1][1] = 1;
+  m[0][1] = m[1][0] = 0;
+
+  //loop finding terms until daemon gets too big
+  do {
+    ai = static_cast<long>(x);
+    if(m[1][0] * ai + m[1][1] > precision) {
+      break;
+    }
+
+    long t = m[0][0] * ai + m[0][1];
+    m[0][1] = m[0][0];
+    m[0][0] = t;
+
+    t = m[1][0] * ai + m[1][1];
+    m[1][1] = m[1][0];
+    m[1][0] = t;
+
+    if (x == static_cast<double>(ai)) {
+      break;   // AF: division by zero
+    }
+
+    x = 1 / (x - static_cast<double>(ai));
+    if (x > DOUBLE_ERROR_REPRESENTATION) {
+      break;  // AF: representation failure
+    }
+  } while(1);
+
+  // now remaining x is between 0 and 1/ai
+  // approx as either 0 or 1/m where m is max that will fit in precision
+  // first try zero
+  const double error0 = startx - ((double) m[0][0] / (double) m[1][0]);
+  const long numerator0 = m[0][0];
+  const long denominator0 = m[1][0];
+
+  LoggerD("%ld/%ld, error = %e\n", numerator0, denominator0, error0);
+
+  /* now try other possibility */
+  ai = (precision - m[1][1]) / m[1][0];
+  m[0][0] = m[0][0] * ai + m[0][1];
+  m[1][0] = m[1][0] * ai + m[1][1];
+
+  double error1m = startx -
+      (static_cast<double>(m[0][0]) / static_cast<double>(m[1][0]));
+  LoggerD("%ld/%ld, error = %e\n", m[0][0], m[1][0], error1m );
+
+  long result_numerator = 0;
+  long result_denominator = 0;
+
+  if (error0 < error1m ) {
+    result_numerator = numerator0;
+    result_denominator = denominator0;
+  }
+  else {
+    result_numerator = m[0][0];
+    result_denominator = m[1][0];
+  }
+
+  if (result_numerator < 0) {
+    result_numerator *= -1;
+  }
+  if (result_denominator < 0) {
+    result_denominator *= -1;
+  }
+
+  LoggerD("Rational(%d, %d) error0 < error1m:%d", result_numerator, result_denominator,
+      error0 < error1m);
+
+  return Rational(numerator0, denominator0);
+}
+
+Rational Rational::createInvalid()
+{
+  return Rational(0,0);
+}
+
+bool Rational::isValid() const
+{
+  if (0 == denominator) {
+    return false;
+  }
+  else {
+    return true;
+  }
+}
+
+double Rational::toDouble() const
+{
+  if (!isValid()) {
+    return NAN;
+  }
+
+  return (double)nominator / (double)denominator;
+}
+
+Rational Rational::createFromExposureTimeString(const std::string& exp_time)
+{
+  LoggerD("Entered");
+  if (exp_time.length() == 0) {
+    return Rational::createInvalid();  //lets assume that empty string means 0,
+                       //however exposure time = 0 is not valid value
+  }
+
+  std::string integer_part;
+  std::string fraction_part;
+
+  int first_space_at = -1;
+  int first_slash_at = -1;
+
+  for(size_t i=0; i < exp_time.size(); ++i) {
+
+    const char& cur = exp_time[i];
+    if (first_space_at < 0 && ' ' == cur) {
+      first_space_at = i;
+    }
+    if (first_slash_at < 0 && '/' == cur) {
+      first_slash_at = i;
+    }
+  }
+
+  if (first_slash_at > 0) {
+    if (first_space_at > 0) {
+      integer_part = exp_time.substr(0,first_space_at);
+      fraction_part = exp_time.substr(first_space_at+1,
+          exp_time.size() - (first_space_at+1));
+    }
+    else {
+      fraction_part = exp_time;
+    }
+  }
+  else {
+    integer_part = exp_time;
+  }
+
+  LoggerD("first_space_at: %d first_slash_at:%d int: [%s] , frac: [%s]",
+      first_space_at, first_slash_at, integer_part.c_str(), fraction_part.c_str());
+
+  long integer_value = 0;
+  long nominator = 0;
+  long denominator = 1;
+
+  if (integer_part.length() > 0) {
+    integer_value = atol(integer_part.c_str());
+  }
+
+  if (fraction_part.length() > 0) {
+    if (sscanf(fraction_part.c_str(), "%ld/%ld", &nominator, &denominator) != 2) {
+      LoggerD("Failed to parse nominator/denominator string: [%s]",
+          fraction_part.c_str());
+      return Rational::createInvalid();
+    }
+  }
+
+  nominator += denominator * integer_value;
+  LoggerD("%d/%d -> %f", nominator, denominator, (float)nominator / denominator);
+
+  if (0 == nominator) {
+    //Exposure time = 0 is invalid value
+    return Rational::createInvalid();
+  }
+
+  return Rational(nominator, denominator);
+}
+
+std::string Rational::toString() const
+{
+  std::stringstream ss;
+  ss << nominator << "/" << denominator;
+  return ss.str();
+}
+
+std::string Rational::toExposureTimeString() const
+{
+  LoggerD("Entered");
+  if (!isValid() || 0 == nominator) {
+    return std::string();
+  }
+
+  std::string output_str;
+
+  if (nominator < denominator) {
+    output_str = toString();
+  }
+  else if (nominator % denominator == 0) {
+    std::stringstream ss;
+    ss << nominator / denominator;
+    output_str = ss.str();
+  }
+  else {
+    ExifLong new_nominator = nominator % denominator;
+    ExifLong new_denominator = denominator;
+    ExifLong integer_value = nominator / denominator;
+
+    std::stringstream ss;
+    ss << integer_value << " ";
+    ss << new_nominator << "/" << new_denominator;
+    output_str = ss.str();
+  }
+
+  return output_str;
+}
+
+} // exif
+} // extension
diff --git a/src/exif/Rational.h b/src/exif/Rational.h
new file mode 100644 (file)
index 0000000..f31dd87
--- /dev/null
@@ -0,0 +1,97 @@
+//
+// Tizen Web Device API
+// Copyright (c) 2014 Samsung Electronics Co., Ltd.
+//
+// Licensed 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.
+//
+
+
+#ifndef __TIZEN_EXIF_RATIONAL_H_
+#define __TIZEN_EXIF_RATIONAL_H_
+
+#include <string>
+#include <vector>
+#include <memory>
+
+#include <libexif/exif-utils.h>
+#include <libexif/exif-entry.h>
+#include <libexif/exif-data.h>
+
+#include "ExifUtil.h"
+
+namespace extension {
+namespace exif {
+
+class Rational;
+typedef std::vector<Rational> Rationals;
+typedef std::shared_ptr<Rationals> RationalsPtr;
+
+/**
+ * This class represents fraction as nominator/denominator - two ExifLong values
+ * Rational type is present in Exif specification - used for example in GPS coordinates
+ */
+class Rational
+{
+public:
+  /**
+   * Default constructor sets to 0/0 - invalud rational number
+   */
+  Rational();
+
+  Rational(ExifLong nom, ExifLong denom);
+  Rational(const ExifRational& exif_rational);
+
+  static Rational createFromDouble(const double value, const long precision = 1000);
+  static Rational createInvalid();
+
+  /**
+   * Returns true if denominator is valid (!= 0) and therefore whole Rational is valid
+   */
+  bool isValid() const;
+
+  double toDouble() const;
+
+  /**
+   * Returns string in format: nominator/denominator,
+   * for example: "1/4", "1/1", "5/3".
+   *
+   */
+  std::string toString() const;
+
+  /**
+   * Create rational number from exposure string
+   * Accepted format "(integer) (nominator/denominator)"
+   * for example:
+   * "1/5", "4/5" - just fraction part
+   * "1", "5" - just integer part
+   * "1 1/5", "4 1/4" - integer + fraction part
+   */
+  static Rational createFromExposureTimeString(const std::string& exp_time);
+
+  /**
+   * Return time exposure string in following format:
+   *
+   * nominator < denominator                 : "1/5", "4/5"
+   * nominator == x*denominator              : "1", "5"
+   * nominator > denominator && nominator != x*denominator : "1 1/5", "4 1/4"
+   */
+  std::string toExposureTimeString() const;
+
+  ExifLong nominator;
+  ExifLong denominator;
+};
+
+} // exif
+} // extension
+
+#endif // __TIZEN_EXIF_RATIONAL_H_
index e4ea5b2b02828274d3868a79b80cf4d70d84b0ce..be75d89c180d390e7deae11c02e498d978bc024b 100644 (file)
         'exif_extension.h',
         'exif_instance.cc',
         'exif_instance.h',
+
+        'ExifInformation.cpp',
+        'ExifInformation.h',
+        'ExifUtil.cpp',
+        'ExifUtil.h',
+        'ExifTagSaver.cpp',
+        'ExifTagSaver.h',
+        'JpegFile.cpp',
+        'JpegFile.h',
+        'Rational.cpp',
+        'Rational.h',
+        'ExifGPSLocation.cpp',
+        'ExifGPSLocation.h',
       ],
       'conditions': [
         [ 'tizen == 1', {
-            'variables': { },
+            'variables': {
+              'packages': [
+                'libexif',
+              ]
+            },
         }],
       ],
     },
index 055735221cfd092efd31353707477a7b5fb965cc..59d2b99868c80efab4b39d3c8499ee68d9c26d03 100644 (file)
@@ -59,9 +59,23 @@ ExifManager.prototype.getExifInfo = function() {
     }
   ]);
 
-  throw 'Not implemented';
+  var callArgs = {
+    uri: args.uri
+  };
+
+  var callback = function(result) {
+    if (native_.isFailure(result)) {
+      native_.callIfPossible(args.errorCallback, native_.getErrorObject(result));
+    } else {
+      var exifInfo = native_.getResultObject(result);
+      args.successCallback(exifInfo);
+    }
+  };
+
+  native_.call('Exif_getExifInfo', callArgs, callback);
 };
 
+
 ExifManager.prototype.saveExifInfo = function() {
   var args = validator_.validateArgs(arguments, [
     {
index 798adeed953eb04b58ecbc859da99acf1ec0cf25..f996bd8228813ea2ca452b708ec6204eaac5d36a 100644 (file)
@@ -1,16 +1,32 @@
-// Copyright (c) 2014 Samsung Electronics Co., Ltd. All Rights Reserved.
+// Copyright (c) 2015 Samsung Electronics Co., Ltd. All Rights Reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
 #include "exif/exif_instance.h"
 
+#include "common/task-queue.h"
+#include "common/logger.h"
+
 #include <string>
+#include <sstream>
 
-#include "common/logger.h"
+#include <libexif/exif-data.h>
+#include <libexif/exif-entry.h>
+#include <libexif/exif-utils.h>
+#include <libexif/exif-loader.h>
+
+#include "ExifUtil.h"
+#include "JpegFile.h"
+#include "ExifInformation.h"
 
 namespace extension {
 namespace exif {
 
+typedef picojson::value JsonValue;
+typedef picojson::object JsonObject;
+typedef picojson::array JsonArray;
+typedef std::string JsonString;
+
 namespace {
 const char kGetExifInfoCmd[] = "Exif_getExifInfo";
 const char kSaveExifInfoCmd[] = "Exif_saveExifInfo";
@@ -19,26 +35,119 @@ const char kGetThumbnailCmd[] = "Exif_getThumbnail";
 
 ExifInstance::ExifInstance() {
   using namespace std::placeholders;
-  #define REGISTER_SYNC(c,x) \
-    RegisterSyncHandler(c, std::bind(&ExifInstance::x, this, _1, _2));
-  REGISTER_SYNC(kGetExifInfoCmd, getExifInfo);
-  REGISTER_SYNC(kSaveExifInfoCmd, saveExifInfo);
-  REGISTER_SYNC(kGetThumbnailCmd, getThumbnail);
-  #undef REGISTER_SYNC
+
+#define REGISTER_ASYNC(c, x) \
+  RegisterHandler(c, std::bind(&ExifInstance::x, this, _1, _2));
+  REGISTER_ASYNC(kGetExifInfoCmd, getExifInfo);
+  REGISTER_ASYNC(kSaveExifInfoCmd, saveExifInfo);
+  REGISTER_ASYNC(kGetThumbnailCmd, getThumbnail);
+#undef REGISTER_ASYNC
 }
 
-ExifInstance::~ExifInstance() {}
+ExifInstance::~ExifInstance() { }
 
 void ExifInstance::getExifInfo(const picojson::value& args, picojson::object& out) {
-  LoggerE("getExifInfo is not implemented");
+  LoggerD("ExifInstance::getExifInfo() in c++ A");
+
+  const std::string& uri = args.get("uri").get<std::string>();
+
+  const double callback_id = args.get("callbackId").get<double>();
+  auto get = [=](const std::shared_ptr<JsonValue>& response) -> void {
+    try {
+      // uri = file:///opt/usr/media/Images/exif.jpg
+      // file_path = /opt/usr/media/Images/exif.jpg
+      const std::string file_path = ExifUtil::convertUriToPath(uri);
+      LoggerD("file_path = %s\n", file_path.c_str());
+
+      LoggerD("ExifInformation::loadFromURI... %s", file_path.c_str());
+      ExifInformationPtr exif_info = ExifInformation::loadFromURI(uri);
+      if (!exif_info)
+      {
+          LoggerE("ExifInformation::loadFromURI failed for %s", file_path.c_str());
+      }
+
+      unsigned long width = exif_info->getWidth();
+      LoggerD("width = %d", width);
+      unsigned long height = exif_info->getHeight();
+      LoggerD("height = %d", height);
+      const std::string& device_maker = exif_info->getDeviceMaker();
+      LoggerD("device_maker = %s", device_maker.c_str());
+      const std::string& device_model = exif_info->getDeviceModel();
+      LoggerD("device_model = %s", device_model.c_str());
+      const time_t original_time = exif_info->getOriginalTime();
+      LoggerD("original_time = %s", asctime(localtime(&original_time)));
+      //...
+
+
+
+
+      /* todo: all fields that need to be implemented:
+      DOMString uri;
+      unsigned long width;
+      unsigned long height;
+      DOMString deviceMaker;
+      DOMString deviceModel;
+      Date originalTime;
+      ImageContentOrientation orientation;
+      double fNumber;
+      unsigned short[] isoSpeedRatings;
+      DOMString exposureTime;
+      ExposureProgram exposureProgram;
+      boolean flash;
+      double focalLength;
+      WhiteBalanceMode whiteBalance;
+      SimpleCoordinates gpsLocation;
+      double gpsAltitude;
+      DOMString gpsProcessingMethod;
+      Date gpsTime;
+      DOMString userComment;
+*/
+
+
+
+      JsonValue result = JsonValue(JsonObject());
+      JsonObject& result_obj = result.get<JsonObject>();
+      std::ostringstream ss_width;
+      ss_width << width;
+      result_obj.insert(std::make_pair("width", ss_width.str().c_str()));
+      std::ostringstream ss_height;
+      ss_height << height;
+      result_obj.insert(std::make_pair("height", ss_height.str().c_str()));
+      result_obj.insert(std::make_pair("device_maker", device_maker.c_str()));
+      result_obj.insert(std::make_pair("device_model", device_model.c_str()));
+      // todo: convert to js type: Date
+      result_obj.insert(std::make_pair("original_time", asctime(localtime(&original_time))));
+
+      // todo: implement remaining fields
+
+      ReportSuccess(result, response->get<picojson::object>());
+    } catch (const common::PlatformException& e) {
+      ReportError(e, response->get<picojson::object>());
+    }
+  };
+
+  auto get_response =
+      [callback_id, this](const std::shared_ptr<JsonValue>& response) -> void {
+        picojson::object& obj = response->get<picojson::object>();
+        obj.insert(std::make_pair("callbackId", callback_id));
+        LoggerD("callback is %s", response->serialize().c_str());
+        PostMessage(response->serialize().c_str());
+      };
+
+  common::TaskQueue::GetInstance().Queue<JsonValue>(
+      get, get_response,
+      std::shared_ptr<JsonValue>(new JsonValue(JsonObject())));
+
+  LoggerD("ExifInstance::getExifInfo() END (c++)");
 }
 
 void ExifInstance::saveExifInfo(const picojson::value& args, picojson::object& out) {
-  LoggerE("saveExifInfo is not implemented");
+  LoggerE("saveExifInfo is not implemented (c++)");
 }
 
 void ExifInstance::getThumbnail(const picojson::value& args, picojson::object& out) {
-  LoggerE("getThumbnail is not implemented");
+  LoggerE("getThumbnail is not implemented (c++)");
 }
+
 }  // namespace exif
 }  // namespace extension
diff --git a/src/exif/old/ExifGPSLocation.cpp b/src/exif/old/ExifGPSLocation.cpp
deleted file mode 100644 (file)
index b1b2b49..0000000
+++ /dev/null
@@ -1,299 +0,0 @@
-//
-// Tizen Web Device API
-// Copyright (c) 2014 Samsung Electronics Co., Ltd.
-//
-// Licensed 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.
-//
-
-#include "ExifGPSLocation.h"
-
-#include <sstream>
-
-#include <Logger.h>
-
-namespace DeviceAPI {
-namespace Exif {
-
-GCSPosition::GCSPosition()
-{
-}
-
-GCSPosition::GCSPosition(Rational _degrees, Rational _minutes, Rational _seconds) :
-        degrees(_degrees),
-        minutes(_minutes),
-        seconds(_seconds)
-{
-}
-
-bool GCSPosition::isValid() const
-{
-    if (!(degrees.isValid() && minutes.isValid() && seconds.isValid())) {
-        return false;
-    }
-
-    if ((degrees.toDouble() > 180.0f) ||
-            (minutes.toDouble() > 60.0f) ||
-            (seconds.toDouble() > 60.0f)) {
-        return false;
-    }
-
-    return toDouble() <= 180.0f;
-}
-
-double GCSPosition::toDouble() const
-{
-    const double degrees_value = degrees.toDouble();
-    const double minutes_value = minutes.toDouble();
-    const double seconds_value = seconds.toDouble();
-    return (degrees_value + (minutes_value/60.0) + (seconds_value/3600.0));
-}
-
-Rationals GCSPosition::toRationalsVector() const
-{
-    Rationals vec;
-    vec.push_back(degrees);
-    vec.push_back(minutes);
-    vec.push_back(seconds);
-    return vec;
-}
-
-std::string GCSPosition::toDebugString() const
-{
-    std::stringstream ss;
-    ss << degrees.toString() << "d ";
-    ss << minutes.toString() << "m ";
-    ss << seconds.toString() << "s";
-    return ss.str();
-}
-
-GCSPosition GCSPosition::createFromDouble(double value)
-{
-    LOGD("Entered value:%f");
-    if (value < 0) {
-        LOGW("Trying to create GCSPosition with double < 0: %f", value);
-        return GCSPosition();
-    }
-
-    if (value > 180.0) {
-        LOGW("Trying to create GCSPosition with double > 180.0: %f", value);
-        return GCSPosition();
-    }
-
-    const double d_degrees = floor(value);
-    double left = value - d_degrees;
-
-    const double d_minutes = floor(left * 60.0);
-    left -= d_minutes / 60.0;
-
-    const double d_seconds = left * 3600.0;
-
-    LOGD("d_degrees:%f d_minutes:%f d_seconds:%f", d_degrees, d_minutes, d_seconds);
-
-    GCSPosition pos;
-    pos.degrees = Rational(static_cast<ExifLong>(d_degrees), 1);
-    pos.minutes = Rational(static_cast<ExifLong>(d_minutes), 1);
-    pos.seconds = Rational::createFromDouble(d_seconds);
-    return pos;
-}
-
-ExifGPSLocation::ExifGPSLocation() :
-        m_longitude_ref(GPS_LOCATION_WEST),
-        m_latitude_ref(GPS_LOCATION_NORTH)
-{
-    for(int i = 0; i < EXIF_GPS_LOCATION_ATTRIBUTE_NUMBER_OF_ATTRIBUTES; ++i) {
-        m_is_set[i] = false;
-    }
-}
-
-void ExifGPSLocation::setLongitude(const GCSPosition& longitude)
-{
-    if (!longitude.isValid()) {
-        LOGW("longitude is not valid!");
-        return;
-    }
-
-    m_is_set[EXIF_GPS_LOCATION_ATTRIBUTE_LONGITUDE] = true;
-    m_longitude = longitude;
-}
-
-const GCSPosition& ExifGPSLocation::getLongitude() const
-{
-    return m_longitude;
-}
-
-void ExifGPSLocation::setLongitudeRef(GPSLocationDirectionLongitude ref)
-{
-    m_is_set[EXIF_GPS_LOCATION_ATTRIBUTE_LONGITUDE_REF] = true;
-    m_longitude_ref = ref;
-}
-
-GPSLocationDirectionLongitude ExifGPSLocation::getLongitudeRef() const
-{
-    return m_longitude_ref;
-}
-
-void ExifGPSLocation::setLatitude(const GCSPosition& latitude)
-{
-    if (!latitude.isValid()) {
-        LOGW("latitude is not valid!");
-        return;
-    }
-
-    m_is_set[EXIF_GPS_LOCATION_ATTRIBUTE_LATITUDE] = true;
-    m_latitude = latitude;
-}
-
-const GCSPosition& ExifGPSLocation::getLatitude() const
-{
-    return m_latitude;
-}
-
-void ExifGPSLocation::setLatitudeRef(GPSLocationDirectionLatitude ref)
-{
-    m_is_set[EXIF_GPS_LOCATION_ATTRIBUTE_LATITUDE_REF] = true;
-    m_latitude_ref = ref;
-}
-
-GPSLocationDirectionLatitude ExifGPSLocation::getLatitudeRef() const
-{
-    return m_latitude_ref;
-}
-
-bool ExifGPSLocation::isSet(ExifGPSLocationAttributes attribute) const
-{
-    return m_is_set[attribute];
-}
-
-void ExifGPSLocation::unset(ExifGPSLocationAttributes attribute)
-{
-    m_is_set[attribute] = false;
-}
-
-void ExifGPSLocation::unsetAll()
-{
-    m_is_set[EXIF_GPS_LOCATION_ATTRIBUTE_LONGITUDE] = false;
-    m_is_set[EXIF_GPS_LOCATION_ATTRIBUTE_LONGITUDE_REF] = false;
-    m_longitude =  GCSPosition();
-
-    m_is_set[EXIF_GPS_LOCATION_ATTRIBUTE_LATITUDE] = false;
-    m_is_set[EXIF_GPS_LOCATION_ATTRIBUTE_LATITUDE_REF] = false;
-    m_latitude = GCSPosition();
-}
-
-bool ExifGPSLocation::isComplete() const
-{
-    return m_is_set[EXIF_GPS_LOCATION_ATTRIBUTE_LONGITUDE] &&
-            m_is_set[EXIF_GPS_LOCATION_ATTRIBUTE_LONGITUDE_REF] &&
-            m_is_set[EXIF_GPS_LOCATION_ATTRIBUTE_LATITUDE] &&
-            m_is_set[EXIF_GPS_LOCATION_ATTRIBUTE_LATITUDE_REF];
-}
-
-
-bool ExifGPSLocation::isValid() const
-{
-    return isComplete() && m_latitude.isValid() && m_longitude.isValid();
-}
-
-Tizen::SimpleCoordinatesPtr ExifGPSLocation::getSimpleCoordinates() const
-{
-    if (!isComplete()) {
-        LOGW("Some attributes are not set!");
-        return Tizen::SimpleCoordinatesPtr();
-    }
-
-    if (!isValid()) {
-        LOGW("Some attributes are not valid!");
-        return Tizen::SimpleCoordinatesPtr();
-    }
-
-    const double cur_latitude = getLatitudeValue();
-    const double cur_longitude = getLongitudeValue();
-
-    return Tizen::SimpleCoordinatesPtr(
-            new Tizen::SimpleCoordinates(cur_latitude, cur_longitude));
-}
-
-double ExifGPSLocation::getLongitudeValue() const
-{
-    const double longitude_dir = (m_longitude_ref == GPS_LOCATION_WEST) ? -1.0f : 1.0f;
-    const double longitude = m_longitude.toDouble() * longitude_dir;
-    return longitude;
-}
-
-double ExifGPSLocation::getLatitudeValue() const
-{
-    const double latitude_dir = (m_latitude_ref == GPS_LOCATION_SOUTH) ? -1.0f : 1.0f;
-    const double latitude = m_latitude.toDouble() * latitude_dir;
-    return latitude;
-}
-
-bool ExifGPSLocation::set(Tizen::SimpleCoordinatesPtr scoords)
-{
-    LOGD("Entered");
-    if (!scoords) {
-        LOGW("Trying to set null SimpleCoordinates!");
-        return false;
-    }
-
-    const double longitude = scoords->getLongitude();
-    const double latitude = scoords->getLatitude();
-    bool updateLongitude = true;
-    bool updateLatitude = true;
-
-    if(isComplete()) {
-        updateLatitude = getLatitudeValue() != latitude;
-        updateLongitude = getLongitudeValue() != longitude;
-    }
-
-    LOGD("latitude:%f longitude:%f", latitude, longitude);
-
-    GCSPosition gcs_longitude = GCSPosition::createFromDouble(fabs(longitude));
-    LOGD("gcs_longitude deg:%s min:%s sec:%s", gcs_longitude.degrees.toString().c_str(),
-            gcs_longitude.minutes.toString().c_str(),
-            gcs_longitude.seconds.toString().c_str());
-
-    GCSPosition gcs_latitude = GCSPosition::createFromDouble(fabs(latitude));
-    LOGD("gcs_latitude deg:%s min:%s sec:%s", gcs_latitude.degrees.toString().c_str(),
-            gcs_latitude.minutes.toString().c_str(),
-            gcs_latitude.seconds.toString().c_str());
-
-    if (!gcs_latitude.isValid() || !gcs_longitude.isValid()) {
-        return false;
-    }
-
-    if(updateLongitude) {
-        setLongitude(gcs_longitude);
-        if (longitude >= 0.0) {
-            setLongitudeRef(GPS_LOCATION_EAST);
-        }
-        else {
-            setLongitudeRef(GPS_LOCATION_WEST);
-        }
-    }
-
-    if(updateLatitude) {
-        setLatitude(gcs_latitude);
-        if (latitude >= 0.0) {
-            setLatitudeRef(GPS_LOCATION_NORTH);
-        }
-        else {
-            setLatitudeRef(GPS_LOCATION_SOUTH);
-        }
-    }
-
-    return true;
-}
-
-
-} // Exif
-} // DeviceAPI
diff --git a/src/exif/old/ExifGPSLocation.h b/src/exif/old/ExifGPSLocation.h
deleted file mode 100644 (file)
index d7aecc7..0000000
+++ /dev/null
@@ -1,147 +0,0 @@
-//
-// Tizen Web Device API
-// Copyright (c) 2014 Samsung Electronics Co., Ltd.
-//
-// Licensed 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.
-//
-
-#ifndef __TIZEN_EXIF_EXIF_GPS_LOCATION_H_
-#define __TIZEN_EXIF_EXIF_GPS_LOCATION_H_
-
-#include <string>
-
-#include <SimpleCoordinates.h>
-
-#include "ExifUtil.h"
-
-namespace DeviceAPI {
-namespace Exif {
-
-enum GPSLocationDirectionLongitude {
-    GPS_LOCATION_WEST,
-    GPS_LOCATION_EAST
-};
-
-enum GPSLocationDirectionLatitude {
-    GPS_LOCATION_NORTH,
-    GPS_LOCATION_SOUTH
-};
-
-enum ExifGPSLocationAttributes {
-    EXIF_GPS_LOCATION_ATTRIBUTE_LONGITUDE = 0,
-    EXIF_GPS_LOCATION_ATTRIBUTE_LONGITUDE_REF,
-    EXIF_GPS_LOCATION_ATTRIBUTE_LATITUDE,
-    EXIF_GPS_LOCATION_ATTRIBUTE_LATITUDE_REF,
-    EXIF_GPS_LOCATION_ATTRIBUTE_NUMBER_OF_ATTRIBUTES
-};
-
-/**
- * This class represents Global Coordinate System using
- * three Rational numbers (as stored in Exif)
- */
-struct GCSPosition
-{
-    GCSPosition();
-    GCSPosition(Rational degrees, Rational minutes, Rational seconds);
-
-    /**
-     * Create GCSPosition from degrees represented as double value
-     */
-    static GCSPosition createFromDouble(double value);
-
-    /**
-     * Verify that all components are valid Rational numbers and
-     * each component is within valid range. Sum of degrees,
-     * minutes and seconds should not be bigger then 180.0
-     */
-    bool isValid() const;
-
-    /**
-     * Return position in degrees
-     */
-    double toDouble() const;
-
-    /**
-     * Return vector of three rationals: dgrees, minutes, seconds
-     */
-    Rationals toRationalsVector() const;
-
-    /**
-     * Return string for debugging purposes
-     */
-    std::string toDebugString() const;
-
-    Rational degrees;
-    Rational minutes;
-    Rational seconds;
-};
-
-class ExifGPSLocation
-{
-public:
-    ExifGPSLocation();
-
-    void setLongitude(const GCSPosition& longitude);
-    const GCSPosition& getLongitude() const;
-
-    void setLongitudeRef(GPSLocationDirectionLongitude ref);
-    GPSLocationDirectionLongitude getLongitudeRef() const;
-
-    void setLatitude(const GCSPosition& latitude);
-    const GCSPosition& getLatitude() const;
-
-    void setLatitudeRef(GPSLocationDirectionLatitude ref);
-    GPSLocationDirectionLatitude getLatitudeRef() const;
-
-    bool isSet(ExifGPSLocationAttributes attribute) const;
-    void unset(ExifGPSLocationAttributes attribute);
-    void unsetAll();
-
-    /**
-     * Returns true only if all components are set.
-     */
-    bool isComplete() const;
-
-    /**
-     * Returns true only if all components are set and valid.
-     */
-    bool isValid() const;
-
-    /**
-     * Returns null pointer if any information is missing or incorrect
-     */
-    Tizen::SimpleCoordinatesPtr getSimpleCoordinates() const;
-
-    /**
-     * Return true if scoords has been set
-     */
-    bool set(Tizen::SimpleCoordinatesPtr scoords);
-
-private:
-
-    double getLongitudeValue() const;
-    double getLatitudeValue() const;
-
-    GCSPosition m_longitude;
-    GPSLocationDirectionLongitude m_longitude_ref;
-
-    GCSPosition m_latitude;
-    GPSLocationDirectionLatitude m_latitude_ref;
-
-    bool m_is_set[EXIF_GPS_LOCATION_ATTRIBUTE_NUMBER_OF_ATTRIBUTES];
-};
-
-} // Exif
-} // DeviceAPI
-
-#endif // __TIZEN_EXIF_EXIF_GPS_LOCATION_H_
index aebb360d2d5da5b25664b7a6358a20d4603462e7..db8d45a1fd1051578a8603bb1a0b13bd4b0a5868 100644 (file)
@@ -25,8 +25,8 @@
 #include <Logger.h>
 #include <PlatformException.h>
 
-namespace DeviceAPI {
-namespace Exif {
+namespace extension {
+namespace exif {
 
 bool isValidDateFormat(const std::string& date)
 {
@@ -271,5 +271,5 @@ void ExifGPSTime::setDateAndTime(Time::TZDatePtr new_time)
             m_time[2].toString().c_str());
 }
 
-} // Exif
-} // DeviceAPI
+} // exif
+} // extension
index 24f15cd76c2bb926eeab55defa0966f948d9a876..3ac21f2f3fc64cf3d862c023bb6dcd1ee5906aac 100644 (file)
@@ -24,8 +24,8 @@
 
 #include "ExifUtil.h"
 
-namespace DeviceAPI {
-namespace Exif {
+namespace extension {
+namespace exif {
 
 class ExifGPSTime
 {
@@ -78,7 +78,7 @@ private:
     time_t m_time_and_date;
 };
 
-} // Exif
-} // DeviceAPI
+} // exif
+} // extension
 
 #endif // __TIZEN_EXIF_EXIF_GPS_TIME_H_
diff --git a/src/exif/old/ExifInformation.cpp b/src/exif/old/ExifInformation.cpp
deleted file mode 100644 (file)
index c9a39f1..0000000
+++ /dev/null
@@ -1,1340 +0,0 @@
-//
-// Tizen Web Device API
-// Copyright (c) 2014 Samsung Electronics Co., Ltd.
-//
-// Licensed 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.
-//
-
-#include "ExifInformation.h"
-
-#include <Logger.h>
-#include <memory>
-#include <PlatformException.h>
-
-#include "ExifTagSaver.h"
-#include "ExifUtil.h"
-#include "JpegFile.h"
-
-using namespace DeviceAPI::Common;
-
-namespace DeviceAPI {
-namespace Exif {
-
-const size_t EXIF_UNDEFINED_TYPE_LENGTH = 8;
-const std::string EXIF_UNDEFINED_TYPE_ASCII =
-        std::string("ASCII\0\0\0", EXIF_UNDEFINED_TYPE_LENGTH);
-const std::string EXIF_UNDEFINED_TYPE_JIS =
-        std::string("JIS\0\0\0\0\0", EXIF_UNDEFINED_TYPE_LENGTH);
-const std::string EXIF_UNDEFINED_TYPE_UNICODE =
-        std::string("UNICODE\0", EXIF_UNDEFINED_TYPE_LENGTH);
-const std::string EXIF_UNDEFINED_TYPE_UNDEFINED =
-        std::string("\0\0\0\0\0\0\0\0", EXIF_UNDEFINED_TYPE_LENGTH);
-
-ExifInformation::ExifInformation()
-{
-    for (int attr = 0; attr < EXIF_INFORMATION_ATTRIBUTE_NUMBER_OF_ATTRIBUTES; attr++) {
-        unset(static_cast<ExifInformationAttribute>(attr));
-    }
-}
-
-ExifInformation::~ExifInformation()
-{
-}
-
-const std::string& ExifInformation::getUri()
-{
-    LOGD("Entered");
-    return m_uri;
-}
-
-void ExifInformation::setUri(const std::string& uri)
-{
-    LOGD("Entered");
-    m_is_set[EXIF_INFORMATION_ATTRIBUTE_URI] = true;
-    m_uri = uri;
-}
-
-unsigned long ExifInformation::getWidth() const
-{
-    LOGD("Entered");
-    return m_width;
-}
-
-void ExifInformation::setWidth(unsigned long width)
-{
-    LOGD("Entered");
-    m_is_set[EXIF_INFORMATION_ATTRIBUTE_WIDTH] = true;
-    m_width = width;
-}
-
-unsigned long ExifInformation::getHeight() const
-{
-    LOGD("Entered");
-    return m_height;
-}
-
-void ExifInformation::setHeight(unsigned long height)
-{
-    LOGD("Entered");
-    m_is_set[EXIF_INFORMATION_ATTRIBUTE_HEIGHT] = true;
-    m_height = height;
-}
-
-const std::string& ExifInformation::getDeviceMaker()
-{
-    LOGD("Entered");
-    return m_device_maker;
-}
-
-void ExifInformation::setDeviceMaker(const std::string& device_maker)
-{
-    LOGD("Entered");
-    m_is_set[EXIF_INFORMATION_ATTRIBUTE_DEVICE_MAKER] = true;
-    m_device_maker = device_maker;
-}
-
-const std::string& ExifInformation::getDeviceModel()
-{
-    LOGD("Entered");
-    return m_device_model;
-}
-
-void ExifInformation::setDeviceModel(const std::string& device_model)
-{
-    LOGD("Entered");
-    m_is_set[EXIF_INFORMATION_ATTRIBUTE_DEVICE_MODEL] = true;
-    m_device_model = device_model;
-}
-
-time_t ExifInformation::getOriginalTime() const
-{
-    LOGD("Entered");
-    return m_original_time;
-}
-
-void ExifInformation::setOriginalTime(time_t original_time)
-{
-    LOGD("Entered");
-    m_is_set[EXIF_INFORMATION_ATTRIBUTE_ORIGINAL_TIME] = true;
-    m_original_time = original_time;
-}
-
-ImageOrientation ExifInformation::getOrientation() const
-{
-    LOGD("Entered");
-    return m_orientation;
-}
-
-void ExifInformation::setOrientation(ImageOrientation orientation)
-{
-    LOGD("Entered");
-    if(EXIF_ORIENTATION_NOT_VALID == orientation) {
-        LOGW("Trying to set NOT VALID orientation");
-        return;
-    }
-
-    m_is_set[EXIF_INFORMATION_ATTRIBUTE_ORIENTATION] = true;
-    m_orientation = orientation;
-}
-
-const Rational& ExifInformation::getFNumber() const
-{
-    LOGD("Entered");
-    return m_f_number;
-}
-
-void ExifInformation::setFNumber(Rational f_number)
-{
-    LOGD("Entered");
-    if(!f_number.isValid()) {
-        LOGW("Trying to set invalid F-Number: %s", f_number.toString().c_str());
-        return;
-    }
-
-    m_is_set[EXIF_INFORMATION_ATTRIBUTE_FNUMBER] = true;
-    m_f_number = f_number;
-}
-
-Common::JSLongLongVector ExifInformation::getIsoSpeedRatings()
-{
-    LOGD("Entered");
-    return m_iso_speed_ratings;
-}
-
-void ExifInformation::setIsoSpeedRatings(
-        const std::vector<long long int>& iso_speed_ratings)
-{
-    LOGD("Entered");
-    m_is_set[EXIF_INFORMATION_ATTRIBUTE_ISO_SPEED_RATINGS] = true;
-    m_iso_speed_ratings = iso_speed_ratings;
-}
-
-void ExifInformation::appendIsoSpeedRatings(long long int iso_speed_rating)
-{
-    m_is_set[EXIF_INFORMATION_ATTRIBUTE_ISO_SPEED_RATINGS] = true;
-    m_iso_speed_ratings.push_back(iso_speed_rating);
-}
-
-const Rational& ExifInformation::getExposureTime()
-{
-    LOGD("Entered");
-    return m_exposure_time;
-}
-
-void ExifInformation::setExposureTime(const Rational& exposure_time)
-{
-    LOGD("Entered");
-    if (!exposure_time.isValid() || 0 == exposure_time.nominator) {
-        LOGW("Trying to set invalid exposure time: [%s]",
-                exposure_time.toString().c_str());
-        return;
-    }
-
-    m_is_set[EXIF_INFORMATION_ATTRIBUTE_EXPOSURE_TIME] = true;
-    m_exposure_time = exposure_time;
-}
-
-ExposureProgram ExifInformation::getExposureProgram()
-{
-    LOGD("Entered");
-    return m_exposure_program;
-}
-
-void ExifInformation::setExposureProgram(ExposureProgram exposure_program)
-{
-    LOGD("Entered");
-    if (EXIF_EXPOSURE_PROGRAM_NOT_VALID == exposure_program) {
-        LOGW("Trying to set NOT VALID exposure program");
-        return;
-    }
-
-    m_is_set[EXIF_INFORMATION_ATTRIBUTE_EXPOSURE_PROGRAM] = true;
-    m_exposure_program = exposure_program;
-}
-
-bool ExifInformation::getFlash() const
-{
-    LOGD("Entered");
-    return m_flash;
-}
-
-void ExifInformation::setFlash(bool flash)
-{
-    LOGD("Entered");
-    m_is_set[EXIF_INFORMATION_ATTRIBUTE_FLASH] = true;
-    m_flash = flash;
-}
-
-const Rational& ExifInformation::getFocalLength() const
-{
-    LOGD("Entered");
-    return m_focal_length;
-}
-
-void ExifInformation::setFocalLength(Rational focal_length)
-{
-    LOGD("Entered");
-    if(!focal_length.isValid()) {
-        LOGW("Trying to set invalid focal length: %s", focal_length.toString().c_str());
-        return;
-    }
-
-    m_is_set[EXIF_INFORMATION_ATTRIBUTE_FOCAL_LENGTH] = true;
-    m_focal_length = focal_length;
-}
-
-WhiteBalanceMode ExifInformation::getWhiteBalanceMode() const
-{
-    LOGD("Entered");
-    return m_white_balance;
-}
-
-void ExifInformation::setWhiteBalanceMode(WhiteBalanceMode white_balance)
-{
-    LOGD("Entered");
-    if (EXIF_WHITE_BALANCE_MODE_NOT_VALID == white_balance) {
-        LOGW("Trying to set NOT VALID white balance mode");
-        return;
-    }
-
-    m_is_set[EXIF_INFORMATION_ATTRIBUTE_WHITE_BALANCE] = true;
-    m_white_balance = white_balance;
-}
-
-ExifGPSLocation& ExifInformation::getGPSExifLocation()
-{
-    return m_exif_gps_location;
-}
-
-Tizen::SimpleCoordinatesPtr ExifInformation::getGPSLocation()
-{
-    if(m_gps_location) {
-        return m_gps_location;
-    }
-
-
-    Tizen::SimpleCoordinatesPtr nscoords = m_exif_gps_location.getSimpleCoordinates();
-    if(!nscoords) {
-        return nscoords;
-    }
-
-    m_gps_location = nscoords;
-    return m_gps_location;
-}
-
-void ExifInformation::setGPSLocation(Tizen::SimpleCoordinatesPtr gps_location)
-{
-    if(!gps_location) {
-        LOGW("Trying to set NULL gps location!");
-        return;
-    }
-
-    m_gps_location = gps_location;
-}
-
-void ExifInformation::unsetGPSLocation()
-{
-    m_gps_location = Tizen::SimpleCoordinatesPtr();
-    m_exif_gps_location.unsetAll();
-}
-
-const Rational& ExifInformation::getGpsAltitude() const
-{
-    LOGD("Entered");
-    return m_gps_altitude;
-}
-
-void ExifInformation::setGpsAltitude(Rational gps_altitude)
-{
-    LOGD("Entered");
-    if(!gps_altitude.isValid()) {
-        LOGW("Trying to set invalid gps altitude: %s", gps_altitude.toString().c_str());
-        return;
-    }
-
-    m_is_set[EXIF_INFORMATION_ATTRIBUTE_GPS_ALTITUDE] = true;
-    m_gps_altitude = gps_altitude;
-}
-
-GpsAltitudeRef ExifInformation::getGpsAltitudeRef() const
-{
-    LOGD("Entered");
-    return m_gps_altitude_ref;
-}
-
-void ExifInformation::setGpsAltitudeRef(const GpsAltitudeRef ref)
-{
-    LOGD("Entered");
-    m_is_set[EXIF_INFORMATION_ATTRIBUTE_GPS_ALTITUDE_REF] = true;
-    m_gps_altitude_ref = ref;
-}
-
-void ExifInformation::setGpsAltitudeWithRef(double gps_altitude)
-{
-    LOGD("Entered");
-    setGpsAltitude(Rational::createFromDouble(fabs(gps_altitude)));
-
-    if(gps_altitude >= 0.0) {
-        setGpsAltitudeRef(GPS_ALTITUDE_REF_ABOVE_SEA);
-    } else {
-        setGpsAltitudeRef(GPS_ALTITUDE_REF_BELOW_SEA);
-    }
-
-}
-
-double ExifInformation::getGpsAltitudeWithRef() const
-{
-    LOGD("Entered");
-
-    if(!m_is_set[EXIF_INFORMATION_ATTRIBUTE_GPS_ALTITUDE_REF] ||
-            GPS_ALTITUDE_REF_ABOVE_SEA == m_gps_altitude_ref) {
-        return m_gps_altitude.toDouble();
-    } else {
-        return -1.0 * m_gps_altitude.toDouble();
-    }
-}
-
-const std::string& ExifInformation::getGpsProcessingMethod() const
-{
-    LOGD("Entered");
-    return m_gps_processing_method;
-}
-
-const std::string& ExifInformation::getGpsProcessingMethodType() const
-{
-    LOGD("Entered");
-    return m_gps_processing_method_type;
-}
-
-void ExifInformation::setGpsProcessingMethod(const std::string& type,
-        const std::string& processing_method)
-{
-    LOGD("Entered");
-    if(type != EXIF_UNDEFINED_TYPE_ASCII &&
-            type != EXIF_UNDEFINED_TYPE_JIS &&
-            type != EXIF_UNDEFINED_TYPE_UNICODE &&
-            type != EXIF_UNDEFINED_TYPE_UNDEFINED) {
-        LOGW("Trying to set invalid GPSProcessingMethod type: [%s] len:%d",
-                type.c_str(), type.length());
-        return;
-    }
-
-    m_is_set[EXIF_INFORMATION_ATTRIBUTE_GPS_PROCESSING_METHOD] = true;
-    m_gps_processing_method = processing_method;
-    m_gps_processing_method_type = type;
-}
-
-ExifGPSTime& ExifInformation::getExifGpsTime()
-{
-    return m_exif_gps_time;
-}
-
-const ExifGPSTime& ExifInformation::getExifGpsTime() const
-{
-    return m_exif_gps_time;
-}
-
-Time::TZDatePtr ExifInformation::getGpsTime()
-{
-    if(m_gps_time) {
-        return m_gps_time;
-    }
-
-    if(!m_exif_gps_time.isValid()) {
-        return Time::TZDatePtr();
-    }
-
-
-    m_gps_time = m_exif_gps_time.getTZDate();
-    return m_gps_time;
-}
-
-void ExifInformation::setGpsTime(Time::TZDatePtr new_time)
-{
-    if(!new_time) {
-        LOGW("Trying to set null new_time!");
-        return;
-    }
-
-    m_gps_time = new_time;
-}
-
-void ExifInformation::unsetGPStime()
-{
-    m_exif_gps_time.unsetAll();
-    m_gps_time = NULL;
-}
-
-
-const std::string& ExifInformation::getUserComment()
-{
-    LOGD("Entered");
-    return m_user_comment;
-}
-
-const std::string& ExifInformation::getUserCommentType()
-{
-    LOGD("Entered");
-    return m_user_comment_type;
-}
-
-void ExifInformation::setUserComment(const std::string& type,
-        const std::string& user_comment)
-{
-    LOGD("Entered");
-    if(type != EXIF_UNDEFINED_TYPE_ASCII &&
-            type != EXIF_UNDEFINED_TYPE_JIS &&
-            type != EXIF_UNDEFINED_TYPE_UNICODE &&
-            type != EXIF_UNDEFINED_TYPE_UNDEFINED) {
-        LOGW("Trying to set invalid user comment type: [%s] len:%d",
-                type.c_str(), type.length());
-        return;
-    }
-
-    m_is_set[EXIF_INFORMATION_ATTRIBUTE_USER_COMMENT] = true;
-    m_user_comment_type = type;
-    m_user_comment = user_comment;
-}
-
-bool ExifInformation::isSet(ExifInformationAttribute attribute) const
-{
-    LOGD("Entered");
-    return m_is_set[attribute];
-}
-
-void ExifInformation::unset(ExifInformationAttribute attribute)
-{
-    LOGD("Entered");
-    if(attribute >= EXIF_INFORMATION_ATTRIBUTE_NUMBER_OF_ATTRIBUTES) {
-        return;
-    }
-
-    m_is_set[attribute] = false;
-    switch (attribute) {
-        case EXIF_INFORMATION_ATTRIBUTE_URI:
-            m_uri = std::string();
-            break;
-        case EXIF_INFORMATION_ATTRIBUTE_WIDTH:
-            m_width = 0;
-            break;
-        case EXIF_INFORMATION_ATTRIBUTE_HEIGHT:
-            m_height = 0;
-            break;
-        case EXIF_INFORMATION_ATTRIBUTE_DEVICE_MAKER:
-            m_device_maker = std::string();
-            break;
-        case EXIF_INFORMATION_ATTRIBUTE_DEVICE_MODEL:
-            m_device_model = std::string();
-            break;
-        case EXIF_INFORMATION_ATTRIBUTE_ORIGINAL_TIME:
-            m_original_time = 0;
-            break;
-        case EXIF_INFORMATION_ATTRIBUTE_ORIENTATION:
-            m_orientation = EXIF_ORIENTATION_NOT_VALID;
-            break;
-        case EXIF_INFORMATION_ATTRIBUTE_FNUMBER:
-            m_f_number = Rational::createInvalid();
-            break;
-        case EXIF_INFORMATION_ATTRIBUTE_ISO_SPEED_RATINGS:
-            m_iso_speed_ratings = std::vector<long long int>();
-            break;
-        case EXIF_INFORMATION_ATTRIBUTE_EXPOSURE_TIME:
-            m_exposure_time = Rational::createInvalid();
-            break;
-        case EXIF_INFORMATION_ATTRIBUTE_EXPOSURE_PROGRAM:
-            m_exposure_program = EXIF_EXPOSURE_PROGRAM_NOT_VALID;
-            break;
-        case EXIF_INFORMATION_ATTRIBUTE_FLASH:
-            m_flash = false;
-            break;
-        case EXIF_INFORMATION_ATTRIBUTE_FOCAL_LENGTH:
-            m_focal_length = Rational::createInvalid();
-            break;
-        case EXIF_INFORMATION_ATTRIBUTE_WHITE_BALANCE:
-            m_white_balance = EXIF_WHITE_BALANCE_MODE_NOT_VALID;
-            break;
-        case EXIF_INFORMATION_ATTRIBUTE_GPS_ALTITUDE:
-            m_gps_altitude = Rational::createInvalid();
-            break;
-        case EXIF_INFORMATION_ATTRIBUTE_GPS_ALTITUDE_REF:
-            m_gps_altitude_ref = GPS_ALTITUDE_REF_ABOVE_SEA;
-            break;
-        case EXIF_INFORMATION_ATTRIBUTE_GPS_PROCESSING_METHOD:
-            m_gps_processing_method = std::string();
-            m_gps_processing_method_type = EXIF_UNDEFINED_TYPE_ASCII;
-            break;
-        case EXIF_INFORMATION_ATTRIBUTE_USER_COMMENT:
-            m_user_comment = std::string();
-            m_user_comment_type = EXIF_UNDEFINED_TYPE_ASCII;
-            break;
-        default:
-            break;
-    }
-}
-
-bool getGCSPositionFromEntry(ExifEntry *entry, ExifData* exif_data, GCSPosition& out_pos)
-{
-    //RATIONAL - 3
-    if (EXIF_FORMAT_RATIONAL == entry->format &&
-            entry->components >= 3 &&
-            entry->data) {
-        const ExifByteOrder order = exif_data_get_byte_order(exif_data);
-        out_pos.degrees = Rational(exif_get_rational(entry->data, order));
-        out_pos.minutes = Rational(exif_get_rational(
-                entry->data +   ExifTypeInfo::RationalSize, order));
-        out_pos.seconds = Rational(exif_get_rational(
-                entry->data + 2*ExifTypeInfo::RationalSize, order));
-        return true;
-    }
-    else {
-        return false;
-    }
-}
-
-bool getRationalsFromEntry(ExifEntry *entry, ExifData* exif_data,
-            unsigned long required_count, Rationals& out_rationals)
-{
-    if (EXIF_FORMAT_RATIONAL == entry->format &&
-            entry->components >= required_count &&
-            entry->data) {
-        const ExifByteOrder order = exif_data_get_byte_order(exif_data);
-        unsigned char* ptr = entry->data;
-
-        for(unsigned long i = 0; i < required_count; ++i) {
-            out_rationals.push_back(Rational(exif_get_rational(ptr, order)));
-            ptr += ExifTypeInfo::RationalSize;
-        }
-
-        return true;
-    }
-    else {
-        return false;
-    }
-}
-
-Rational getRationalFromEntry(ExifEntry *entry, ExifData* exif_data)
-{
-    if (EXIF_FORMAT_RATIONAL == entry->format && entry->components >= 1 && entry->data) {
-        const ExifByteOrder order = exif_data_get_byte_order(exif_data);
-        return Rational(exif_get_rational(entry->data, order));
-    }
-    else {
-        return Rational::createInvalid();
-    }
-}
-
-bool decomposeExifUndefined(ExifEntry* entry, std::string& type, std::string& value)
-{
-    if(!entry || !entry->data) {
-        LOGW("exif entry is NULL/empty");
-        return false;
-    }
-
-    if(entry->size < EXIF_UNDEFINED_TYPE_LENGTH) {
-        LOGW("entry size is invalid %d < EXIF_UNDEFINED_TYPE_LENGTH", entry->size);
-        return false;
-    }
-
-    const char* ptr = reinterpret_cast<const char*>(entry->data);
-    type = std::string(ptr, EXIF_UNDEFINED_TYPE_LENGTH);
-    ptr += EXIF_UNDEFINED_TYPE_LENGTH;
-    value = std::string(ptr, entry->size - EXIF_UNDEFINED_TYPE_LENGTH);
-    return true;
-}
-
-void ExifInformation::processEntry(ExifEntry* entry, ExifData* exif_data)
-{
-    char buf[2000];
-    exif_entry_get_value(entry, buf, sizeof(buf));
-    ExifUtil::printExifEntryInfo(entry, exif_data);
-
-    const ExifIfd cur_ifd = exif_entry_get_ifd(entry);
-    if (EXIF_IFD_INTEROPERABILITY == cur_ifd || EXIF_IFD_1 == cur_ifd) {
-        return;
-    }
-
-    switch (static_cast<unsigned int>(entry->tag)) {
-        case EXIF_TAG_IMAGE_WIDTH: {
-            //SHORT or LONG - 1
-            exif_entry_get_value(entry, buf, sizeof(buf));
-            LOGD( "Setting ExifInformation width to: [%s]", buf );
-            setWidth(atol(buf));
-            break;
-        }
-        case EXIF_TAG_IMAGE_LENGTH: {
-            //SHORT or LONG - 1
-            exif_entry_get_value(entry, buf, sizeof(buf));
-            LOGD( "Setting ExifInformation height to: [%s]", buf );
-            setHeight(atol(buf));
-            break;
-        }
-        case EXIF_TAG_MAKE: {
-            //ASCII - Any
-            exif_entry_get_value(entry, buf, sizeof(buf));
-            LOGD( "Setting ExifInformation maker to: [%s]", buf );
-            setDeviceMaker(std::string(buf));
-            break;
-        }
-        case EXIF_TAG_MODEL: {
-            //ASCII - Any
-            exif_entry_get_value(entry, buf, sizeof(buf));
-            LOGD( "Setting ExifInformation model to: [%s]", buf );
-            setDeviceModel(std::string(buf));
-            break;
-        }
-        case EXIF_TAG_DATE_TIME_ORIGINAL: {
-            //ASCII - 20
-            exif_entry_get_value(entry, buf, sizeof(buf));
-            const time_t time = ExifUtil::exifDateTimeOriginalToTimeT(
-                    reinterpret_cast<const char*>(entry->data));
-            LOGD( "Setting ExifInformation time original to: [%s] time_t:%d", buf,
-                    (int)time);
-            setOriginalTime(time);
-        }
-        case EXIF_TAG_ORIENTATION: {
-            //SHORT - 1
-            exif_entry_get_value(entry, buf, sizeof(buf));
-            const ExifByteOrder order = exif_data_get_byte_order(exif_data);
-            const ExifShort orient(exif_get_short(entry->data, order));
-
-            if(orient < EXIF_ORIENTATION_NORMAL || orient >= EXIF_ORIENTATION_NOT_VALID) {
-                LOGW("Couldn't set ExifInformation - orientation is not valid: %d (%s)",
-                        orient, buf);
-            }
-            else {
-                LOGD("Setting ExifInformation orientation to: %d [%s]", orient, buf);
-                setOrientation(static_cast<ImageOrientation>(orient));
-            }
-            break;
-        }
-        case EXIF_TAG_FNUMBER:
-        {
-            //RATIONAL - 1
-            Rational fnumber = getRationalFromEntry(entry, exif_data);
-            if(fnumber.isValid()) {
-                LOGD("Setting ExifInformation fnumber to: %f (%s)", fnumber.toDouble(),
-                    fnumber.toString().c_str());
-                setFNumber(fnumber);
-            }
-            else {
-                LOGW("Couldn't set ExifInformation - fnumber is not valid: %s",
-                        fnumber.toString().c_str());
-            }
-            break;
-        }
-        case EXIF_TAG_ISO_SPEED_RATINGS: {
-            //SHORT - Any
-            if (EXIF_FORMAT_SHORT == entry->format &&
-                    entry->components > 0 &&
-                    entry->data) {
-                const ExifByteOrder order = exif_data_get_byte_order(exif_data);
-                unsigned char* read_ptr = entry->data;
-                const size_t size_per_member =
-                        ExifUtil::getSizeOfExifFormatType(entry->format);
-
-                for(unsigned long i = 0; i < entry->components; ++i) {
-                    ExifShort iso_rating = exif_get_short(read_ptr, order);
-                    appendIsoSpeedRatings(iso_rating);
-
-                    LOGD("Appending ExifInformation speed ratings with: %d",
-                            static_cast<int>(iso_rating));
-
-                    read_ptr += size_per_member;
-                }
-            }
-            else {
-                LOGE("iso speed ratings: format or components count is invalid!");
-            }
-            break;
-        }
-        case EXIF_TAG_EXPOSURE_TIME: {
-            //RATIONAL - 1
-            if (EXIF_FORMAT_RATIONAL == entry->format &&
-                    entry->components > 0 &&
-                    entry->data) {
-
-                const ExifByteOrder order = exif_data_get_byte_order(exif_data);
-                const Rational exp_time(exif_get_rational(entry->data, order));
-
-                if (exp_time.isValid()) {
-                    LOGD("Setting ExifInformation exposure time to: %s (%s)",
-                            exp_time.toString().c_str(),
-                            exp_time.toExposureTimeString().c_str());
-                    setExposureTime(exp_time);
-                }
-                else {
-                    LOGD("Couldn't set ExifInformation - exposure time is not valid: %s",
-                            exp_time.toString().c_str());
-                }
-            }
-            else {
-                LOGE("exposure time: format or components count is invalid!");
-            }
-            break;
-        }
-        case EXIF_TAG_EXPOSURE_PROGRAM: {
-            //SHORT - 1
-            exif_entry_get_value(entry, buf, sizeof(buf));
-
-            const ExifByteOrder order = exif_data_get_byte_order(exif_data);
-            const ExifShort exp_program = exif_get_short(entry->data, order);
-            if(exp_program >= EXIF_EXPOSURE_PROGRAM_NOT_VALID) {
-                LOGW("ExposureProgram: %d (%s) is not valid!", exp_program, buf);
-            }
-            else {
-                LOGD("Setting ExifInformation exposure program to: %d [%s]",
-                        exp_program, buf );
-                setExposureProgram(static_cast<ExposureProgram>(exp_program));
-            }
-            break;
-        }
-        case EXIF_TAG_FLASH: {
-            //SHORT - 1
-            exif_entry_get_value(entry, buf, sizeof(buf));
-
-            const ExifByteOrder order = exif_data_get_byte_order(exif_data);
-            const ExifShort flash = exif_get_short(entry->data, order);
-
-            LOGD( "Setting ExifInformation flash to: [%s] flash=%d", buf, flash);
-            setFlash(flash != 0);
-            break;
-        }
-        case EXIF_TAG_FOCAL_LENGTH: {
-            //RATIONAL - 1
-            Rational flength = getRationalFromEntry(entry, exif_data);
-            if(flength.isValid()) {
-                LOGD("Setting ExifInformation focal length to: %f (%s)",
-                        flength.toDouble(), flength.toString().c_str());
-                setFocalLength(flength);
-            }
-            else {
-                LOGW("Couldn't set ExifInformation - focal length is not valid: %s",
-                        flength.toString().c_str());
-            }
-            break;
-        }
-        case EXIF_TAG_WHITE_BALANCE: {
-            //SHORT - 1
-            exif_entry_get_value(entry, buf, sizeof(buf));
-            LOGD( "Setting ExifInformation white balance to: [%s]", buf );
-            if (entry->data[0]) {
-                setWhiteBalanceMode(EXIF_WHITE_BALANCE_MODE_MANUAL);
-            }
-            else {
-                setWhiteBalanceMode(EXIF_WHITE_BALANCE_MODE_AUTO);
-            }
-            break;
-        }
-        case EXIF_TAG_GPS_LONGITUDE: {
-            //RATIONAL - 3
-            GCSPosition longitude;
-            if (getGCSPositionFromEntry(entry, exif_data, longitude)) {
-                m_exif_gps_location.setLongitude(longitude);
-                LOGD("Setting ExifInformation gps longitude to: %s; %s; %s valid:%d",
-                        longitude.degrees.toString().c_str(),
-                        longitude.minutes.toString().c_str(),
-                        longitude.seconds.toString().c_str(),
-                        longitude.isValid());
-            }
-            else {
-                exif_entry_get_value(entry, buf, sizeof(buf));
-                LOGW("Couldn't set longitude pos - data is not valid: [%s]", buf);
-            }
-            break;
-        }
-        case EXIF_TAG_GPS_LONGITUDE_REF: {
-            //ASCII - 2
-            if(entry->size < 1) {
-                LOGW("Longtitude ref entry do not contain enought data!");
-                break;
-            }
-
-            const char ref = static_cast<char>(entry->data[0]);
-            if ('E' == ref || 'e' == ref) {          //East
-                m_exif_gps_location.setLongitudeRef(GPS_LOCATION_EAST);
-                LOGD("Setting ExifInformation gps longitude REF to: EAST");
-            }
-            else if ('W' == ref || 'w' == ref) {     //West
-                m_exif_gps_location.setLongitudeRef(GPS_LOCATION_WEST);
-                LOGD("Setting ExifInformation gps longitude REF to: WEST");
-            }
-            else {
-                LOGW("Unknown longitude ref: %c (0x%x)", ref, static_cast<int>(ref));
-            }
-            break;
-        }
-        case EXIF_TAG_GPS_LATITUDE: {
-            //RATIONAL - 3
-            exif_entry_get_value(entry, buf, sizeof(buf));
-            LOGD( "Setting ExifInformation latitude to: [%s], tag->%s",
-                    buf, exif_tag_get_name(entry->tag) );
-
-            GCSPosition latitude;
-            if (getGCSPositionFromEntry(entry, exif_data, latitude)) {
-                m_exif_gps_location.setLatitude(latitude);
-                LOGD("Setting ExifInformation gps latitude to: %s; %s; %s valid:%d",
-                        latitude.degrees.toString().c_str(),
-                        latitude.minutes.toString().c_str(),
-                        latitude.seconds.toString().c_str(),
-                        latitude.isValid());
-            }
-            else {
-                LOGW("Couldn't set latitude pos - data is not valid!");
-            }
-            break;
-        }
-        case EXIF_TAG_GPS_LATITUDE_REF: {
-            //ASCII - 2
-            if(entry->size < 1) {
-                LOGW("Latitude ref entry do not contain enought data!");
-                break;
-            }
-
-            const char ref = static_cast<char>(entry->data[0]);
-            if ('N' == ref || 'n' == ref) {          //North
-                m_exif_gps_location.setLatitudeRef(GPS_LOCATION_NORTH);
-                LOGD("Setting ExifInformation gps latitude REF to: NORTH");
-            }
-            else if ('S' == ref || 's' == ref) {     //South
-                m_exif_gps_location.setLatitudeRef(GPS_LOCATION_SOUTH);
-                LOGD("Setting ExifInformation gps latitude REF to: SOUTH");
-            }
-            else {
-                LOGW("Unknown latitude ref: %c (0x%x)", ref, static_cast<int>(ref));
-            }
-            break;
-        }
-        case EXIF_TAG_GPS_ALTITUDE: {
-            //RATIONAL - 1
-            Rational gps_altitude = getRationalFromEntry(entry, exif_data);
-            if(gps_altitude.isValid()) {
-                LOGD("Setting ExifInformation gps altitude to: %f (%s)",
-                        gps_altitude.toDouble(), gps_altitude.toString().c_str());
-                setGpsAltitude(gps_altitude);
-            }
-            else {
-                LOGW("Couldn't set ExifInformation - gps altitude is not valid: %s",
-                        gps_altitude.toString().c_str());
-            }
-            break;
-        }
-        case EXIF_TAG_GPS_ALTITUDE_REF: {
-            //BYTE - 1
-            const ExifByte altitude_ref = static_cast<ExifByte>(entry->data[0]);
-            if(static_cast<ExifByte>(GPS_ALTITUDE_REF_ABOVE_SEA) == altitude_ref ||
-                    static_cast<ExifByte>(GPS_ALTITUDE_REF_BELOW_SEA) == altitude_ref) {
-                setGpsAltitudeRef(static_cast<GpsAltitudeRef>(altitude_ref));
-                LOGD( "Setting ExifInformation gps altitude ref to: %d (%s)",
-                        static_cast<int>(altitude_ref),
-                        (altitude_ref > 0) ? "below sea" : "above sea");
-            } else {
-                LOGW("GPS altitude ref is invalid:%d should be 0 or 1!",
-                        static_cast<int>(altitude_ref));
-            }
-            break;
-        }
-        case EXIF_TAG_GPS_PROCESSING_METHOD: {
-            //UNDEFINED - Any
-            std::string type, value;
-            if(decomposeExifUndefined(entry, type, value)) {
-                LOGD("Extracted GPSProcessingMethod: [%s], len:%d, type:%s",
-                        value.c_str(), value.length(), type.c_str());
-                setGpsProcessingMethod(type, value);
-
-                LOGD("Setting ExifInformation processing method to: [%s], len:%d, type:%s",
-                        m_gps_processing_method.c_str(),
-                        m_gps_processing_method.length(),
-                        m_gps_processing_method_type.c_str());
-            }
-            else {
-                LOGW("GPSProcessingMethod tag contains invalid values!");
-            }
-            break;
-        }
-        case EXIF_TAG_GPS_DATE_STAMP: {
-            //ASCII - 11
-            exif_entry_get_value(entry, buf, sizeof(buf));
-            LOGD( "Setting ExifInformation gps date stamp to: [%s]", buf );
-            m_exif_gps_time.setDate(buf);
-            break;
-        }
-        case EXIF_TAG_GPS_TIME_STAMP: {
-            //Rational - 3
-            exif_entry_get_value(entry, buf, sizeof(buf));
-            LOGD( "Setting ExifInformation gps time stamp to: [%s]", buf);
-
-            Rationals time;
-            if (getRationalsFromEntry(entry, exif_data, 3, time)) {
-                m_exif_gps_time.setTime(time);
-            }
-            break;
-        }
-        case EXIF_TAG_USER_COMMENT: {
-            //UNDEFINED - Any
-            std::string type, value;
-            if(decomposeExifUndefined(entry, type, value)) {
-                LOGD("Extracted UserComment: [%s], len:%d, type:%s",
-                        value.c_str(), value.length(), type.c_str());
-                setUserComment(type, value);
-
-                LOGD("Setting ExifInformation user comment to: [%s], len:%d, type:%s",
-                        m_user_comment.c_str(),
-                        m_user_comment.length(),
-                        m_user_comment_type.c_str());
-            }
-            else {
-                LOGW("UserComment tag contains invalid values!");
-            }
-
-            break;
-        }
-        default:
-            LOGD("Field of tag:%x.H [%s] is not supported, value: [%s]", entry->tag,
-                    exif_tag_get_name_in_ifd(entry->tag, cur_ifd),
-                    exif_entry_get_value(entry, buf, sizeof(buf)));
-    }
-}
-
-struct ExifInfoAndDataHolder {
-    ExifInformationPtr exif_info;
-    ExifData* exif_data;
-};
-
-void ExifInformation::contentForeachFunctionProxy(ExifEntry *entry, void *user_data)
-{
-    ExifInfoAndDataHolder* holder = static_cast<ExifInfoAndDataHolder*>(user_data);
-    if (!holder) {
-        LOGE("holder is NULL");
-    }
-
-    if (!holder->exif_info) {
-        LOGE("exif_info is NULL!");
-        return;
-    }
-
-    if (!holder->exif_data) {
-        LOGE("exif_data is NULL!");
-        return;
-    }
-
-    try {
-        holder->exif_info->processEntry(entry, holder->exif_data);
-    }
-    catch(const BasePlatformException &err) {
-        LOGE("processEntry thrown exception: %s : %s", err.getName().c_str(),
-                    err.getMessage().c_str());
-    }
-    catch(...) {
-        LOGE("Unsupported error while processing Exif entry.");
-    }
-}
-
-void ExifInformation::dataForeachFunction(ExifContent *content, void *user_data)
-{
-    exif_content_foreach_entry(content, contentForeachFunctionProxy, user_data);
-}
-
-
-ExifInformationPtr ExifInformation::loadFromURI(const std::string& uri)
-{
-    ExifInformationPtr exif_info(new ExifInformation());
-    exif_info->setUri(uri);
-
-    const std::string file_path = ExifUtil::convertUriToPath(uri);
-    ExifData* ed = exif_data_new_from_file (file_path.c_str());
-    if (!ed) {
-        LOGE("Error reading exif from file %s", file_path.c_str());
-        throw NotFoundException("Error reading exif from file");
-    }
-
-    LOGD("exif_data_foreach_content START");
-
-    ExifInfoAndDataHolder holder;
-    holder.exif_info = exif_info;
-    holder.exif_data = ed;
-    exif_data_foreach_content(ed, dataForeachFunction, static_cast<void*>(&holder));
-
-    LOGD("exif_data_foreach_content END");
-
-    exif_data_unref(ed);
-    ed = NULL;
-
-    return exif_info;
-}
-
-
-void ExifInformation::removeNulledAttributesFromExifData(ExifData* exif_data)
-{
-    LOGD("Entered");
-    if(!exif_data) {
-        LOGE("exif_data is NULL");
-        throw UnknownException("Invalid Exif provided");
-    }
-
-    if (!isSet(EXIF_INFORMATION_ATTRIBUTE_WIDTH)) {
-        LOGD("Removing width");
-        ExifTagSaver::removeExifEntryWithTag(EXIF_TAG_IMAGE_WIDTH, exif_data);
-    }
-    if (!isSet(EXIF_INFORMATION_ATTRIBUTE_HEIGHT)) {
-        LOGD("Removing height");
-        ExifTagSaver::removeExifEntryWithTag(EXIF_TAG_IMAGE_LENGTH, exif_data);
-    }
-    if (!isSet(EXIF_INFORMATION_ATTRIBUTE_DEVICE_MAKER)) {
-        LOGD("Removing device maker");
-        ExifTagSaver::removeExifEntryWithTag(EXIF_TAG_MAKE, exif_data);
-    }
-    if (!isSet(EXIF_INFORMATION_ATTRIBUTE_ORIENTATION)) {
-        LOGD("Removing orientation");
-        ExifTagSaver::removeExifEntryWithTag(EXIF_TAG_ORIENTATION, exif_data);
-    }
-    if (!isSet(EXIF_INFORMATION_ATTRIBUTE_EXPOSURE_PROGRAM)) {
-        LOGD("Removing exposure program");
-        ExifTagSaver::removeExifEntryWithTag(EXIF_TAG_EXPOSURE_PROGRAM, exif_data);
-    }
-    if (!isSet(EXIF_INFORMATION_ATTRIBUTE_ISO_SPEED_RATINGS)) {
-        LOGD("Removing iso speed ratings");
-        ExifTagSaver::removeExifEntryWithTag(EXIF_TAG_ISO_SPEED_RATINGS, exif_data);
-    }
-    if (!isSet(EXIF_INFORMATION_ATTRIBUTE_WHITE_BALANCE)) {
-        LOGD("Removing white balance");
-        ExifTagSaver::removeExifEntryWithTag(EXIF_TAG_WHITE_BALANCE, exif_data);
-    }
-    if (!isSet(EXIF_INFORMATION_ATTRIBUTE_DEVICE_MODEL)) {
-        LOGD("Removing device model");
-        ExifTagSaver::removeExifEntryWithTag(EXIF_TAG_MODEL, exif_data);
-    }
-    if (!isSet(EXIF_INFORMATION_ATTRIBUTE_ORIGINAL_TIME)) {
-        LOGD("Removing original time");
-        ExifTagSaver::removeExifEntryWithTag(EXIF_TAG_DATE_TIME_ORIGINAL, exif_data);
-    }
-    if (!isSet(EXIF_INFORMATION_ATTRIBUTE_EXPOSURE_TIME)) {
-        LOGD("Removing exposure time");
-        ExifTagSaver::removeExifEntryWithTag(EXIF_TAG_EXPOSURE_TIME, exif_data);
-    }
-    if (!isSet(EXIF_INFORMATION_ATTRIBUTE_FNUMBER)) {
-        LOGD("Removing f-number");
-        ExifTagSaver::removeExifEntryWithTag(EXIF_TAG_FNUMBER, exif_data);
-    }
-    if (!isSet(EXIF_INFORMATION_ATTRIBUTE_FLASH)) {
-        LOGD("Removing flash");
-        ExifTagSaver::removeExifEntryWithTag(EXIF_TAG_FLASH, exif_data);
-    }
-    if (!isSet(EXIF_INFORMATION_ATTRIBUTE_FOCAL_LENGTH)) {
-        LOGD("Removing focal length");
-        ExifTagSaver::removeExifEntryWithTag(EXIF_TAG_FOCAL_LENGTH, exif_data);
-    }
-    if (!isSet(EXIF_INFORMATION_ATTRIBUTE_GPS_ALTITUDE)) {
-        LOGD("Removing gps altitude");
-        ExifTagSaver::removeExifEntryWithTag(
-            static_cast<ExifTag>(EXIF_TAG_GPS_ALTITUDE), exif_data);
-    }
-    if (!isSet(EXIF_INFORMATION_ATTRIBUTE_GPS_ALTITUDE_REF)) {
-        LOGD("Removing gps altitude ref");
-        ExifTagSaver::removeExifEntryWithTag(
-                static_cast<ExifTag>(EXIF_TAG_GPS_ALTITUDE_REF), exif_data);
-    }
-    if (!isSet(EXIF_INFORMATION_ATTRIBUTE_GPS_PROCESSING_METHOD)) {
-        LOGD("Removing gps processing method");
-        ExifTagSaver::removeExifEntryWithTag(
-                static_cast<ExifTag>(EXIF_TAG_GPS_PROCESSING_METHOD), exif_data);
-    }
-    if (!isSet(EXIF_INFORMATION_ATTRIBUTE_USER_COMMENT)) {
-        LOGD("Removing user comment");
-        ExifTagSaver::removeExifEntryWithTag(EXIF_TAG_USER_COMMENT, exif_data);
-    }
-
-    if (!m_exif_gps_location.isSet(EXIF_GPS_LOCATION_ATTRIBUTE_LATITUDE)) {
-        LOGD("Removing latitude");
-        ExifTagSaver::removeExifEntryWithTag(
-                static_cast<ExifTag>(EXIF_TAG_GPS_LATITUDE), exif_data);
-    }
-    if (!m_exif_gps_location.isSet(EXIF_GPS_LOCATION_ATTRIBUTE_LATITUDE_REF)) {
-        LOGD("Removing latitude ref");
-        ExifTagSaver::removeExifEntryWithTag(
-                static_cast<ExifTag>(EXIF_TAG_GPS_LATITUDE_REF), exif_data);
-    }
-    if (!m_exif_gps_location.isSet(EXIF_GPS_LOCATION_ATTRIBUTE_LONGITUDE)) {
-        LOGD("Removing longitude");
-        ExifTagSaver::removeExifEntryWithTag(
-                static_cast<ExifTag>(EXIF_TAG_GPS_LONGITUDE), exif_data);
-    }
-    if (!m_exif_gps_location.isSet(EXIF_GPS_LOCATION_ATTRIBUTE_LONGITUDE_REF)) {
-        LOGD("Removing longitude ref");
-        ExifTagSaver::removeExifEntryWithTag(
-                static_cast<ExifTag>(EXIF_TAG_GPS_LONGITUDE_REF), exif_data);
-    }
-
-    if (!m_exif_gps_time.isTimeSet()) {
-        LOGD("Removing gps time");
-        ExifTagSaver::removeExifEntryWithTag(
-                static_cast<ExifTag>(EXIF_TAG_GPS_TIME_STAMP), exif_data);
-    }
-    if (!m_exif_gps_time.isDateSet()) {
-        LOGD("Removing gps date");
-        ExifTagSaver::removeExifEntryWithTag(
-                static_cast<ExifTag>(EXIF_TAG_GPS_DATE_STAMP), exif_data);
-    }
-}
-
-void ExifInformation::updateAttributesInExifData(ExifData* exif_data)
-{
-    LOGD("Entered");
-    if(!exif_data) {
-        LOGE("exif_data is NULL");
-        throw UnknownException("Invalid Exif provided");
-    }
-
-    if (isSet(EXIF_INFORMATION_ATTRIBUTE_WIDTH)) {
-        LOGD("Saving width: %d", getWidth());
-        ExifTagSaver::saveToExif(getWidth(),
-                EXIF_TAG_IMAGE_WIDTH, exif_data);
-    }
-    if (isSet(EXIF_INFORMATION_ATTRIBUTE_HEIGHT)) {
-        LOGD("Saving height: %d", getHeight());
-        ExifTagSaver::saveToExif(getHeight(),
-                EXIF_TAG_IMAGE_LENGTH, exif_data);
-    }
-    if (isSet(EXIF_INFORMATION_ATTRIBUTE_DEVICE_MAKER)) {
-        LOGD("Saving device maker: %s", getDeviceMaker().c_str());
-        ExifTagSaver::saveToExif(getDeviceMaker(),
-                EXIF_TAG_MAKE, exif_data);
-    }
-    if (isSet(EXIF_INFORMATION_ATTRIBUTE_ORIENTATION)) {
-        LOGD("Saving orientation: %d", static_cast<int>(getOrientation()));
-        ExifTagSaver::saveToExif(static_cast<long int>(getOrientation()),
-                EXIF_TAG_ORIENTATION, exif_data);
-    }
-    if (isSet(EXIF_INFORMATION_ATTRIBUTE_EXPOSURE_PROGRAM)) {
-        LOGD("Saving exposure program: %d", static_cast<int>(getExposureProgram()));
-        ExifTagSaver::saveToExif(getExposureProgram(),
-                EXIF_TAG_EXPOSURE_PROGRAM, exif_data);
-    }
-    if (isSet(EXIF_INFORMATION_ATTRIBUTE_ISO_SPEED_RATINGS)) {
-        std::vector<long long int> iso_ratings = getIsoSpeedRatings();
-        LOGD("Saving iso speed ratings count:%d", iso_ratings.size());
-        ExifTagSaver::saveToExif(iso_ratings, EXIF_FORMAT_SHORT,
-                EXIF_TAG_ISO_SPEED_RATINGS, exif_data);
-    }
-    if (isSet(EXIF_INFORMATION_ATTRIBUTE_WHITE_BALANCE)) {
-        LOGD("Saving white balance: %d", static_cast<int>(getWhiteBalanceMode()));
-        ExifTagSaver::saveToExif(getWhiteBalanceMode(),
-                EXIF_TAG_WHITE_BALANCE, exif_data);
-    }
-    if (isSet(EXIF_INFORMATION_ATTRIBUTE_DEVICE_MODEL)) {
-        LOGD("Saving device model: %s", getDeviceModel().c_str());
-        ExifTagSaver::saveToExif(getDeviceModel(),
-                EXIF_TAG_MODEL, exif_data);
-    }
-    if (isSet(EXIF_INFORMATION_ATTRIBUTE_ORIGINAL_TIME)) {
-        const time_t o_time = getOriginalTime();
-        const std::string o_time_str = ExifUtil::timeTToExifDateTimeOriginal(o_time);
-        LOGD("Saving original time time_t:%d, format:%s", static_cast<int>(o_time),
-                o_time_str.c_str());
-
-        ExifTagSaver::saveToExif(o_time_str,
-                EXIF_TAG_DATE_TIME_ORIGINAL, exif_data);
-    }
-    if (isSet(EXIF_INFORMATION_ATTRIBUTE_EXPOSURE_TIME)) {
-        Rational exposure_time = getExposureTime();
-        if (exposure_time.isValid()) {
-            LOGD("Saving exposure time: %s (%s)",
-                    exposure_time.toString().c_str(),
-                    exposure_time.toExposureTimeString().c_str());
-
-            ExifTagSaver::saveToExif(exposure_time,
-                    EXIF_TAG_EXPOSURE_TIME, exif_data);
-        }
-    }
-    if (isSet(EXIF_INFORMATION_ATTRIBUTE_FNUMBER)) {
-        auto f_number = getFNumber();
-        LOGD("Saving f-number: %f (%s)", f_number.toDouble(),
-                f_number.toString().c_str());
-        ExifTagSaver::saveToExif(f_number,
-                EXIF_TAG_FNUMBER, exif_data);
-    }
-    if (isSet(EXIF_INFORMATION_ATTRIBUTE_FLASH)) {
-        LOGD("Saving flash: %s", getFlash() ? "ON" : "OFF");
-        ExifTagSaver::saveToExif(getFlash(),
-                EXIF_TAG_FLASH, exif_data);
-    }
-    if (isSet(EXIF_INFORMATION_ATTRIBUTE_FOCAL_LENGTH)) {
-        auto f_length = getFocalLength();
-        LOGD("Saving focal length:%f (%s)", f_length.toDouble(),
-                f_length.toString().c_str());
-        ExifTagSaver::saveToExif(f_length,
-                EXIF_TAG_FOCAL_LENGTH, exif_data);
-    }
-    if (isSet(EXIF_INFORMATION_ATTRIBUTE_GPS_ALTITUDE)) {
-        LOGD("Saving gps altitude:%f (%s)", m_gps_altitude.toDouble(),
-                 m_gps_altitude.toString().c_str());
-        ExifTagSaver::saveToExif(m_gps_altitude,
-                static_cast<ExifTag>(EXIF_TAG_GPS_ALTITUDE), exif_data);
-    }
-    if (isSet(EXIF_INFORMATION_ATTRIBUTE_GPS_ALTITUDE_REF)) {
-        //Exif spec:
-        //0 = Sea level
-        //1 = Sea level reference (negative value)
-        LOGD("Saving gps altitude ref:%d (%s)", static_cast<int>(m_gps_altitude_ref),
-                (m_gps_altitude_ref > 0) ? "below sea" : "above sea");
-        ExifTagSaver::saveToExif(static_cast<long int>(m_gps_altitude_ref),
-                static_cast<ExifTag>(EXIF_TAG_GPS_ALTITUDE_REF), exif_data);
-    }
-    if (isSet(EXIF_INFORMATION_ATTRIBUTE_GPS_PROCESSING_METHOD)) {
-        LOGD("Saving gps processing method: [%s] type:%s",
-                getGpsProcessingMethod().c_str(), getGpsProcessingMethodType().c_str());
-
-        const std::string joined = getGpsProcessingMethodType() + getGpsProcessingMethod();
-        LOGD("joined: [%s]", joined.c_str());
-
-        ExifTagSaver::saveToExif(joined,
-                static_cast<ExifTag>(EXIF_TAG_GPS_PROCESSING_METHOD), exif_data, false);
-    }
-    if (isSet(EXIF_INFORMATION_ATTRIBUTE_USER_COMMENT)) {
-        LOGD("Saving user comment: %s (type:%s)", getUserComment().c_str(),
-            getUserCommentType().c_str());
-
-        const std::string joined = getUserCommentType() + getUserComment();
-        LOGD("joined: [%s]", joined.c_str());
-
-        ExifTagSaver::saveToExif(joined,
-                EXIF_TAG_USER_COMMENT, exif_data, false);
-    }
-
-    if(m_gps_location) {
-        m_exif_gps_location.set(m_gps_location);
-    }
-    ExifTagSaver::saveGpsLocationToExif(m_exif_gps_location, exif_data);
-
-    if(m_gps_time) {
-        m_exif_gps_time.setDateAndTime(m_gps_time);
-    }
-    ExifTagSaver::saveGpsTimeToExif(m_exif_gps_time, exif_data);
-}
-
-void ExifInformation::saveToFile(const std::string& file_path)
-{
-    LOGD("Entered");
-    LOGD("Using JpegFile to read: [%s] and Exif if present", file_path.c_str());
-
-    bool exif_data_is_new = false;
-    JpegFilePtr jpg_file = JpegFile::loadFile(file_path);
-    ExifData* exif_data = jpg_file->getExifData();
-
-    //Exif is not present in file - create new ExifData
-    if (!exif_data) {
-        LOGD("Exif is not present in file: [%s] creating new", file_path.c_str());
-
-        exif_data = exif_data_new();
-        exif_data_set_option(exif_data, EXIF_DATA_OPTION_FOLLOW_SPECIFICATION);
-        exif_data_set_data_type(exif_data, EXIF_DATA_TYPE_COMPRESSED);
-        exif_data_set_byte_order(exif_data, EXIF_BYTE_ORDER_MOTOROLA);
-        exif_data_is_new = true;
-    }
-
-    if (!exif_data) {
-        LOGE("Couldn't allocate new ExifData");
-        throw UnknownException("Memory allocation failed");
-    }
-
-    LOGD("Exif data type: %d", exif_data_get_data_type(exif_data) );
-    LOGD("Exif byte order: %d", exif_data_get_byte_order(exif_data) );
-    exif_data_set_option(exif_data, EXIF_DATA_OPTION_FOLLOW_SPECIFICATION);
-
-    try {
-        //If we have created new ExifData there is nothing to remove
-        if(!exif_data_is_new) {
-            //Remove attributes that have been nulled
-            removeNulledAttributesFromExifData(exif_data);
-        }
-
-        updateAttributesInExifData(exif_data);
-
-        LOGD("Using JpegFile to save new Exif in: [%s]", file_path.c_str());
-        if(exif_data_is_new) {
-            jpg_file->setNewExifData(exif_data);
-        }
-
-        jpg_file->saveToFile(file_path);
-    }
-    catch (...) {
-        exif_data_unref(exif_data);
-        exif_data = NULL;
-        throw;
-    }
-
-    exif_data_unref(exif_data);
-    exif_data = NULL;
-}
-
-} // Exif
-} // DeviceAPI
diff --git a/src/exif/old/ExifInformation.h b/src/exif/old/ExifInformation.h
deleted file mode 100644 (file)
index 400dc86..0000000
+++ /dev/null
@@ -1,210 +0,0 @@
-//
-// Tizen Web Device API
-// Copyright (c) 2014 Samsung Electronics Co., Ltd.
-//
-// Licensed 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.
-//
-
-#ifndef __TIZEN_EXIF_EXIFINFORMATION_H_
-#define __TIZEN_EXIF_EXIFINFORMATION_H_
-
-#include <libexif/exif-loader.h>
-#include <string>
-
-#include <JSVector.h>
-#include <TimeDuration.h>
-
-#include "ExifGPSLocation.h"
-#include "ExifGPSTime.h"
-
-namespace DeviceAPI {
-namespace Exif {
-
-class ExifInformation;
-typedef std::shared_ptr<ExifInformation> ExifInformationPtr;
-
-extern const size_t EXIF_UNDEFINED_TYPE_LENGTH;
-extern const std::string EXIF_UNDEFINED_TYPE_ASCII;
-extern const std::string EXIF_UNDEFINED_TYPE_JIS;
-extern const std::string EXIF_UNDEFINED_TYPE_UNICODE;
-extern const std::string EXIF_UNDEFINED_TYPE_UNDEFINED;
-
-enum ExifInformationAttribute{
-    EXIF_INFORMATION_ATTRIBUTE_URI,
-    EXIF_INFORMATION_ATTRIBUTE_WIDTH,
-    EXIF_INFORMATION_ATTRIBUTE_HEIGHT,
-    EXIF_INFORMATION_ATTRIBUTE_DEVICE_MAKER,
-    EXIF_INFORMATION_ATTRIBUTE_DEVICE_MODEL,
-    EXIF_INFORMATION_ATTRIBUTE_ORIGINAL_TIME,
-    EXIF_INFORMATION_ATTRIBUTE_ORIENTATION,
-    EXIF_INFORMATION_ATTRIBUTE_FNUMBER,
-    EXIF_INFORMATION_ATTRIBUTE_ISO_SPEED_RATINGS,
-    EXIF_INFORMATION_ATTRIBUTE_EXPOSURE_TIME,
-    EXIF_INFORMATION_ATTRIBUTE_EXPOSURE_PROGRAM,
-    EXIF_INFORMATION_ATTRIBUTE_FLASH,
-    EXIF_INFORMATION_ATTRIBUTE_FOCAL_LENGTH,
-    EXIF_INFORMATION_ATTRIBUTE_WHITE_BALANCE,
-    EXIF_INFORMATION_ATTRIBUTE_GPS_ALTITUDE,
-    EXIF_INFORMATION_ATTRIBUTE_GPS_ALTITUDE_REF,
-    EXIF_INFORMATION_ATTRIBUTE_GPS_PROCESSING_METHOD,
-    EXIF_INFORMATION_ATTRIBUTE_USER_COMMENT,
-    EXIF_INFORMATION_ATTRIBUTE_NUMBER_OF_ATTRIBUTES
-};
-
-enum GpsAltitudeRef {
-    GPS_ALTITUDE_REF_ABOVE_SEA = 0,
-    GPS_ALTITUDE_REF_BELOW_SEA = 1
-};
-
-class ExifInformation
-{
-public:
-    ExifInformation();
-    ~ExifInformation();
-
-    static ExifInformationPtr loadFromURI(const std::string& uri);
-    void saveToFile(const std::string& file_path);
-
-    const std::string& getUri();
-    void setUri(const std::string& uri);
-
-    unsigned long getWidth() const;
-    void setWidth(unsigned long width);
-
-    unsigned long getHeight() const;
-    void setHeight(unsigned long height);
-
-    const std::string& getDeviceMaker();
-    void setDeviceMaker(const std::string& device_maker);
-
-    const std::string& getDeviceModel();
-    void setDeviceModel(const std::string& device_model);
-
-    time_t getOriginalTime() const;
-    void setOriginalTime(time_t original_time);
-
-    ImageOrientation getOrientation() const;
-    void setOrientation(ImageOrientation orientation);
-
-    const Rational& getFNumber() const;
-    void setFNumber(Rational f_number);
-
-    Common::JSLongLongVector getIsoSpeedRatings();
-    void setIsoSpeedRatings(const std::vector<long long int>& iso_speed_ratings);
-    void appendIsoSpeedRatings(long long int iso_speed_rating);
-
-    const Rational& getExposureTime();
-    void setExposureTime(const Rational& exposure_time);
-
-    ExposureProgram getExposureProgram();
-    void setExposureProgram(ExposureProgram exposure_program );
-
-    bool getFlash() const;
-    void setFlash(bool flash);
-
-    const Rational& getFocalLength() const;
-    void setFocalLength(Rational focal_length);
-
-    WhiteBalanceMode getWhiteBalanceMode() const;
-    void setWhiteBalanceMode(WhiteBalanceMode white_balance);
-
-    ExifGPSLocation& getGPSExifLocation();
-    Tizen::SimpleCoordinatesPtr getGPSLocation();
-    void setGPSLocation(Tizen::SimpleCoordinatesPtr gps_location);
-    void unsetGPSLocation();
-
-    const Rational& getGpsAltitude() const;
-    void setGpsAltitude(Rational gps_altitude);
-
-    GpsAltitudeRef getGpsAltitudeRef() const;
-    void setGpsAltitudeRef(const GpsAltitudeRef ref);
-
-    /**
-     * gps_altitude can be negative and positive:
-     * if gps_altitude < 0.0 GPS_ALTITUDE_REF_BELOW_SEA is set
-     * if gps_altitude >= 0.0 GPS_ALTITUDE_REF_ABOVE_SEA is set
-     */
-    void setGpsAltitudeWithRef(double gps_altitude);
-
-    /**
-     * Return gps altitude which can be negative (below sea level) and positive (above sea
-     * level)
-     */
-    double getGpsAltitudeWithRef() const;
-
-    const std::string& getGpsProcessingMethod() const;
-    const std::string& getGpsProcessingMethodType() const;
-    void setGpsProcessingMethod(const std::string& type,
-            const std::string& processing_method);
-
-    ExifGPSTime& getExifGpsTime();
-    const ExifGPSTime& getExifGpsTime() const;
-    Time::TZDatePtr getGpsTime();
-    void setGpsTime(Time::TZDatePtr new_time);
-    void unsetGPStime();
-
-    const std::string& getUserComment();
-    const std::string& getUserCommentType();
-    void setUserComment(const std::string& type,
-            const std::string& user_comment);
-
-    bool isSet(ExifInformationAttribute attribute) const;
-    void unset(ExifInformationAttribute attribute);
-
-private:
-    void processEntry(ExifEntry* entry, ExifData* exif_data);
-    static void contentForeachFunctionProxy(ExifEntry* entry, void* user_data);
-    static void dataForeachFunction(ExifContent* content, void* user_data);
-
-    void removeNulledAttributesFromExifData(ExifData* exif_data);
-    void updateAttributesInExifData(ExifData* exif_data);
-
-    std::string m_uri;
-    unsigned long m_width;
-    unsigned long m_height;
-    std::string m_device_maker;
-    std::string m_device_model;
-
-    time_t m_original_time;
-
-    ImageOrientation m_orientation;
-    Rational m_f_number;
-    Common::JSLongLongVector m_iso_speed_ratings;
-    Rational m_exposure_time;
-    ExposureProgram m_exposure_program;
-    bool m_flash;
-    Rational m_focal_length;
-    WhiteBalanceMode m_white_balance;
-
-    ExifGPSLocation m_exif_gps_location;
-    Tizen::SimpleCoordinatesPtr m_gps_location;
-
-    Rational m_gps_altitude;
-    GpsAltitudeRef m_gps_altitude_ref;
-
-    std::string m_gps_processing_method;
-    std::string m_gps_processing_method_type;
-
-    ExifGPSTime m_exif_gps_time;
-    Time::TZDatePtr m_gps_time;
-
-    std::string m_user_comment;
-    std::string m_user_comment_type;
-
-    bool m_is_set[EXIF_INFORMATION_ATTRIBUTE_NUMBER_OF_ATTRIBUTES];
-};
-
-} // Exif
-} // DeviceAPI
-
-#endif // __TIZEN_EXIF_EXIFINFORMATION_H_
diff --git a/src/exif/old/ExifTagSaver.cpp b/src/exif/old/ExifTagSaver.cpp
deleted file mode 100644 (file)
index 6f6ebf3..0000000
+++ /dev/null
@@ -1,413 +0,0 @@
-//
-// Tizen Web Device API
-// Copyright (c) 2014 Samsung Electronics Co., Ltd.
-//
-// Licensed 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.
-//
-
-#include "ExifTagSaver.h"
-
-#include <libexif/exif-format.h>
-#include <sstream>
-
-#include <PlatformException.h>
-
-#include "ExifUtil.h"
-
-namespace DeviceAPI {
-
-using namespace DeviceAPI::Common;
-
-namespace Exif {
-
-void ExifTagSaver::removeExifEntryWithTag(const ExifTag tag, ExifData* exif_data)
-{
-    LOGD("Entered tag:%d (0x%x)", tag, tag);
-    ExifEntry* exif_entry = exif_data_get_entry(exif_data, tag);
-    if (!exif_entry) {
-        LOGD("Exif entry with tag:%d (0x%x) is not present", tag, tag);
-        return;
-    }
-
-    exif_content_remove_entry(exif_entry->parent, exif_entry);
-}
-
-void ExifTagSaver::saveToExif(long int value, ExifTag tag, ExifData* exif_data)
-{
-    ExifEntry* entry = prepareEntry(exif_data, tag);
-    ExifByteOrder order = exif_data_get_byte_order(exif_data);
-
-    switch (entry->format) {
-        case EXIF_FORMAT_BYTE:
-            entry->data[0] = static_cast<unsigned char>(value);
-            break;
-        case EXIF_FORMAT_SHORT:
-            exif_set_short (entry->data, order, value);
-            break;
-        case EXIF_FORMAT_LONG:
-            exif_set_long (entry->data, order, value);
-            break;
-        case EXIF_FORMAT_SLONG:
-            exif_set_slong (entry->data, order, value);
-            break;
-        default:
-            LOGE("Error: wrong format: %d \n", entry->format );
-    }
-}
-
-void ExifTagSaver::saveToExif(const std::string& value, ExifTag tag, ExifData* exif_data,
-        bool add_zero_character)
-{
-    ExifEntry* entry = prepareEntry(exif_data, tag);
-    if (!value.empty()) {
-
-        if (entry->data) {
-            free(entry->data);
-            entry->data = NULL;
-        }
-
-        size_t new_len = value.length();
-        if(add_zero_character) {
-            ++new_len;
-        }
-
-        entry->size = new_len;
-        entry->components = new_len;
-
-        entry->data = static_cast<unsigned char*>(malloc(entry->size));
-        memcpy(entry->data, value.c_str(), value.length());
-        if(add_zero_character) {
-            entry->data[value.length()] = '\0';
-        }
-    }
-}
-
-void ExifTagSaver::saveToExif(const Rational& value, ExifTag tag, ExifData* exif_data)
-{
-    ExifEntry* entry = prepareEntry(exif_data, tag);
-    entry->format = EXIF_FORMAT_RATIONAL;
-
-    if (ExifTypeInfo::RationalSize != entry->size) {
-        if (entry->data) {
-            free(entry->data);
-            entry->data = NULL;
-        }
-
-        entry->size = ExifTypeInfo::RationalSize;
-        entry->data = static_cast<unsigned char*>(malloc(entry->size));
-        memset(entry->data, 0, entry->size);
-    }
-
-    entry->components = 1;
-
-    ExifByteOrder order = exif_data_get_byte_order(exif_data);
-    ExifRational r;
-    r.numerator = value.nominator;
-    r.denominator = value.denominator;
-    exif_set_rational(entry->data, order, r);
-}
-
-void ExifTagSaver::saveToExif(const Rationals& value, ExifTag tag, ExifData* exif_data)
-{
-    ExifEntry* entry = prepareEntry(exif_data, tag);
-    ExifByteOrder order = exif_data_get_byte_order(exif_data);
-    entry->format = EXIF_FORMAT_RATIONAL;
-
-    const unsigned int required_size = ExifTypeInfo::RationalSize * value.size();
-    if (required_size != entry->size) {
-        if (entry->data) {
-            free(entry->data);
-            entry->data = NULL;
-        }
-
-        entry->size = required_size;
-        entry->data = static_cast<unsigned char*>(malloc(entry->size));
-        memset(entry->data, 0, entry->size);
-    }
-
-    entry->components = value.size();
-    for(size_t i = 0; i < value.size(); ++i)
-    {
-        ExifRational r;
-        r.numerator = value[i].nominator;
-        r.denominator = value[i].denominator;
-        exif_set_rational(entry->data + i * ExifTypeInfo::RationalSize, order, r);
-    }
-}
-
-void ExifTagSaver::saveToExif(std::vector<long long int>& value, ExifFormat store_as,
-            ExifTag tag, ExifData* exif_data)
-{
-    ExifEntry* entry = prepareEntry(exif_data, tag);
-    const ExifByteOrder order = exif_data_get_byte_order(exif_data);
-
-    const size_t size_per_member = ExifUtil::getSizeOfExifFormatType(store_as);
-    switch (store_as) {
-        case EXIF_FORMAT_BYTE:
-        case EXIF_FORMAT_SHORT:
-        case EXIF_FORMAT_SSHORT:
-        case EXIF_FORMAT_LONG:
-        case EXIF_FORMAT_SLONG:
-            break;
-        default:
-            LOGE("output ExifFormat: %d is not supported!");
-            return;
-    }
-    entry->format = store_as;
-
-    const size_t num_elements = value.size();
-    const unsigned int required_size = size_per_member * num_elements;
-    if (required_size != entry->size) {
-        if (entry->data) {
-            free(entry->data);
-            entry->data = NULL;
-        }
-
-        entry->size = required_size;
-        entry->data = static_cast<unsigned char*>(malloc(entry->size));
-        memset(entry->data, 0, entry->size);
-    }
-    entry->components = num_elements;
-
-
-    switch (store_as) {
-        case EXIF_FORMAT_BYTE: {
-            for(size_t i = 0; i < num_elements; ++i) {
-                entry->data[i] = static_cast<ExifByte>(value[i]);
-            }
-            break;
-        }
-
-        case EXIF_FORMAT_SHORT: {
-            for(size_t i = 0; i < num_elements; ++i) {
-                exif_set_short(entry->data + i * size_per_member, order,
-                        static_cast<ExifShort>(value[i]));
-            }
-            break;
-        }
-
-        case EXIF_FORMAT_SSHORT: {
-            for(size_t i = 0; i < num_elements; ++i) {
-                exif_set_sshort(entry->data + i * size_per_member, order,
-                        static_cast<ExifSShort>(value[i]));
-            }
-            break;
-        }
-
-        case EXIF_FORMAT_LONG: {
-            for(size_t i = 0; i < num_elements; ++i) {
-                exif_set_long(entry->data + i * size_per_member, order,
-                        static_cast<ExifLong>(value[i]));
-            }
-            break;
-        }
-
-        case EXIF_FORMAT_SLONG: {
-            for(size_t i = 0; i < num_elements; ++i) {
-                exif_set_slong(entry->data + i * size_per_member, order,
-                        static_cast<ExifSLong>(value[i]));
-            }
-            break;
-        }
-
-        default:
-            break;
-    }
-
-
-    LOGD("entry after save:");
-    ExifUtil::printExifEntryInfo(entry, exif_data);
-}
-
-void ExifTagSaver::saveGpsLocationToExif(const ExifGPSLocation& gps_info,
-        ExifData* exif_data)
-{
-    if (gps_info.isSet(EXIF_GPS_LOCATION_ATTRIBUTE_LATITUDE)) {
-        auto latitude = gps_info.getLatitude();
-        LOGD("Saving latitude: %s", latitude.toDebugString().c_str());
-        saveToExif(latitude.toRationalsVector(),
-                static_cast<ExifTag>(EXIF_TAG_GPS_LATITUDE), exif_data);
-    }
-
-    if (gps_info.isSet(EXIF_GPS_LOCATION_ATTRIBUTE_LATITUDE_REF)) {
-        std::string lat_ref =
-                (gps_info.getLatitudeRef() == GPS_LOCATION_NORTH) ? "N" : "S";
-        LOGD("Saving latitude ref: %s", lat_ref.c_str());
-        saveToExif(lat_ref, static_cast<ExifTag>(EXIF_TAG_GPS_LATITUDE_REF), exif_data);
-    }
-
-    if (gps_info.isSet(EXIF_GPS_LOCATION_ATTRIBUTE_LONGITUDE)) {
-
-        auto longitude = gps_info.getLongitude();
-        LOGD("Saving longitude: %s", longitude.toDebugString().c_str());
-        saveToExif(longitude.toRationalsVector(),
-                static_cast<ExifTag>(EXIF_TAG_GPS_LONGITUDE), exif_data);
-    }
-
-    if (gps_info.isSet(EXIF_GPS_LOCATION_ATTRIBUTE_LONGITUDE_REF)) {
-        std::string long_ref =
-                (gps_info.getLongitudeRef() == GPS_LOCATION_WEST) ? "W" : "E";
-        LOGD("Saving longitude ref: %s", long_ref.c_str());
-        saveToExif(long_ref, static_cast<ExifTag>(EXIF_TAG_GPS_LONGITUDE_REF), exif_data);
-    }
-}
-
-void ExifTagSaver::saveGpsTimeToExif(const ExifGPSTime& gps_time,
-            ExifData* exif_data)
-{
-    if (gps_time.isTimeSet()) {
-        const Rationals& time = gps_time.getTime();
-        LOGD("Saving gps time: [%s]h [%s]m [%s]d",
-                time[0].toString().c_str(),
-                time[1].toString().c_str(),
-                time[2].toString().c_str());
-
-        saveToExif(time, static_cast<ExifTag>(EXIF_TAG_GPS_TIME_STAMP), exif_data);
-    }
-
-    if (gps_time.isDateSet()) {
-        std::string date = gps_time.getDate();
-        LOGD("Saving gps date: [%s]", date.c_str());
-
-        saveToExif(date, static_cast<ExifTag>(EXIF_TAG_GPS_DATE_STAMP), exif_data);
-    }
-}
-
-ExifEntry* ExifTagSaver::prepareEntry(ExifData* exif_data, ExifTag tag)
-{
-    LOGD("Entered m_tag:%d", tag);
-
-    ExifEntry* exif_entry = exif_data_get_entry(exif_data, tag);
-    if (!exif_entry) {
-        exif_entry = createNewTag(exif_data, deduceIfdSection(tag),
-                deduceDataFormat(tag), tag );
-    }
-
-    if (!exif_entry) {
-        LOGE("Couldn't create new Exif tag");
-        throw UnknownException("Could not save Exif to file");
-    }
-
-    exif_entry_initialize(exif_entry, tag);
-
-    return exif_entry;
-}
-
-ExifEntry* ExifTagSaver::createNewTag(ExifData* exif_data, ExifIfd ifd,
-        ExifFormat format, ExifTag tag)
-{
-    LOGD("Creating new tag: %d", tag);
-
-    ExifEntry* new_entry = exif_entry_new();
-    new_entry->tag = tag;
-    new_entry->format = format;
-    exif_content_add_entry(exif_data->ifd[ifd], new_entry);
-    exif_entry_initialize(new_entry, tag);
-    return new_entry;
-}
-
-ExifIfd ExifTagSaver::deduceIfdSection(ExifTag tag)
-{
-    switch (static_cast<unsigned int>(tag)) {
-        //Tags in IFD_0 Section
-        case EXIF_TAG_MAKE:
-        case EXIF_TAG_MODEL:
-        case EXIF_TAG_IMAGE_WIDTH:
-        case EXIF_TAG_IMAGE_LENGTH:
-        case EXIF_TAG_ORIENTATION:
-            return EXIF_IFD_0;
-
-        //Tags in IFD_EXIF Section
-        case EXIF_TAG_USER_COMMENT:
-        case EXIF_TAG_DATE_TIME_ORIGINAL:
-        case EXIF_TAG_EXPOSURE_TIME:
-        case EXIF_TAG_FNUMBER:
-        case EXIF_TAG_EXPOSURE_PROGRAM:
-        case EXIF_TAG_ISO_SPEED_RATINGS:
-        case EXIF_TAG_WHITE_BALANCE:
-        case EXIF_TAG_FLASH:
-        case EXIF_TAG_FOCAL_LENGTH:
-            return EXIF_IFD_EXIF;
-
-        //Tags in IFD_GPS Section
-        case EXIF_TAG_GPS_LATITUDE_REF:
-        case EXIF_TAG_GPS_LONGITUDE_REF:
-        case EXIF_TAG_GPS_LATITUDE:
-        case EXIF_TAG_GPS_LONGITUDE:
-        case EXIF_TAG_GPS_ALTITUDE:
-        case EXIF_TAG_GPS_ALTITUDE_REF:
-        case EXIF_TAG_GPS_TIME_STAMP:
-        case EXIF_TAG_GPS_PROCESSING_METHOD:
-        case EXIF_TAG_GPS_DATE_STAMP:
-            return EXIF_IFD_GPS;
-
-        //Tags in other sections
-        default:
-            LOGE("Unsupported tag: %d", tag);
-            throw UnknownException("Unsupported tag");
-    }
-}
-
-ExifFormat ExifTagSaver::deduceDataFormat(ExifTag tag)
-{
-    switch (static_cast<unsigned int>(tag)) {
-        //Tags with byte type:
-        case EXIF_TAG_GPS_ALTITUDE_REF:
-            return EXIF_FORMAT_BYTE;
-
-        //Tags with long type:
-        case EXIF_TAG_IMAGE_WIDTH:
-        case EXIF_TAG_IMAGE_LENGTH:
-            return EXIF_FORMAT_LONG;
-
-        //Tags with short type:
-        case EXIF_TAG_ORIENTATION:
-        case EXIF_TAG_EXPOSURE_PROGRAM:
-        case EXIF_TAG_WHITE_BALANCE:
-        case EXIF_TAG_FLASH:
-            return EXIF_FORMAT_SHORT;
-
-        //Tags with ASCII type:
-        case EXIF_TAG_MAKE:
-        case EXIF_TAG_MODEL:
-        case EXIF_TAG_DATE_TIME_ORIGINAL:
-        case EXIF_TAG_GPS_LATITUDE_REF:
-        case EXIF_TAG_GPS_LONGITUDE_REF:
-        case EXIF_TAG_GPS_DATE_STAMP:
-            return EXIF_FORMAT_ASCII;
-
-        //Tags with rational type:
-        case EXIF_TAG_EXPOSURE_TIME:
-        case EXIF_TAG_FNUMBER:
-        case EXIF_TAG_FOCAL_LENGTH:
-        case EXIF_TAG_GPS_LATITUDE:
-        case EXIF_TAG_GPS_LONGITUDE:
-        case EXIF_TAG_GPS_ALTITUDE:
-        case EXIF_TAG_GPS_TIME_STAMP:
-        case EXIF_TAG_ISO_SPEED_RATINGS:
-            return EXIF_FORMAT_RATIONAL;
-
-        //Tags with undefined type:
-        case EXIF_TAG_USER_COMMENT:
-        case EXIF_TAG_GPS_PROCESSING_METHOD:
-            return EXIF_FORMAT_UNDEFINED;
-
-        //Unsupported tags:
-        default:
-            LOGE("Unsupported tag: %d", tag);
-            throw UnknownException("Unsupported tag");
-    }
-}
-
-} // Exif
-} // DeviceAPI
diff --git a/src/exif/old/ExifTagSaver.h b/src/exif/old/ExifTagSaver.h
deleted file mode 100644 (file)
index e1c7c4d..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-//
-// Tizen Web Device API
-// Copyright (c) 2014 Samsung Electronics Co., Ltd.
-//
-// Licensed 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.
-//
-
-/**
- * @file    ExifTagSaver.h
- */
-
-#ifndef __TIZEN_EXIF_EXIF_TAG_SAVER_H__
-#define __TIZEN_EXIF_EXIF_TAG_SAVER_H__
-
-#include <string>
-#include <libexif/exif-data.h>
-
-#include "ExifGPSLocation.h"
-#include "ExifGPSTime.h"
-
-namespace DeviceAPI {
-namespace Exif {
-
-class ExifTagSaver
-{
-public:
-    static void removeExifEntryWithTag(const ExifTag tag, ExifData* exif_data);
-
-    static void saveToExif(long int value, ExifTag tag, ExifData* exif_data);
-    static void saveToExif(const std::string& value, ExifTag tag, ExifData* exif_data,
-            bool add_zero_character = true);
-    static void saveToExif(const Rational& value, ExifTag tag, ExifData* exif_data);
-    static void saveToExif(const Rationals& value, ExifTag tag, ExifData* exif_data);
-    static void saveToExif(std::vector<long long int>& value, ExifFormat store_as,
-            ExifTag tag, ExifData* exif_data);
-    static void saveGpsLocationToExif(const ExifGPSLocation& gps_info,
-            ExifData* exif_data);
-    static void saveGpsTimeToExif(const ExifGPSTime& gps_time,
-            ExifData* exif_data);
-
-private:
-    static ExifEntry* prepareEntry(ExifData* exif_data, ExifTag tag);
-    static ExifIfd deduceIfdSection(ExifTag tag);
-    static ExifFormat deduceDataFormat(ExifTag tag);
-    static ExifEntry* createNewTag(ExifData* exif_data, ExifIfd ifd,
-        ExifFormat format, ExifTag tag);
-};
-
-} // Exif
-} // DeviceAPI
-
-#endif // __TIZEN_EXIF_EXIF_TAG_SAVER_H__
diff --git a/src/exif/old/ExifUtil.cpp b/src/exif/old/ExifUtil.cpp
deleted file mode 100644 (file)
index 53e6690..0000000
+++ /dev/null
@@ -1,431 +0,0 @@
-//
-// Tizen Web Device API
-// Copyright (c) 2014 Samsung Electronics Co., Ltd.
-//
-// Licensed 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.
-//
-
-#include "ExifUtil.h"
-
-#include <iomanip>
-#include <sstream>
-
-#include <Logger.h>
-#include <PlatformException.h>
-
-namespace DeviceAPI {
-
-using namespace DeviceAPI::Common;
-
-namespace Exif {
-
-namespace {
-const std::string ORIENTATION_NORMAL = "NORMAL";
-const std::string ORIENTATION_FLIP_HORIZONTAL = "FLIP_HORIZONTAL";
-const std::string ORIENTATION_ROTATE_180 = "ROTATE_180";
-const std::string ORIENTATION_FLIP_VERTICAL = "FLIP_VERTICAL";
-const std::string ORIENTATION_TRANSPOSE = "TRANSPOSE";
-const std::string ORIENTATION_ROTATE_90 = "ROTATE_90";
-const std::string ORIENTATION_TRANSVERSE = "TRANSVERSE";
-const std::string ORIENTATION_ROTATE_270 = "ROTATE_270";
-
-const std::string WHITE_BALANCE_MODE_AUTO = "AUTO";
-const std::string WHITE_BALANCE_MODE_MANUAL = "MANUAL";
-
-const std::string EXPOSURE_PROGRAM_NOT_DEFINED = "NOT_DEFINED";
-const std::string EXPOSURE_PROGRAM_MANUAL = "MANUAL";
-const std::string EXPOSURE_PROGRAM_NORMAL = "NORMAL";
-const std::string EXPOSURE_PROGRAM_APERTURE_PRIORITY = "APERTURE_PRIORITY";
-const std::string EXPOSURE_PROGRAM_SHUTTER_PRIORITY = "SHUTTER_PRIORITY";
-const std::string EXPOSURE_PROGRAM_CREATIVE_PROGRAM = "CREATIVE_PROGRAM";
-const std::string EXPOSURE_PROGRAM_ACTION_PROGRAM = "ACTION_PROGRAM";
-const std::string EXPOSURE_PROGRAM_PORTRAIT_MODE = "PORTRAIT_MODE";
-const std::string EXPOSURE_PROGRAM_LANDSCAPE_MODE = "LANDSCAPE_MODE";
-
-const std::string DUMMY = ""; // For unexpected input handling
-
-const std::string URI_PREFIX = "file://";
-const std::string URI_ABSOLUTE_PREFIX = "file:///";
-}
-
-const size_t ExifTypeInfo::ByteSize = 1;
-const size_t ExifTypeInfo::ASCIISize = 1;
-const size_t ExifTypeInfo::ShortSize = 2;
-const size_t ExifTypeInfo::LongSize = 4;
-const size_t ExifTypeInfo::RationalSize = 8;
-const size_t ExifTypeInfo::UndefinedSize = 1;
-const size_t ExifTypeInfo::SLongSize = 4;
-const size_t ExifTypeInfo::SRationalSize = 8;
-
-const ExifByte ExifTypeInfo::ByteId = 1;
-const ExifByte ExifTypeInfo::ASCIIId = 2;
-const ExifByte ExifTypeInfo::ShortId = 3;
-const ExifByte ExifTypeInfo::LongId = 4;
-const ExifByte ExifTypeInfo::RationalId = 5;
-const ExifByte ExifTypeInfo::UndefinedId = 7;
-const ExifByte ExifTypeInfo::SLongId = 9;
-const ExifByte ExifTypeInfo::SRationalId = 10;
-
-ExifUtil::ExifUtil()
-{
-}
-
-ExifUtil::~ExifUtil()
-{
-}
-
-ImageOrientation ExifUtil::stringToOrientation(const std::string& orientation)
-{
-    LOGD("Entered");
-    if (ORIENTATION_NORMAL == orientation) {
-        return ImageOrientation::EXIF_ORIENTATION_NORMAL;
-    }
-    if (ORIENTATION_FLIP_HORIZONTAL == orientation) {
-        return ImageOrientation::EXIF_ORIENTATION_FLIP_HORIZONTAL;
-    }
-    if (ORIENTATION_ROTATE_180 == orientation) {
-        return ImageOrientation::EXIF_ORIENTATION_ROTATE_180;
-    }
-    if (ORIENTATION_FLIP_VERTICAL == orientation) {
-        return ImageOrientation::EXIF_ORIENTATION_FLIP_VERTICAL;
-    }
-    if (ORIENTATION_TRANSPOSE == orientation) {
-        return ImageOrientation::EXIF_ORIENTATION_TRANSPOSE;
-    }
-    if (ORIENTATION_ROTATE_90 == orientation) {
-        return ImageOrientation::EXIF_ORIENTATION_ROTATE_90;
-    }
-    if (ORIENTATION_TRANSVERSE == orientation) {
-        return ImageOrientation::EXIF_ORIENTATION_TRANSVERSE;
-    }
-    if (ORIENTATION_ROTATE_270 == orientation) {
-        return ImageOrientation::EXIF_ORIENTATION_ROTATE_270;
-    }
-    return ImageOrientation::EXIF_ORIENTATION_NOT_VALID;
-}
-
-const std::string& ExifUtil::orientationToString(ImageOrientation orientation)
-{
-    LOGD("Entered");
-    switch (orientation) {
-        case ImageOrientation::EXIF_ORIENTATION_NORMAL:
-            return ORIENTATION_NORMAL;
-        case ImageOrientation::EXIF_ORIENTATION_FLIP_HORIZONTAL:
-            return ORIENTATION_FLIP_HORIZONTAL;
-        case ImageOrientation::EXIF_ORIENTATION_ROTATE_180:
-            return ORIENTATION_ROTATE_180;
-        case ImageOrientation::EXIF_ORIENTATION_FLIP_VERTICAL:
-            return ORIENTATION_FLIP_VERTICAL;
-        case ImageOrientation::EXIF_ORIENTATION_TRANSPOSE:
-            return ORIENTATION_TRANSPOSE;
-        case ImageOrientation::EXIF_ORIENTATION_ROTATE_90:
-            return ORIENTATION_ROTATE_90;
-        case ImageOrientation::EXIF_ORIENTATION_TRANSVERSE:
-            return ORIENTATION_TRANSVERSE;
-        case ImageOrientation::EXIF_ORIENTATION_ROTATE_270:
-            return ORIENTATION_ROTATE_270;
-        default:
-            return DUMMY;
-    }
-}
-
-WhiteBalanceMode ExifUtil::stringToWhiteBalance(const std::string& white_balance)
-{
-    LOGD("Entered");
-    if (WHITE_BALANCE_MODE_AUTO == white_balance) {
-        return WhiteBalanceMode::EXIF_WHITE_BALANCE_MODE_AUTO;
-    }
-    if (WHITE_BALANCE_MODE_MANUAL == white_balance) {
-        return WhiteBalanceMode::EXIF_WHITE_BALANCE_MODE_MANUAL;
-    }
-    return WhiteBalanceMode::EXIF_WHITE_BALANCE_MODE_NOT_VALID;
-}
-
-const std::string& ExifUtil::whiteBalanceToString(WhiteBalanceMode value)
-{
-    LOGD("Entered");
-    switch (value) {
-        case WhiteBalanceMode::EXIF_WHITE_BALANCE_MODE_AUTO:
-            return WHITE_BALANCE_MODE_AUTO;
-        case WhiteBalanceMode::EXIF_WHITE_BALANCE_MODE_MANUAL:
-            return WHITE_BALANCE_MODE_MANUAL;
-        default:
-            return DUMMY;
-    }
-}
-
-ExposureProgram ExifUtil::stringToExposureProgram(
-        const std::string& exposure_program)
-{
-    LOGD("Entered");
-    if (EXPOSURE_PROGRAM_NOT_DEFINED == exposure_program) {
-        return EXIF_EXPOSURE_PROGRAM_NOT_DEFINED;
-    }
-    if (EXPOSURE_PROGRAM_MANUAL == exposure_program) {
-        return EXIF_EXPOSURE_PROGRAM_MANUAL;
-    }
-    if (EXPOSURE_PROGRAM_NORMAL == exposure_program) {
-        return EXIF_EXPOSURE_PROGRAM_NORMAL;
-    }
-    if (EXPOSURE_PROGRAM_APERTURE_PRIORITY == exposure_program) {
-        return EXIF_EXPOSURE_PROGRAM_APERTURE_PRIORITY;
-    }
-    if (EXPOSURE_PROGRAM_SHUTTER_PRIORITY == exposure_program) {
-        return EXIF_EXPOSURE_PROGRAM_SHUTTER_PRIORITY;
-    }
-    if (EXPOSURE_PROGRAM_CREATIVE_PROGRAM == exposure_program) {
-        return EXIF_EXPOSURE_PROGRAM_CREATIVE_PROGRAM;
-    }
-    if (EXPOSURE_PROGRAM_ACTION_PROGRAM == exposure_program) {
-        return EXIF_EXPOSURE_PROGRAM_ACTION_PROGRAM;
-    }
-    if (EXPOSURE_PROGRAM_PORTRAIT_MODE == exposure_program) {
-        return EXIF_EXPOSURE_PROGRAM_PORTRAIT_MODE;
-    }
-    if (EXPOSURE_PROGRAM_LANDSCAPE_MODE == exposure_program) {
-        return EXIF_EXPOSURE_PROGRAM_LANDSCAPE_MODE;
-    }
-    return EXIF_EXPOSURE_PROGRAM_NOT_VALID;
-}
-
-const std::string& ExifUtil::exposureProgramToString(ExposureProgram value)
-{
-    LOGD("Entered");
-    switch (value) {
-        case ExposureProgram::EXIF_EXPOSURE_PROGRAM_NOT_DEFINED:
-            return EXPOSURE_PROGRAM_NOT_DEFINED;
-        case ExposureProgram::EXIF_EXPOSURE_PROGRAM_MANUAL:
-            return EXPOSURE_PROGRAM_MANUAL;
-        case ExposureProgram::EXIF_EXPOSURE_PROGRAM_NORMAL:
-            return EXPOSURE_PROGRAM_NORMAL;
-        case ExposureProgram::EXIF_EXPOSURE_PROGRAM_APERTURE_PRIORITY:
-            return EXPOSURE_PROGRAM_APERTURE_PRIORITY;
-        case ExposureProgram::EXIF_EXPOSURE_PROGRAM_SHUTTER_PRIORITY:
-            return EXPOSURE_PROGRAM_SHUTTER_PRIORITY;
-        case ExposureProgram::EXIF_EXPOSURE_PROGRAM_CREATIVE_PROGRAM:
-            return EXPOSURE_PROGRAM_CREATIVE_PROGRAM;
-        case ExposureProgram::EXIF_EXPOSURE_PROGRAM_ACTION_PROGRAM:
-            return EXPOSURE_PROGRAM_ACTION_PROGRAM;
-        case ExposureProgram::EXIF_EXPOSURE_PROGRAM_PORTRAIT_MODE:
-            return EXPOSURE_PROGRAM_PORTRAIT_MODE;
-        case ExposureProgram::EXIF_EXPOSURE_PROGRAM_LANDSCAPE_MODE:
-            return EXPOSURE_PROGRAM_LANDSCAPE_MODE;
-        default:
-            return DUMMY;
-    }
-}
-
-bool ExifUtil::isValidAbsoluteURI(const std::string& uri)
-{
-    return 0 == uri.find(URI_ABSOLUTE_PREFIX);
-}
-
-void ExifUtil::getURIInfo(const std::string& uri,
-        const Filesystem::NodeType expected_type,
-        const std::string& required_permission,
-        bool& out_exists,
-        Filesystem::NodeType& out_type,
-        bool& out_permission_granted)
-{
-    const std::string absolute_path = ExifUtil::convertUriToPath(uri);
-    out_exists = false;
-    out_permission_granted = false;
-
-    try {
-        Filesystem::PathPtr path = Filesystem::Path::create(absolute_path);
-        Filesystem::NodePtr node = Filesystem::Node::resolve(path);
-        out_type = node->getType();
-        out_exists = true;
-
-        if(expected_type == out_type) {
-            out_permission_granted = node->checkPermission(path, required_permission,
-                    expected_type);
-        }
-    }
-    catch (const BasePlatformException &err) {
-        LOGE("Couldn't resolve path: %s, got:%s (%s)", absolute_path.c_str(),
-                (err.getName()).c_str(), (err.getMessage()).c_str());
-    }
-    catch(...) {
-        LOGE("Couldn't resolve path: %s", absolute_path.c_str());
-    }
-}
-
-std::string ExifUtil::convertUriToPath(const std::string& str)
-{
-    std::string path = ltrim(str);
-    std::string prefix = path.substr(0, URI_PREFIX.size());
-
-    if (prefix == URI_PREFIX) {
-        return path.substr(URI_PREFIX.size());
-    }
-    else {
-        return path;
-    }
-}
-
-std::string ExifUtil::ltrim(const std::string& s)
-{
-    std::string str = s;
-    std::string::iterator i;
-    for (i = str.begin(); i != str.end(); i++) {
-        if (!isspace(*i)) {
-            break;
-        }
-    }
-    if (i == str.end()) {
-        str.clear();
-    }
-    else {
-        str.erase(str.begin(), i);
-    }
-    return str;
-}
-
-time_t ExifUtil::exifDateTimeOriginalToTimeT(const char* string)
-{
-    int year, month, day, hour, min, sec;
-    if (sscanf(string, "%d:%d:%d %d:%d:%d",
-                &year, &month, &day, &hour, &min, &sec) >= 6) {
-        return convertToTimeT(year, month, day, hour, min, sec);
-    }
-
-    return 0;
-}
-
-std::string ExifUtil::timeTToExifDateTimeOriginal(time_t time)
-{
-    int year, month, day, hour, min, sec;
-    extractFromTimeT(time, year, month, day, hour, min, sec);
-
-    std::ostringstream ss;
-    ss << std::setfill('0') << std::setw(4) << year << ':' ;
-    ss << std::setfill('0') << std::setw(2) << month << ':' ;
-    ss << std::setfill('0') << std::setw(2) << day << ' ' ;
-
-    ss << std::setfill('0') << std::setw(2) << hour << ':' ;
-    ss << std::setfill('0') << std::setw(2) << min << ':' ;
-    ss << std::setfill('0') << std::setw(2) << sec;
-    return ss.str();
-}
-
-size_t  ExifUtil::getSizeOfExifFormatType(ExifFormat format)
-{
-    size_t size_per_member = 0;
-    switch (format) {
-        case EXIF_FORMAT_BYTE:
-            size_per_member = 1;
-            break;
-
-        case EXIF_FORMAT_SHORT:
-        case EXIF_FORMAT_SSHORT:
-            size_per_member = 2;
-            break;
-
-        case EXIF_FORMAT_LONG:
-        case EXIF_FORMAT_SLONG:
-            size_per_member = 4;
-            break;
-
-        case EXIF_FORMAT_RATIONAL:
-        case EXIF_FORMAT_SRATIONAL:
-            size_per_member = 8;
-            break;
-
-        default:
-            LOGE("output ExifFormat: %d is not supported!");
-            return 0;
-    }
-
-    return size_per_member;
-}
-
-void ExifUtil::printExifEntryInfo(ExifEntry* entry, ExifData* exif_data)
-{
-    char buf[2000];
-    std::stringstream ss;
-
-    if (!entry) {
-        LOGE("entry is null");
-        return;
-    }
-
-    if (!entry->data) {
-        LOGE("entry data is null");
-        return;
-    }
-
-    unsigned char* read_buf_ptr = entry->data;
-
-    size_t size_per_member = getSizeOfExifFormatType(entry->format);
-    if (0 == size_per_member) {
-        size_per_member = 1;    //display as array of bytes
-    }
-
-    for(unsigned long compi = 0; compi < entry->components; ++compi) {
-
-        if (compi > 0) {
-            ss << " ";
-        }
-
-        for(size_t i = 0; i < size_per_member; ++i) {
-            unsigned int value = read_buf_ptr[i];
-            ss << std::hex << std::setw(2) << std::setfill('0') << value;
-        }
-
-        read_buf_ptr += size_per_member;
-    }
-
-    LOGD("Entry{name:%s type:%s size:%d components:%d value:%s RAW DATA:[%s]}",
-            exif_tag_get_name(entry->tag),
-            exif_format_get_name(entry->format),
-            (int)entry->size,
-            (int)entry->components,
-            exif_entry_get_value(entry, buf, sizeof(buf)),
-            ss.str().c_str());
-}
-
-void ExifUtil::extractFromTimeT(const time_t time,
-            int& out_year, int& out_month, int& out_day,
-            int& out_hour, int& out_min, int& out_sec)
-{
-    struct tm* utc = gmtime(&time);
-
-    out_year = utc->tm_year + 1900;
-    out_month = utc->tm_mon + 1;
-    out_day = utc->tm_mday;
-    out_hour = utc->tm_hour;
-    out_min = utc->tm_min;
-    out_sec = utc->tm_sec;
-}
-
-time_t ExifUtil::convertToTimeT(int year, int month, int day,
-            int hour, int min, int sec)
-{
-    time_t tmp_time = 0;
-    struct tm* timeinfo = localtime(&tmp_time);
-    timeinfo->tm_year = year - 1900;
-    timeinfo->tm_mon = month - 1;
-    timeinfo->tm_mday = day;
-
-    timeinfo->tm_hour = hour;
-    timeinfo->tm_min = min;
-    timeinfo->tm_sec = sec;
-
-    //From mktime documentation:
-    //"The values of the members tm_wday and tm_yday of timeptr are ignored"
-    return timegm(timeinfo);
-}
-
-} // Exif
-} // DeviceAPI
diff --git a/src/exif/old/ExifUtil.h b/src/exif/old/ExifUtil.h
deleted file mode 100644 (file)
index b687c62..0000000
+++ /dev/null
@@ -1,153 +0,0 @@
-//
-// Tizen Web Device API
-// Copyright (c) 2014 Samsung Electronics Co., Ltd.
-//
-// Licensed 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.
-//
-
-
-#ifndef __TIZEN_EXIF_EXIFUTIL_H_
-#define __TIZEN_EXIF_EXIFUTIL_H_
-
-#include <libexif/exif-data.h>
-#include <libexif/exif-entry.h>
-#include <libexif/exif-utils.h>
-#include <string>
-#include <vector>
-
-#include <Node.h>
-#include <Path.h>
-#include <TZDate.h>
-
-#include "Rational.h"
-
-namespace DeviceAPI {
-namespace Exif {
-
-enum ImageOrientation {
-    EXIF_ORIENTATION_NORMAL = 1,
-    EXIF_ORIENTATION_FLIP_HORIZONTAL = 2,
-    EXIF_ORIENTATION_ROTATE_180 = 3,
-    EXIF_ORIENTATION_FLIP_VERTICAL = 4,
-    EXIF_ORIENTATION_TRANSPOSE = 5,
-    EXIF_ORIENTATION_ROTATE_90 = 6,
-    EXIF_ORIENTATION_TRANSVERSE = 7,
-    EXIF_ORIENTATION_ROTATE_270 = 8,
-    EXIF_ORIENTATION_NOT_VALID,
-};
-
-enum WhiteBalanceMode {
-    EXIF_WHITE_BALANCE_MODE_AUTO = 0,
-    EXIF_WHITE_BALANCE_MODE_MANUAL = 1,
-    EXIF_WHITE_BALANCE_MODE_NOT_VALID
-};
-
-enum ExposureProgram {
-    EXIF_EXPOSURE_PROGRAM_NOT_DEFINED = 0,
-    EXIF_EXPOSURE_PROGRAM_MANUAL = 1,
-    EXIF_EXPOSURE_PROGRAM_NORMAL = 2,
-    EXIF_EXPOSURE_PROGRAM_APERTURE_PRIORITY = 3,
-    EXIF_EXPOSURE_PROGRAM_SHUTTER_PRIORITY = 4,
-    EXIF_EXPOSURE_PROGRAM_CREATIVE_PROGRAM = 5,
-    EXIF_EXPOSURE_PROGRAM_ACTION_PROGRAM = 6,
-    EXIF_EXPOSURE_PROGRAM_PORTRAIT_MODE = 7,
-    EXIF_EXPOSURE_PROGRAM_LANDSCAPE_MODE = 8,
-    EXIF_EXPOSURE_PROGRAM_NOT_VALID
-};
-
-/**
- * From Exif 2.2 specification:
- *  The following types are used in Exif:
- *  1 = BYTE An 8-bit unsigned integer.,
- *  2 = ASCII An 8-bit byte containing one 7-bit ASCII code. The final byte is terminated
- *      with NULL.,
- *  3 = SHORT A 16-bit (2-byte) unsigned integer,
- *  4 = LONG A 32-bit (4-byte) unsigned integer,
- *  5 = RATIONAL Two LONGs. The first LONG is the numerator and the second LONG expresses
- *      the denominator.,
- *  7 = UNDEFINED An 8-bit byte that can take any value depending on the field definition,
- *  9 = SLONG A 32-bit (4-byte) signed integer (2's complement notation),
- * 10 = SRATIONAL Two SLONGs. The first SLONG is the numerator and the second SLONG is the
- *      denominator.
- */
-struct ExifTypeInfo {
-
-    /**
-     * Number of bytes used by each exif type
-     */
-    static const size_t ByteSize;       //1 byte
-    static const size_t ASCIISize;      //1 byte (*N)
-    static const size_t ShortSize;      //2 bytes
-    static const size_t LongSize;       //4 bytes
-    static const size_t RationalSize;   //8 bytes
-    static const size_t UndefinedSize;  //1 byte (*N)
-    static const size_t SLongSize;      //4 bytes
-    static const size_t SRationalSize;  //8 bytes
-
-    /**
-     * Id values used by Exif to identify type
-     */
-    static const ExifByte ByteId;         // 1
-    static const ExifByte ASCIIId;        // 2
-    static const ExifByte ShortId;        // 3
-    static const ExifByte LongId;         // 4
-    static const ExifByte RationalId;     // 5
-    static const ExifByte UndefinedId;    // 7
-    static const ExifByte SLongId;        // 9
-    static const ExifByte SRationalId;    //10
-};
-
-class ExifUtil
-{
-public:
-    ExifUtil();
-    virtual ~ExifUtil();
-
-    static ImageOrientation stringToOrientation(const std::string& orientation);
-    static const std::string& orientationToString(ImageOrientation value);
-
-    static WhiteBalanceMode stringToWhiteBalance(const std::string& white_balance);
-    static const std::string& whiteBalanceToString(WhiteBalanceMode value);
-
-    static ExposureProgram stringToExposureProgram(const std::string& exposure_program);
-    static const std::string& exposureProgramToString(ExposureProgram value);
-
-    static bool isValidAbsoluteURI(const std::string& uri);
-    static void getURIInfo(const std::string& uri,
-            const Filesystem::NodeType expected_type,
-            const std::string& required_permission,
-            bool& out_exists,
-            Filesystem::NodeType& out_type,
-            bool& out_permission_granted);
-
-    static std::string convertUriToPath(const std::string& str);
-    static std::string ltrim(const std::string& s);
-
-    static time_t exifDateTimeOriginalToTimeT(const char* string);
-    static std::string timeTToExifDateTimeOriginal(time_t time);
-
-    static size_t getSizeOfExifFormatType(ExifFormat format);
-    static void  printExifEntryInfo(ExifEntry* entry, ExifData* exif_data);
-
-    static void extractFromTimeT(const time_t time,
-            int& out_year, int& out_month, int& out_day,
-            int& out_hour, int& out_min, int& out_sec);
-
-    static time_t convertToTimeT(int year, int month, int day,
-            int hour, int min, int sec);
-};
-
-} // EXIF
-} // DeviceApi
-
-#endif // __TIZEN_EXIF_EXIFUTIL_H_
diff --git a/src/exif/old/JpegFile.cpp b/src/exif/old/JpegFile.cpp
deleted file mode 100644 (file)
index a03272e..0000000
+++ /dev/null
@@ -1,733 +0,0 @@
-//
-// Tizen Web Device API
-// Copyright (c) 2014 Samsung Electronics Co., Ltd.
-//
-// Licensed 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.
-//
-
-//
-// For details of JPEG file format see:
-// http://www.media.mit.edu/pia/Research/deepview/exif.html
-
-#include "JpegFile.h"
-
-#include <iomanip>
-#include <limits>
-#include <stdio.h>
-#include <sstream>
-
-#include <Logger.h>
-#include <PlatformException.h>
-
-namespace DeviceAPI {
-
-using namespace DeviceAPI::Common;
-
-namespace Exif {
-
-/**
- * Size of maximal JPEG's section data length
- * (since it is stored as unsigned short limit is 2^16 -1)
- */
-const unsigned int MAX_JPEG_SECTION_DATA_SIZE = 65535;
-
-/**
- * JPEG's section data length includes 2 bytes for length therefore we need to
- * substract 2 from MAX_JPEG_SECTION_DATA_SIZE
- */
-const unsigned int MAX_AVAILABLE_JPEG_SECTION_DATA_SIZE = MAX_JPEG_SECTION_DATA_SIZE - 2;
-
-bool isJpegMarker(const int value)
-{
-    return value >= JPEG_MARKER_LOWEST_ID && value <= JPEG_MARKER_HIGHEST_ID;
-}
-
-JpegMarker castToJpegMarker(const unsigned char byte)
-{
-    if (byte < JPEG_MARKER_LOWEST_ID || byte > JPEG_MARKER_HIGHEST_ID) {
-        return JPEG_MARKER_UNKNOWN;
-    }
-
-    return static_cast<JpegMarker>(byte);
-}
-
-long readUShortBE(unsigned char* src)
-{
-    return ((static_cast<long>(src[0]) << 8) | static_cast<long>(src[1]));
-}
-
-void writeUShortBE(unsigned short value, unsigned char* buffer)
-{
-    buffer[0] = static_cast<unsigned char>(value >> 8);
-    buffer[1] = static_cast<unsigned char>(value);
-}
-
-struct CArrayDeleter {
-  void operator()(void* buffer) { free(buffer); }
-};
-
-JpegFile::JpegFile() :
-    m_in_data(NULL),
-    m_in_data_size(0),
-    m_image_data(NULL),
-    m_image_size(0),
-    m_padding_data(NULL),
-    m_padding_data_size(0),
-    m_in_file(NULL),
-    m_out_file(NULL)
-{
-
-}
-
-JpegFile::~JpegFile()
-{
-    delete [] m_in_data;
-    m_in_data = NULL;
-    m_in_data_size = 0;
-
-    m_padding_data = NULL;
-    m_padding_data_size = 0;
-
-    for(SectionsVec::iterator it = m_sections.begin(); it != m_sections.end(); ++it) {
-        JpegFileSectionPtr cur = *it;
-
-        if (cur->exif_data) {
-            exif_data_unref(cur->exif_data);
-            cur->exif_data = NULL;
-        }
-
-        cur->data_ptr = NULL;
-        cur->size = 0;
-        cur->type = JPEG_MARKER_UNKNOWN;
-    }
-
-    m_image_data = NULL;
-    m_image_size = 0;
-
-    if (m_in_file) {
-        fclose(m_in_file);
-        m_in_file = NULL;
-    }
-
-    if (m_out_file) {
-        fclose(m_out_file);
-        m_out_file = NULL;
-    }
-}
-
-JpegFilePtr JpegFile::loadFile(const std::string& path)
-{
-    JpegFile* new_jpg = new (std::nothrow) JpegFile();
-    if (!new_jpg) {
-        LOGE("Couldn't allocate Jpegfile!");
-        throw UnknownException("Memory allocation failed");
-    }
-
-    JpegFilePtr jpg_ptr(new_jpg);
-    jpg_ptr->load(path);
-    return jpg_ptr;
-}
-
-void JpegFile::load(const std::string& path)
-{
-    LOGD("Entered file:%s", path.c_str());
-
-    m_source_file_path = path;
-
-    m_in_file = fopen(path.c_str(), "rb");
-    if (!m_in_file) {
-        LOGE("Couldn't open Jpeg file: [%s]", path.c_str());
-        throw NotFoundException("Could not open JPG file");
-    }
-
-    fseek(m_in_file, 0, SEEK_END);
-    const size_t in_file_size = static_cast<size_t>(ftell(m_in_file));
-    fseek(m_in_file, 0, SEEK_SET);
-    LOGD("JPEG file: [%s] size:%d", path.c_str(), in_file_size);
-    if (0 == in_file_size) {
-        LOGE("Input file [%s] is empty!", path.c_str());
-        throw UnknownException("JPEG file is invalid");
-    }
-
-    m_in_data = new (std::nothrow) unsigned char[in_file_size];
-    if (!m_in_data) {
-        LOGE("Couldn't allocate buffer with size: %d", in_file_size);
-        throw UnknownException("Memory allocation failed");
-    }
-
-    m_in_data_size = in_file_size;
-
-    const size_t read_bytes = fread(m_in_data, 1, m_in_data_size, m_in_file);
-    if (read_bytes != m_in_data_size) {
-        LOGE("Couldn't read all: %d bytes. Read only: %d bytes!", m_in_data_size,
-                read_bytes);
-        throw UnknownException("Could not read JPEG file");
-    }
-
-    if (fclose(m_in_file) == EOF) {
-        LOGE("Couldn't close input file: %s!", path.c_str());
-    }
-    m_in_file = NULL;
-
-    generateListOfSections();
-}
-
-std::string JpegFile::getPartOfFile(const size_t offset,
-        const size_t num_bytes_before,
-        const size_t num_bytes_after)
-{
-    long long int start = static_cast<long long int>(offset) - num_bytes_before;
-    if (start < 0) {
-        start = 0;
-    }
-
-    long long int end = static_cast<long long int>(offset) + num_bytes_after;
-    if (end >= m_in_data_size) {
-        end = m_in_data_size - 1;
-    }
-
-    std::stringstream ss;
-    ss << std::setfill('0') << std::setw(2) << std::hex;
-    for(long long int i = start; i <= end; ++i) {
-        ss << static_cast<int>(m_in_data[i]);
-    }
-    return ss.str();
-}
-
-
-void JpegFile::generateListOfSections()
-{
-    LOGD("Entered");
-
-    //JPEG starts with:
-    //FFD8 (2 bytes) - SOI Marker
-    //
-    //then:
-    //N sections - format of section:
-    //0xFF(1 byte) + Marker Number(1 byte) + Data size(2 bytes) + Data
-    //
-    //then:
-    //SOS 0xFF(1 byte) + Marker Number(1 byte) + Data size(2 bytes) + Data
-    //
-    //Image data
-    //
-    //FFD9 (2 bytes) - EOI Marker
-    //
-    //Warning: some images taken on Android contains some extra data at the end
-    //we will keep it in m_padding_data
-
-    m_padding_data = NULL;
-    m_padding_data_size = 0;
-
-    for(size_t offset = 0, iterration = 0; offset < m_in_data_size;++iterration) {
-
-        LOGD("offset:%d | Starting iteration: %d", offset, iterration);
-        const size_t search_len = 10;
-        size_t search_offset = 0;
-        for(search_offset = 0; search_offset < search_len; ++search_offset) {
-            //Skip bytes until first no 0xff
-            unsigned char& tmp_marker = m_in_data[offset + search_offset];
-            if (tmp_marker != 0xff) {
-                break;
-            }
-        }
-
-        if (search_len == search_offset) {
-            LOGE("offset:%d | Couldn't find marker! RAW DATA:{%s}", offset,
-                    getPartOfFile(offset, 0, 10).c_str());
-            throw UnknownException("JPEG file is invalid");
-        }
-
-        const size_t section_offset = offset + search_offset - 1;
-        unsigned char* section_begin = m_in_data + section_offset;
-
-        offset = section_offset;    //Move to section begin
-        LOGD("offset:%d | Moved to section begin", offset);
-
-        if (!isJpegMarker(section_begin[1])) {
-            LOGE("offset:%d | Is not valid marker: 0x%x RAW DATA:{%s}", offset,
-                    section_begin[1], getPartOfFile(section_offset,0,4).c_str());
-            throw UnknownException("JPEG file is invalid");
-        }
-
-        const JpegMarker cur_marker = castToJpegMarker(section_begin[1]);
-        LOGD("offset:%d | Found valid marker: 0x%x RAW DATA:{%s}", offset,
-                cur_marker,
-                getPartOfFile(section_offset,0,4).c_str());
-
-        offset += 2;    //Read 0xffxx marker tag - 2 bytes
-
-        JpegFileSectionPtr section;
-        {
-            JpegFileSection* sec = new (std::nothrow) JpegFileSection();
-            if (!sec) {
-                LOGE("Couldn't allocate JpegFileSection");
-                throw UnknownException("Memory allocation failed");
-            }
-
-            section = JpegFileSectionPtr(sec);
-        }
-
-        section->type = cur_marker;
-        m_sections.push_back(section);
-        if (cur_marker == JPEG_MARKER_SOI ||
-            cur_marker == JPEG_MARKER_EOI) {
-            LOGD("offset:%d | Found: %s marker, moving to next marker at:%d",
-                    section_offset, ((cur_marker == JPEG_MARKER_SOI) ? "SOI" : "EOI"),
-                    offset);
-
-            if(cur_marker == JPEG_MARKER_EOI && m_padding_data != NULL) {
-                LOGW("Padding data have been found - do not try to parse end of file");
-                break;
-            }
-        }
-        else {
-            //From JPEG/EXIF info:
-            // Please notice that "Data" contains Data size descriptor, if there is
-            // a Marker like this;
-            //
-            // FF C1 00 0C
-            // It means this Marker(0xFFC1) has 0x000C(equal 12)bytes of data. But the
-            // data size '12' includes "Data size" descriptor, it follows only 10 bytes of
-            // data after 0x000C.
-            //
-
-            const long total_section_len = readUShortBE(section_begin + 2); //Include data
-                                                                            //size 2 bytes
-
-            const long section_data_len = total_section_len - 2;            //Exclude data
-                                                                            //size 2 bytes
-
-            LOGD("offset:%d tag:0x%x | Read total_section_len:%d (data len:%d)",
-                    section_offset, cur_marker, total_section_len, section_data_len);
-
-            offset += 2;    //Read data size - 2 bytes
-
-            if (total_section_len < 0) {
-                LOGE("offset:%d tag:0x%x | Error: total_section_len is: %d < 0", offset,
-                        cur_marker, total_section_len);
-                throw UnknownException("JPEG file is invalid");
-            }
-
-            if (section_offset + 2 + total_section_len > m_in_data_size) {
-                LOGE("offset:%d tag:0x%x | Error: current section offset:%d"
-                        " + 2 + total_section_len:%d = %d is greater then file size:%d",
-                        offset, cur_marker,
-                        section_offset, total_section_len,
-                        section_offset + total_section_len, m_in_data_size);
-                throw UnknownException("JPEG file is invalid");
-            }
-
-            if (JPEG_MARKER_APP1 == cur_marker) {
-                //TODO: verify this
-                //-4 --> 0xFF(1 byte)+Marker Number(1 byte)+Data size(2 bytes))
-                //const unsigned int exif_data_size = section_length - 4;
-
-                const unsigned int exif_data_size = total_section_len + 2;
-                section->exif_data = exif_data_new_from_data (section_begin,
-                        exif_data_size);
-
-                LOGD("offset:%d tag:0x%x | Loading exif from offset:%d"
-                        " len:%d exif_data_new_from_data returned: %p",
-                        offset, cur_marker, section_offset, exif_data_size,
-                        section->exif_data);
-
-                if (!section->exif_data) {
-                    LOGW("offset:%d tag:0x%x | Couldn't load Exif!", offset, cur_marker);
-                }
-            }
-
-            //This just saves pointer not copying data
-            section->data_ptr = section_begin + 2 + 2; //2 bytes marker + 2 bytes data size
-            section->size = section_data_len;  //Exclude data size
-
-            if (JPEG_MARKER_SOS == cur_marker) {
-                //Calculate offset of first image data which is just after this SOS section
-                const size_t image_data_offset = section_offset + 2 + total_section_len;
-
-                //Calculate size of image data from start to expected EOI at end of file.
-                //
-                //-2 (exclude ending EOI marker (2 bytes)
-                size_t image_size = m_in_data_size - image_data_offset - 2;
-                LOGW("offset:%d tag:0x%x | Image data offset:%d Estimated image size:%d",
-                        offset, cur_marker, image_data_offset, image_size);
-
-                m_image_data = m_in_data + image_data_offset;
-
-                size_t eoi_tag_index = 0;
-                bool found_eoi_tag = searchForTagInBuffer(m_in_data + image_data_offset,
-                        m_in_data + m_in_data_size, JPEG_MARKER_EOI, eoi_tag_index);
-                if(!found_eoi_tag) {
-                    LOGE("Could not find EOI tag! Assume that there is no EOI and rest of "
-                            "JPEG file contains image data stream: image_size+= 2");
-                    image_size += 2; //Skip expected EOI tag which is not present
-                } else {
-                    LOGD("EOI tag found at offset: %d from SOS data", eoi_tag_index);
-
-                    if(eoi_tag_index != image_size) {
-                        LOGW("Estimated image size:%d doesn't match EOI tag index:%d"
-                                " delta:%d", image_size, eoi_tag_index,
-                                image_size - eoi_tag_index);
-
-                        LOGW("Setting image_size to EOI tag: %d", eoi_tag_index);
-                        image_size = eoi_tag_index;
-
-                        m_padding_data = m_image_data + image_size + 2; //(skip EOI tag)
-                        m_padding_data_size = (m_in_data + m_in_data_size) - m_padding_data;
-                        LOGW("Saving padding data from offset:%d with size:%d",
-                            m_padding_data - m_in_data, m_padding_data_size);
-                    }
-                }
-
-                m_image_size = image_size;
-
-                offset = image_data_offset + image_size;
-                LOGD("offset:%d tag:0x%x | SOS Offset moved to next marker", offset,
-                        cur_marker);
-            }
-            else {
-                offset += section_data_len;
-                LOGD("offset:%d tag:0x%x | Offset moved to next marker", offset, cur_marker);
-            }
-        }
-    }
-}
-
-bool JpegFile::searchForTagInBuffer(const unsigned char* buffer_start,
-        const unsigned char* buffer_end,
-        const JpegMarker marker,
-        size_t& out_index)
-{
-    LOGD("Entered start:%p end:%p marker:0x%x", buffer_start, buffer_end, marker);
-
-    if(!buffer_start) {
-        LOGE("buffer_start is NULL");
-        return false;
-    }
-
-    if(!buffer_end) {
-        LOGE("buffer_end is NULL");
-        return false;
-    }
-
-    if(buffer_end <= buffer_start) {
-        LOGE("buffer_end: %p <= buffer_start: %p", buffer_end, buffer_start);
-        return false;
-    }
-
-    LOGD("Bytes to scan: %d", static_cast<size_t>(buffer_end - buffer_start));
-    const unsigned char marker_uchar = static_cast<unsigned char>(marker);
-
-    for(const unsigned char* ptr = buffer_start; ptr < buffer_end; ++ptr) {
-
-        if((0xff == *ptr) && (ptr+1 < buffer_end)) {
-            if(marker_uchar == *(ptr+1)) {
-                out_index = static_cast<size_t>(ptr - buffer_start);
-                return true;
-            }
-        }
-    }
-
-    out_index = 0;
-    return false;
-}
-
-void JpegFile::setNewExifData(ExifData* new_exif_data)
-{
-    if (!new_exif_data) {
-        LOGE("Trying to set NULL exif_data!");
-        throw UnknownException("Could not save Exif in JPEG file");
-    }
-
-    JpegFileSectionPtr exif = getExifSection();
-    if (!exif) {
-        LOGW("Could't find Exif section - creating new one");
-        {
-            JpegFileSection* new_sec = new (std::nothrow) JpegFileSection();
-            if (!new_sec) {
-                LOGE("Couldn't allocate JpegFileSection");
-                throw UnknownException("Memory allocation failed");
-            }
-            new_sec->type = JPEG_MARKER_APP1;
-
-            exif = JpegFileSectionPtr(new_sec);
-        }
-
-        SectionsVec::iterator insert_it = m_sections.begin();
-        bool soi_is_present = false;
-
-        if (insert_it != m_sections.end()) {
-            if ((*insert_it)->type != JPEG_MARKER_SOI) {
-                LOGW("First section is not SOI - Start Of Image!");
-            }
-            else {
-                soi_is_present = true;
-            }
-        }
-
-        if (!soi_is_present) {
-            LOGW("SOI section is missing");
-            throw UnknownException("JPEG file is invalid");
-        }
-
-        //Insert new Exif sections just after SOI
-        ++insert_it;
-        if (insert_it != m_sections.begin()) {
-            m_sections.insert(insert_it, exif);
-        }
-        else {
-            //This shouldn't happen since we at lest need SOS and EOI sections
-            m_sections.push_back(exif);
-        }
-    }
-
-    //We don't want to save old data
-    exif->data_ptr = NULL;
-    exif->size = 0;
-
-    exif_data_unref(exif->exif_data);
-    exif_data_ref (new_exif_data);
-    exif->exif_data = new_exif_data;
-}
-
-ExifData* JpegFile::getExifData()
-{
-    JpegFileSectionPtr exif = getExifSection();
-    if (!exif) {
-        return NULL;
-    }
-
-    exif_data_ref(exif->exif_data);
-    return exif->exif_data;
-}
-
-void JpegFile::saveToFile(const std::string& out_path)
-{
-    LOGD("Entered out_path:%s", out_path.c_str());
-    try {
-        saveToFilePriv(out_path);
-    }
-    catch (...) {
-        LOGE("Exception occured during saveToFilePriv "
-                "original file: [%] new: [%s]",
-                m_source_file_path.c_str(),
-                out_path.c_str());
-
-        if (out_path == m_source_file_path) {
-
-            LOGD("Trying to recover broken JPEG file: [%s]", out_path.c_str());
-            //We were writing to source file and since something went wrong let's
-            //restore old file - we have it in m_in_data
-
-            FILE* outf = fopen(out_path.c_str(), "wb");
-            if (!outf) {
-                LOGE("Couldn't open output file: [%s] - JPEG file will not be restored!");
-            }
-            else {
-                size_t bytes_wrote = fwrite(m_in_data, 1, m_in_data_size, outf);
-                if (bytes_wrote != m_in_data_size) {
-                    LOGE("Couldn't restore whole JPEG! "
-                            "Only %d of %d bytes have been wrote!",
-                            bytes_wrote, m_in_data_size);
-                }
-                if (EOF == fclose(outf)) {
-                    LOGE("Couldn't close restore output file: [%s]", out_path.c_str());
-                }
-            }
-        }
-
-        throw;
-    }
-}
-
-void JpegFile::saveToFilePriv(const std::string& out_path)
-{
-    LOGD("Entered out_path:%s", out_path.c_str());
-
-    m_out_file = fopen(out_path.c_str(), "wb");
-    if (!m_out_file) {
-        LOGE("Couldn't open output file: %s", out_path.c_str());
-        throw UnknownException("Could not write JPEG file");
-    }
-
-    unsigned char tmp_buf[128];
-    size_t offset = 0;
-
-    int section_index = 0;
-    for(SectionsVec::iterator it = m_sections.begin();
-            it != m_sections.end();
-            ++it, ++ section_index) {
-
-        JpegFileSectionPtr cur = *it;
-        const JpegMarker cur_marker = cur->type;
-
-        LOGD("offset:%d | Section: %d marker 0x%x", offset, section_index, cur_marker);
-
-        size_t bytes_to_write = 0;
-        size_t bytes_wrote = 0;
-
-        tmp_buf[0] = 0xff;
-        tmp_buf[1] = cur_marker;
-        bytes_to_write += 2;
-
-        bool write_section_data = false;
-
-        bool write_exif_data = false;
-
-        std::unique_ptr<unsigned char, CArrayDeleter> exif_output_data;
-        unsigned int exif_output_size = 0;
-
-        if (cur_marker != JPEG_MARKER_SOI &&
-                cur_marker != JPEG_MARKER_EOI) {
-
-            unsigned short section_size = 2;
-            if (JPEG_MARKER_APP1 && cur->exif_data) {
-
-                unsigned char* tmp = NULL;
-                exif_data_save_data (cur->exif_data, &tmp, &exif_output_size);
-                if (!tmp || 0 == exif_output_size) {
-                    LOGE("Couldn't generate RAW Exif data!");
-                    throw UnknownException("Could not save Exif in JPEG file");
-                }
-
-                LOGD("offset:%d | Generated Exif RAW Data length:%d", offset,
-                        exif_output_size);
-
-                exif_output_data.reset(tmp);
-
-                if (exif_output_size > MAX_AVAILABLE_JPEG_SECTION_DATA_SIZE) {
-                    LOGE("exif_output_size:%d is greater then maximum JPEG section"
-                            "data block size: %d", exif_output_size,
-                            MAX_AVAILABLE_JPEG_SECTION_DATA_SIZE);
-                    throw UnknownException("Exif data is to big to be saved in JPEG file");
-                }
-                section_size += exif_output_size;
-                write_exif_data = true;
-            }
-            else {
-                section_size += cur->size;
-                write_section_data = true;
-            }
-
-            writeUShortBE(section_size, tmp_buf + bytes_to_write);
-            bytes_to_write += 2;
-        }
-
-        LOGD("offset:%d | Writing section: marker:0x%x size:%d", offset, cur_marker,
-                cur->size);
-
-        bytes_wrote = fwrite(tmp_buf, 1, bytes_to_write, m_out_file);
-        offset += bytes_wrote;
-
-        if (bytes_wrote != bytes_to_write) {
-            LOGE("Couldn't wrote %d bytes! Only %d bytes wrote", bytes_to_write,
-                    bytes_wrote);
-            throw UnknownException("Could not write JPEG file");
-        }
-
-        if (write_section_data && cur->size > 0) {
-            LOGD("offset:%d | Writing data with length:%d", offset, cur->size);
-
-            bytes_to_write = cur->size;
-            bytes_wrote = fwrite(cur->data_ptr, 1, bytes_to_write, m_out_file);
-            offset += bytes_wrote;
-
-            if (bytes_wrote != bytes_to_write) {
-                LOGE("Couldn't wrote %d bytes! Only %d bytes wrote", bytes_to_write,
-                        bytes_wrote);
-                throw UnknownException("Could not write JPEG file");
-            }
-        }
-
-        if (write_exif_data && exif_output_data && exif_output_size > 0) {
-            LOGD("offset:%d | Writing new exif data with length:%d", offset,
-                    exif_output_size);
-
-            bytes_to_write = exif_output_size;
-            bytes_wrote = fwrite(exif_output_data.get(), 1, bytes_to_write, m_out_file);
-            offset += bytes_wrote;
-
-            if (bytes_wrote != bytes_to_write) {
-                LOGE("Couldn't wrote %d bytes! Only %d bytes wrote", bytes_to_write,
-                        bytes_wrote);
-                throw UnknownException("Could not write JPEG file");
-            }
-        }
-
-        if (JPEG_MARKER_SOS == cur_marker) {
-            LOGD("offset:%d | Writing image data stream with lenght:%d", offset,
-                    m_image_size);
-
-            bytes_to_write = m_image_size;
-            bytes_wrote = fwrite(m_image_data, 1, bytes_to_write, m_out_file);
-            offset += bytes_wrote;
-
-            if (bytes_wrote != bytes_to_write) {
-                LOGE("Couldn't wrote %d bytes! Only %d bytes wrote", bytes_to_write,
-                        bytes_wrote);
-                throw UnknownException("Could not write JPEG file");
-            }
-        }
-    }
-
-    if(m_padding_data && m_padding_data_size > 0) {
-        LOGD("Padding data exists and contains:%d bytes saving to JPEG file");
-        const size_t bytes_wrote = fwrite(m_image_data, 1, m_padding_data_size,
-                m_out_file);
-
-        if (bytes_wrote != m_padding_data_size) {
-            LOGE("Couldn't wrote %d bytes! Only %d bytes wrote", m_padding_data_size,
-                    bytes_wrote);
-            throw UnknownException("Could not write JPEG file");
-        }
-    }
-
-    if (fclose(m_out_file) == EOF) {
-        LOGE("Couldn't close output file: %s", out_path.c_str());
-        m_out_file = NULL;
-    }  else {
-        m_out_file = NULL;
-        LOGD("Closed output file: %s wrote:%d bytes: %d", out_path.c_str(), offset);
-    }
-}
-
-JpegFileSectionPtr JpegFile::getExifSection()
-{
-    size_t num_exif_sections = 0;
-    JpegFileSectionPtr first_exif_section;
-
-    for(SectionsVec::iterator it = m_sections.begin(); it != m_sections.end(); ++it) {
-        JpegFileSectionPtr cur = *it;
-
-        if (JPEG_MARKER_APP1 == cur->type) {
-            if (!cur->exif_data) {
-                LOGW("Warning: found APP1 section but exif_data is NULL (Not Exif?)");
-                continue;
-            }
-
-            ++num_exif_sections;
-            if (!first_exif_section) {
-                first_exif_section = cur;
-            }
-            else {
-                LOGW("Warning: found %d APP1/Exif sections - only first is currently supported!");
-            }
-        }
-    }
-
-    return first_exif_section;
-}
-
-
-} // namespace Exif
-} // namespace DeviceAPI
diff --git a/src/exif/old/JpegFile.h b/src/exif/old/JpegFile.h
deleted file mode 100644 (file)
index bde6959..0000000
+++ /dev/null
@@ -1,138 +0,0 @@
-//
-// Tizen Web Device API
-// Copyright (c) 2014 Samsung Electronics Co., Ltd.
-//
-// Licensed 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.
-//
-
-
-#ifndef __TIZEN_EXIF_JPEG_FILE_H_
-#define __TIZEN_EXIF_JPEG_FILE_H_
-
-#include <memory>
-#include <string>
-#include <vector>
-#include <stdio.h>
-#include <map>
-#include <libexif/exif-data.h>
-#include <libexif/exif-entry.h>
-#include <libexif/exif-utils.h>
-
-namespace DeviceAPI {
-namespace Exif {
-
-enum JpegMarker{
-    JPEG_MARKER_UNKNOWN     = 0x00,
-    JPEG_MARKER_LOWEST_ID   = 0xc0,
-    JPEG_MARKER_SOI         = 0xd8, //Start Of Image
-    JPEG_MARKER_EOI         = 0xd9, //End Of Image
-    JPEG_MARKER_SOS         = 0xda, //Start Of Stream
-    JPEG_MARKER_APP1        = 0xe1, //Application Data 1 - for Exif
-    JPEG_MARKER_HIGHEST_ID  = 0xfe
-};
-
-struct JpegFileSection;
-typedef std::shared_ptr<JpegFileSection> JpegFileSectionPtr;
-
-struct JpegFileSection
-{
-    JpegFileSection() :
-        type(JPEG_MARKER_UNKNOWN),
-        data_ptr(NULL),
-        size(0),
-        exif_data(NULL) {};
-
-    JpegMarker type;
-    unsigned char* data_ptr;
-    unsigned short size;
-
-    ExifData* exif_data;
-};
-
-
-class JpegFile;
-typedef std::shared_ptr<JpegFile> JpegFilePtr;
-
-class JpegFile {
-public:
-    static JpegFilePtr loadFile(const std::string& path);
-    ~JpegFile();
-
-    void setNewExifData(ExifData* new_exif_data);
-
-    /**
-     * You are responsible to unreference returned data with: exif_data_unref(...)
-     * Example:
-     *     ExifData* ed = jpeg.getExifData();
-     *     if(ed) {
-     *         doSth(ed);
-     *         exif_data_unref(ed);
-     *     }
-     */
-    ExifData* getExifData();
-
-    void saveToFile(const std::string& out_path);
-
-private:
-    JpegFile();
-    void load(const std::string& path);
-    void generateListOfSections();
-
-    std::string getPartOfFile(const size_t offset,
-            const size_t num_bytes_before = 10,
-            const size_t num_bytes_after = 10);
-
-    JpegFileSectionPtr getExifSection();
-    void saveToFilePriv(const std::string& out_path);
-
-    /**
-     * Search for first occurence of specific tag inside buffer.
-     *
-     * buffer_end is the first byte that should not be checked:
-     * [buffer_start ... buffer_end)
-     *
-     * For example EOI - search for first 'ffd9' in buffer
-     */
-    static bool searchForTagInBuffer(const unsigned char* buffer_start,
-            const unsigned char* buffer_end,
-            const JpegMarker marker,
-            size_t& out_index);
-
-    std::string m_source_file_path;
-
-    unsigned char* m_in_data;
-    size_t m_in_data_size;
-
-    unsigned char* m_image_data;
-    size_t m_image_size;
-
-    /**
-     * This contains any bytes after EOI.
-     * Usually there should be no extra bytes after EOI unfortunately
-     * some cameras saves extra bytes (for example Android).
-     */
-    unsigned char* m_padding_data;
-    size_t m_padding_data_size;
-
-    FILE* m_in_file;
-    FILE* m_out_file;
-
-    typedef std::vector<JpegFileSectionPtr> SectionsVec;
-    SectionsVec m_sections;
-};
-
-
-} // namespace Exif
-} // namespace DeviceApi
-
-#endif // __TIZEN_EXIF_JPEG_FILE_H_
diff --git a/src/exif/old/Rational.cpp b/src/exif/old/Rational.cpp
deleted file mode 100644 (file)
index 3b7c49f..0000000
+++ /dev/null
@@ -1,270 +0,0 @@
-//
-// Tizen Web Device API
-// Copyright (c) 2014 Samsung Electronics Co., Ltd.
-//
-// Licensed 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.
-//
-
-#include "Rational.h"
-
-#include <Logger.h>
-
-namespace DeviceAPI {
-namespace Exif {
-
-namespace {
-const double DOUBLE_ERROR_REPRESENTATION = static_cast<double>(0x7FFFFFFF);
-} //anonymous namespace
-
-Rational::Rational() :
-        nominator(0),
-        denominator(0)
-{
-}
-
-Rational::Rational(ExifLong nom, ExifLong denom) :
-        nominator(nom),
-        denominator(denom)
-{
-}
-
-Rational::Rational(const ExifRational& exif_rational) :
-        nominator(exif_rational.numerator),
-        denominator(exif_rational.denominator)
-{
-}
-
-Rational Rational::createFromDouble(const double value, const long precision)
-{
-    LOGD("Entered value:%f precision:%d", value, precision);
-    if (value < 0.0) {
-        LOGW("Trying to create negative Rational: %f!", value);
-        return Rational();
-    }
-
-    if (value < 0.000000001) {
-        LOGD("Skipping calculation returning: Rational(0,1)");
-        return Rational(0,1);
-    }
-
-    long m[2][2];
-    double x, startx;
-    long ai;
-
-    startx = x = value;
-
-    // initialize matrix
-    m[0][0] = m[1][1] = 1;
-    m[0][1] = m[1][0] = 0;
-
-    //loop finding terms until denom gets too big
-    do {
-        ai = static_cast<long>(x);
-        if(m[1][0] * ai + m[1][1] > precision) {
-            break;
-        }
-
-        long t = m[0][0] * ai + m[0][1];
-        m[0][1] = m[0][0];
-        m[0][0] = t;
-
-        t = m[1][0] * ai + m[1][1];
-        m[1][1] = m[1][0];
-        m[1][0] = t;
-
-        if (x == static_cast<double>(ai)) {
-            break;     // AF: division by zero
-        }
-
-        x = 1 / (x - static_cast<double>(ai));
-        if (x > DOUBLE_ERROR_REPRESENTATION) {
-            break;  // AF: representation failure
-        }
-    } while(1);
-
-    // now remaining x is between 0 and 1/ai
-    // approx as either 0 or 1/m where m is max that will fit in precision
-    // first try zero
-    const double error0 = startx - ((double) m[0][0] / (double) m[1][0]);
-    const long numerator0 = m[0][0];
-    const long denominator0 = m[1][0];
-
-    LOGD("%ld/%ld, error = %e\n", numerator0, denominator0, error0);
-
-    /* now try other possibility */
-    ai = (precision - m[1][1]) / m[1][0];
-    m[0][0] = m[0][0] * ai + m[0][1];
-    m[1][0] = m[1][0] * ai + m[1][1];
-
-    double error1m = startx -
-            (static_cast<double>(m[0][0]) / static_cast<double>(m[1][0]));
-    LOGD("%ld/%ld, error = %e\n", m[0][0], m[1][0], error1m );
-
-    long result_numerator = 0;
-    long result_denominator = 0;
-
-    if (error0 < error1m ) {
-        result_numerator = numerator0;
-        result_denominator = denominator0;
-    }
-    else {
-        result_numerator = m[0][0];
-        result_denominator = m[1][0];
-    }
-
-    if (result_numerator < 0) {
-        result_numerator *= -1;
-    }
-    if (result_denominator < 0) {
-        result_denominator *= -1;
-    }
-
-    LOGD("Rational(%d, %d) error0 < error1m:%d", result_numerator, result_denominator,
-            error0 < error1m);
-
-    return Rational(numerator0, denominator0);
-}
-
-Rational Rational::createInvalid()
-{
-    return Rational(0,0);
-}
-
-bool Rational::isValid() const
-{
-    if (0 == denominator) {
-        return false;
-    }
-    else {
-        return true;
-    }
-}
-
-double Rational::toDouble() const
-{
-    if (!isValid()) {
-        return NAN;
-    }
-
-    return (double)nominator / (double)denominator;
-}
-
-Rational Rational::createFromExposureTimeString(const std::string& exp_time)
-{
-    LOGD("Entered");
-    if (exp_time.length() == 0) {
-        return Rational::createInvalid();  //lets assume that empty string means 0,
-                                           //however exposure time = 0 is not valid value
-    }
-
-    std::string integer_part;
-    std::string fraction_part;
-
-    int first_space_at = -1;
-    int first_slash_at = -1;
-
-    for(size_t i=0; i < exp_time.size(); ++i) {
-
-        const char& cur = exp_time[i];
-        if (first_space_at < 0 && ' ' == cur) {
-            first_space_at = i;
-        }
-        if (first_slash_at < 0 && '/' == cur) {
-            first_slash_at = i;
-        }
-    }
-
-    if (first_slash_at > 0) {
-        if (first_space_at > 0) {
-            integer_part = exp_time.substr(0,first_space_at);
-            fraction_part = exp_time.substr(first_space_at+1,
-                    exp_time.size() - (first_space_at+1));
-        }
-        else {
-            fraction_part = exp_time;
-        }
-    }
-    else {
-        integer_part = exp_time;
-    }
-
-    LOGD("first_space_at: %d first_slash_at:%d int: [%s] , frac: [%s]",
-            first_space_at, first_slash_at, integer_part.c_str(), fraction_part.c_str());
-
-    long integer_value = 0;
-    long nominator = 0;
-    long denominator = 1;
-
-    if (integer_part.length() > 0) {
-        integer_value = atol(integer_part.c_str());
-    }
-
-    if (fraction_part.length() > 0) {
-        if (sscanf(fraction_part.c_str(), "%ld/%ld", &nominator, &denominator) != 2) {
-            LOGD("Failed to parse nominator/denominator string: [%s]",
-                    fraction_part.c_str());
-            return Rational::createInvalid();
-        }
-    }
-
-    nominator += denominator * integer_value;
-    LOGD("%d/%d -> %f", nominator, denominator, (float)nominator / denominator);
-
-    if (0 == nominator) {
-        //Exposure time = 0 is invalid value
-        return Rational::createInvalid();
-    }
-
-    return Rational(nominator, denominator);
-}
-
-std::string Rational::toString() const
-{
-    std::stringstream ss;
-    ss << nominator << "/" << denominator;
-    return ss.str();
-}
-
-std::string Rational::toExposureTimeString() const
-{
-    LOGD("Entered");
-    if (!isValid() || 0 == nominator) {
-        return std::string();
-    }
-
-    std::string output_str;
-
-    if (nominator < denominator) {
-        output_str = toString();
-    }
-    else if (nominator % denominator == 0) {
-        std::stringstream ss;
-        ss << nominator / denominator;
-        output_str = ss.str();
-    }
-    else {
-        ExifLong new_nominator = nominator % denominator;
-        ExifLong new_denominator = denominator;
-        ExifLong integer_value = nominator / denominator;
-
-        std::stringstream ss;
-        ss << integer_value << " ";
-        ss << new_nominator << "/" << new_denominator;
-        output_str = ss.str();
-    }
-
-    return output_str;
-}
-
-} // Exif
-} // DeviceAPI
\ No newline at end of file
diff --git a/src/exif/old/Rational.h b/src/exif/old/Rational.h
deleted file mode 100644 (file)
index 4903759..0000000
+++ /dev/null
@@ -1,97 +0,0 @@
-//
-// Tizen Web Device API
-// Copyright (c) 2014 Samsung Electronics Co., Ltd.
-//
-// Licensed 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.
-//
-
-
-#ifndef __TIZEN_EXIF_RATIONAL_H_
-#define __TIZEN_EXIF_RATIONAL_H_
-
-#include <string>
-#include <vector>
-#include <memory>
-
-#include <libexif/exif-utils.h>
-#include <libexif/exif-entry.h>
-#include <libexif/exif-data.h>
-
-#include "ExifUtil.h"
-
-namespace DeviceAPI {
-namespace Exif {
-
-class Rational;
-typedef std::vector<Rational> Rationals;
-typedef std::shared_ptr<Rationals> RationalsPtr;
-
-/**
- * This class represents fraction as nominator/denominator - two ExifLong values
- * Rational type is present in Exif specification - used for example in GPS coordinates
- */
-class Rational
-{
-public:
-    /**
-     * Default constructor sets to 0/0 - invalud rational number
-     */
-    Rational();
-
-    Rational(ExifLong nom, ExifLong denom);
-    Rational(const ExifRational& exif_rational);
-
-    static Rational createFromDouble(const double value, const long precision = 1000);
-    static Rational createInvalid();
-
-    /**
-     * Returns true if denominator is valid (!= 0) and therefore whole Rational is valid
-     */
-    bool isValid() const;
-
-    double toDouble() const;
-
-    /**
-     * Returns string in format: nominator/denominator,
-     * for example: "1/4", "1/1", "5/3".
-     *
-     */
-    std::string toString() const;
-
-    /**
-     * Create rational number from exposure string
-     * Accepted format "(integer) (nominator/denominator)"
-     * for example:
-     * "1/5", "4/5" - just fraction part
-     * "1", "5" - just integer part
-     * "1 1/5", "4 1/4" - integer + fraction part
-     */
-    static Rational createFromExposureTimeString(const std::string& exp_time);
-
-    /**
-     * Return time exposure string in following format:
-     *
-     * nominator < denominator                               : "1/5", "4/5"
-     * nominator == x*denominator                            : "1", "5"
-     * nominator > denominator && nominator != x*denominator : "1 1/5", "4 1/4"
-     */
-    std::string toExposureTimeString() const;
-
-    ExifLong nominator;
-    ExifLong denominator;
-};
-
-} // Exif
-} // DeviceApi
-
-#endif // __TIZEN_EXIF_RATIONAL_H_
\ No newline at end of file