// limitations under the License.
//
-#include "exif_gps_location.h"
+#include "exif/exif_gps_location.h"
#include <string>
#include <sstream>
#include <cmath>
-#include "common/platform_exception.h"
+#include "common/assert.h"
#include "common/logger.h"
namespace extension {
#include <string>
#include <vector>
-#include "exif_util.h"
-#include "rational.h"
+#include "exif/exif_util.h"
+#include "exif/rational.h"
namespace extension {
namespace exif {
// limitations under the License.
//
-#include "exif_information.h"
+#include "exif/exif_information.h"
#include <memory>
#include <cmath>
#include "common/assert.h"
#include "common/converter.h"
#include "common/logger.h"
-#include "common/platform_exception.h"
+#include "common/platform_result.h"
-#include "exif_tag_saver.h"
-#include "exif_util.h"
-#include "jpeg_file.h"
+#include "exif/exif_tag_saver.h"
+#include "exif/exif_util.h"
+#include "exif/jpeg_file.h"
namespace extension {
namespace exif {
-const size_t EXIF_UNDEFINED_TYPE_LENGTH = 8;
+using common::ErrorCode;
+using common::PlatformResult;
+
+const std::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 =
void ExifInformation::removeNulledAttributesFromExifData(ExifData* exif_data) {
LoggerD("Entered");
- if (!exif_data) {
- LoggerE("exif_data is NULL");
- throw common::UnknownException("Invalid Exif provided");
- }
+ AssertMsg(exif_data, "exif_data is NULL");
if (!isSet(EXIF_INFORMATION_ATTRIBUTE_WIDTH)) {
LoggerD("Removing width");
void ExifInformation::updateAttributesInExifData(ExifData* exif_data) {
LoggerD("Entered");
- if (!exif_data) {
- LoggerE("exif_data is NULL");
- throw common::UnknownException("Invalid Exif provided");
- }
+ AssertMsg(exif_data, "exif_data is NULL");
if (isSet(EXIF_INFORMATION_ATTRIBUTE_WIDTH)) {
LoggerD("Saving width: %d", getWidth());
}
}
-void ExifInformation::saveToFile(const std::string& file_path) {
+PlatformResult 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);
+ JpegFilePtr jpg_file;
+ PlatformResult result = JpegFile::loadFile(file_path, &jpg_file);
+ if (!result)
+ return result;
+
ExifData* exif_data = jpg_file->getExifData();
+ bool exif_data_is_new = false;
// Exif is not present in file - create new ExifData
if (!exif_data) {
file_path.c_str());
exif_data = exif_data_new();
+ if (!exif_data) {
+ LoggerE("Couldn't allocate new ExifData");
+ return PlatformResult(ErrorCode::UNKNOWN_ERR, "Memory allocation failed");
+ }
+
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) );
+ 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);
- }
+ // 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);
- updateAttributesInExifData(exif_data);
+ LoggerD("Using JpegFile to save new Exif in: [%s]", file_path.c_str());
+ if (exif_data_is_new) {
+ result = jpg_file->setNewExifData(exif_data);
+ }
- LoggerD("Using JpegFile to save new Exif in: [%s]", file_path.c_str());
- if (exif_data_is_new) {
- jpg_file->setNewExifData(exif_data);
- }
+ exif_data_unref(exif_data);
- jpg_file->saveToFile(file_path);
- }
- catch (...) {
- exif_data_unref(exif_data);
- exif_data = NULL;
- throw;
+ if (!result) {
+ return result;
}
- exif_data_unref(exif_data);
- exif_data = NULL;
+ return jpg_file->saveToFile(file_path);
}
} // namespace exif
#include <vector>
#include "common/picojson.h"
+#include "common/platform_result.h"
#include "exif/exif_gps_location.h"
typedef std::map<std::string, std::string> AttributeMap;
typedef std::vector<long long int> IsoSpeedRatingsVector;
-extern const size_t EXIF_UNDEFINED_TYPE_LENGTH;
+extern const std::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;
explicit ExifInformation(const picojson::value& args);
~ExifInformation();
- void saveToFile(const std::string& file_path);
+ common::PlatformResult saveToFile(const std::string& file_path);
const std::string& getUri();
void setUri(const std::string& uri);
#include <sstream>
#include "common/logger.h"
-#include "common/platform_exception.h"
+#include "common/platform_result.h"
#include "common/task-queue.h"
#include "exif/exif_information.h"
namespace extension {
namespace exif {
-typedef picojson::value JsonValue;
-typedef picojson::object JsonObject;
-typedef picojson::array JsonArray;
-typedef std::string JsonString;
+using common::PlatformResult;
+using common::ErrorCode;
ExifInstance::ExifInstance() {
using namespace std::placeholders;
const double callback_id = args.get("callbackId").get<double>();
auto get = [=](const std::shared_ptr<JsonValue>& response)->void {
- try {
- const std::string& file_path = ExifUtil::convertUriToPath(uri);
- LoggerD("file_path = %s", file_path.c_str());
+ JsonValue result = JsonValue(JsonObject());
+ PlatformResult status(ErrorCode::NO_ERROR);
- JsonValue result_direct = GetExifInfo::LoadFromURI(uri);
- ReportSuccess(result_direct, response->get<picojson::object>());
- }
- catch (const common::PlatformException& e) {
- ReportError(e, response->get<picojson::object>());
- }
+ // TODO(r.galka) it can be done on JS side
+ const std::string &file_path = ExifUtil::convertUriToPath(uri);
+ LoggerD("file_path = %s", file_path.c_str());
+
+ status = GetExifInfo::LoadFromURI(uri, &result);
+ if (status)
+ ReportSuccess(result, response->get<picojson::object>());
+ else
+ ReportError(status, &response->get<picojson::object>());
};
auto get_response = [callback_id, this](const std::shared_ptr<JsonValue>& response)->void {
LoggerD("exit");
}
-void ExifInstance::ExifManagerSaveExifInfo(const picojson::value& args, picojson::object& out) {
+void ExifInstance::ExifManagerSaveExifInfo(const picojson::value& args,
+ picojson::object& out) {
LoggerD("Entered");
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 {
- ExifInformationPtr exifInfo(new ExifInformation(args));
- const std::string& uri = exifInfo->getUri();
- const std::string& path = ExifUtil::convertUriToPath(uri);
- exifInfo->saveToFile(path);
+ auto get = [=](const std::shared_ptr<JsonValue>& response) -> void {
+ JsonValue result = JsonValue(JsonObject());
+ PlatformResult status(ErrorCode::NO_ERROR);
- ReportSuccess(args, response->get<picojson::object>());
- }
- catch (const common::PlatformException& e) {
- ReportError(e, response->get<picojson::object>());
- }
+ ExifInformationPtr exifInfo(new ExifInformation(args));
+ const std::string& uri = exifInfo->getUri();
+ // TODO(r.galka) it can be done on JS side
+ const std::string& path = ExifUtil::convertUriToPath(uri);
+ status = exifInfo->saveToFile(path);
+
+ if (status)
+ ReportSuccess(result, response->get<picojson::object>());
+ else
+ ReportError(status, &response->get<picojson::object>());
};
- auto get_response = [callback_id, this](const std::shared_ptr<JsonValue>& response)->void {
+ 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", picojson::value(callback_id)));
PostMessage(response->serialize().c_str());
};
- common::TaskQueue::GetInstance().Queue<JsonValue>(
- get, get_response, std::shared_ptr<JsonValue>(new JsonValue(JsonObject())));
+ common::TaskQueue::GetInstance().Queue<JsonValue>(get, get_response,
+ std::shared_ptr<JsonValue>(new JsonValue(JsonObject())));
}
-void ExifInstance::ExifManagerGetThumbnail(const picojson::value& args, picojson::object& out) {
+void ExifInstance::ExifManagerGetThumbnail(const picojson::value& args,
+ picojson::object& out) {
LoggerD("Entered");
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 {
- const std::string &file_path = ExifUtil::convertUriToPath(uri);
- JsonValue result = JsonValue(JsonObject());
- JsonObject &result_obj = result.get<JsonObject>();
-
- std::string ext = file_path.substr(file_path.find_last_of(".") + 1);
- std::transform(ext.begin(), ext.end(), ext.begin(), ::tolower);
-
- if ("jpg" == ext) {
- ext = "jpeg";
- }
-
- if ("jpeg" == ext || "png" == ext || "gif" == ext) {
- LoggerD("Get thumbnail from Exif in file: [%s]", file_path.c_str());
- ExifData *exif_data = exif_data_new_from_file(file_path.c_str());
- if (!exif_data) {
- LoggerE("Error reading from file [%s]", file_path.c_str());
- throw common::UnknownException("Error reading from file");
- }
-
- if (exif_data->data && exif_data->size) {
- gchar *ch_uri = g_base64_encode(exif_data->data, exif_data->size);
- exif_data_unref(exif_data);
- std::string base64 = "data:image/" + ext + ";base64," + ch_uri;
-
- std::pair<std::string, picojson::value> pair;
- pair = std::make_pair("src", picojson::value(base64));
- result_obj.insert(pair);
- } else {
- exif_data_unref(exif_data);
- LoggerE("File [%s] doesn't contain thumbnail", file_path.c_str());
- throw common::UnknownException("File doesn't contain thumbnail");
- }
- } else {
- LoggerE("extension: %s is not valid (jpeg/jpg/png/gif is supported)", ext.c_str());
- throw common::InvalidValuesException("getThumbnail support only jpeg/jpg/png/gif");
- }
+ PlatformResult status(ErrorCode::NO_ERROR);
- ReportSuccess(result, response->get<picojson::object>());
+ // TODO(r.galka) it can be done on JS side
+ const std::string &file_path = ExifUtil::convertUriToPath(uri);
+ JsonValue result = JsonValue(JsonObject());
+ JsonObject &result_obj = result.get<JsonObject>();
+
+ std::string ext = file_path.substr(file_path.find_last_of(".") + 1);
+ std::transform(ext.begin(), ext.end(), ext.begin(), ::tolower);
+
+ if ("jpg" == ext) {
+ ext = "jpeg";
}
- catch (const common::PlatformException &e) {
- ReportError(e, response->get<picojson::object>());
+
+ if ("jpeg" != ext && "png" != ext && "gif" != ext) {
+ LoggerE("extension: %s is not valid (jpeg/jpg/png/gif is supported)",
+ ext.c_str());
+ status = PlatformResult(ErrorCode::INVALID_VALUES_ERR,
+ "getThumbnail support only jpeg/jpg/png/gif");
+ ReportError(status, &response->get<picojson::object>());
+ return;
+ }
+
+ LoggerD("Get thumbnail from Exif in file: [%s]", file_path.c_str());
+ ExifData *exif_data = exif_data_new_from_file(file_path.c_str());
+ if (!exif_data) {
+ LoggerE("Error reading from file [%s]", file_path.c_str());
+ status = PlatformResult(ErrorCode::UNKNOWN_ERR,
+ "Error reading from file");
+ ReportError(status, &response->get<picojson::object>());
+ return;
}
+
+ if (!exif_data->data || !exif_data->size) {
+ exif_data_unref(exif_data);
+ LoggerE("File [%s] doesn't contain thumbnail", file_path.c_str());
+ status = PlatformResult(ErrorCode::UNKNOWN_ERR,
+ "File doesn't contain thumbnail");
+ ReportError(status, &response->get<picojson::object>());
+ return;
+ }
+
+ gchar *ch_uri = g_base64_encode(exif_data->data, exif_data->size);
+ exif_data_unref(exif_data);
+ std::string base64 = "data:image/" + ext + ";base64," + ch_uri;
+
+ std::pair<std::string, picojson::value> pair;
+ pair = std::make_pair("src", picojson::value(base64));
+ result_obj.insert(pair);
+
+ ReportSuccess(result, response->get<picojson::object>());
};
auto get_response = [callback_id, this](const std::shared_ptr<JsonValue>& response)->void {
#include "common/extension.h"
#include "common/picojson.h"
+typedef picojson::value JsonValue;
+typedef picojson::object JsonObject;
+typedef picojson::array JsonArray;
+typedef std::string JsonString;
+
namespace extension {
namespace exif {
// limitations under the License.
//
-#include "exif_tag_saver.h"
+#include "exif/exif_tag_saver.h"
#include <libexif/exif-format.h>
#include <sstream>
#include <cstring>
-#include "common/platform_exception.h"
+#include "common/platform_result.h"
#include "common/logger.h"
-#include "exif_util.h"
+#include "exif/exif_util.h"
namespace extension {
namespace exif {
void ExifTagSaver::saveToExif(long int value, ExifTag tag,
ExifData* exif_data) {
ExifEntry* entry = prepareEntry(exif_data, tag);
+ if (!entry) {
+ // TODO return PlatformResult and handle error
+ LoggerE("Exif entry is null");
+ return;
+ }
+
ExifByteOrder order = exif_data_get_byte_order(exif_data);
LoggerD("entry->format: %d", entry->format);
ExifData* exif_data, ExifFormat format,
bool add_zero_character) {
ExifEntry* entry = prepareEntry(exif_data, tag);
+ if (!entry) {
+ // TODO return PlatformResult and handle error
+ LoggerE("Exif entry is null");
+ return;
+ }
+
if (!value.empty()) {
if (entry->data) {
free(entry->data);
entry->data = NULL;
}
- size_t new_len = value.length();
+ std::size_t new_len = value.length();
if (add_zero_character) {
++new_len;
}
void ExifTagSaver::saveToExif(const Rational& value, ExifTag tag,
ExifData* exif_data) {
ExifEntry* entry = prepareEntry(exif_data, tag);
+ if (!entry) {
+ // TODO return PlatformResult and handle error
+ LoggerE("Exif entry is null");
+ return;
+ }
entry->format = EXIF_FORMAT_RATIONAL;
if (ExifTypeInfo::RationalSize != entry->size) {
void ExifTagSaver::saveToExif(const Rationals& value, ExifTag tag,
ExifData* exif_data) {
ExifEntry* entry = prepareEntry(exif_data, tag);
+ if (!entry) {
+ // TODO return PlatformResult and handle error
+ LoggerE("Exif entry is null");
+ return;
+ }
ExifByteOrder order = exif_data_get_byte_order(exif_data);
entry->format = EXIF_FORMAT_RATIONAL;
}
entry->components = value.size();
- for (size_t i = 0; i < value.size(); ++i) {
+ for (std::size_t i = 0; i < value.size(); ++i) {
ExifRational r;
r.numerator = value[i].nominator;
r.denominator = value[i].denominator;
ExifFormat store_as,
ExifTag tag, ExifData* exif_data) {
ExifEntry* entry = prepareEntry(exif_data, tag);
+ if (!entry) {
+ // TODO return PlatformResult and handle error
+ LoggerE("Exif entry is null");
+ return;
+ }
const ExifByteOrder order = exif_data_get_byte_order(exif_data);
- const size_t size_per_member = ExifUtil::getSizeOfExifFormatType(store_as);
+ const std::size_t size_per_member = ExifUtil::getSizeOfExifFormatType(store_as);
switch (store_as) {
case EXIF_FORMAT_BYTE:
case EXIF_FORMAT_SHORT:
}
entry->format = store_as;
- const size_t num_elements = value.size();
+ const std::size_t num_elements = value.size();
const unsigned int required_size = size_per_member * num_elements;
if (required_size != entry->size) {
if (entry->data) {
switch (store_as) {
case EXIF_FORMAT_BYTE: {
- for (size_t i = 0; i < num_elements; ++i) {
+ for (std::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) {
+ for (std::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) {
+ for (std::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) {
+ for (std::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) {
+ for (std::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:");
if (!exif_entry) {
LoggerE("Couldn't create new Exif tag");
- // throw UnknownException("Could not save Exif to file");
+ return NULL;
}
exif_entry_initialize(exif_entry, tag);
}
ExifIfd ExifTagSaver::deduceIfdSection(ExifTag tag) {
+ // TODO EXIF_TAG_* and EXIF_TAG_GPS_* are sharing same values,
+ // they shouldn't be used in one switch statement.
+
switch (static_cast<unsigned int>(tag)) {
// Tags in IFD_0 Section
case EXIF_TAG_MAKE:
// Tags in other sections
default:
LoggerE("Unsupported tag: %d", tag);
- // throw UnknownException("Unsupported tag");
+ // TODO handle error
}
}
ExifFormat ExifTagSaver::deduceDataFormat(ExifTag tag) {
+ // TODO EXIF_TAG_* and EXIF_TAG_GPS_* are sharing same values,
+ // they shouldn't be used in one switch statement.
+
switch (static_cast<unsigned int>(tag)) {
// Tags with byte type:
case EXIF_TAG_GPS_ALTITUDE_REF:
// Unsupported tags:
default:
LoggerE("Unsupported tag: %d", tag);
- // throw UnknownException("Unsupported tag");
+ // TODO handle error
}
}
// limitations under the License.
//
-#include "exif_util.h"
+#include "exif/exif_util.h"
#include <iomanip>
#include <sstream>
-#include "common/platform_exception.h"
+#include "common/platform_result.h"
#include "common/logger.h"
namespace extension {
const std::string URI_ABSOLUTE_PREFIX = "file:///";
} // namespace
-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 std::size_t ExifTypeInfo::ByteSize = 1;
+const std::size_t ExifTypeInfo::ASCIISize = 1;
+const std::size_t ExifTypeInfo::ShortSize = 2;
+const std::size_t ExifTypeInfo::LongSize = 4;
+const std::size_t ExifTypeInfo::RationalSize = 8;
+const std::size_t ExifTypeInfo::UndefinedSize = 1;
+const std::size_t ExifTypeInfo::SLongSize = 4;
+const std::size_t ExifTypeInfo::SRationalSize = 8;
const ExifByte ExifTypeInfo::ByteId = 1;
const ExifByte ExifTypeInfo::ASCIIId = 2;
}
size_t ExifUtil::getSizeOfExifFormatType(ExifFormat format) {
- size_t size_per_member = 0;
+ std::size_t size_per_member = 0;
switch (format) {
case EXIF_FORMAT_BYTE:
size_per_member = 1;
unsigned char* read_buf_ptr = entry->data;
- size_t size_per_member = getSizeOfExifFormatType(entry->format);
+ std::size_t size_per_member = getSizeOfExifFormatType(entry->format);
if (0 == size_per_member) {
size_per_member = 1; // display as array of bytes
}
* 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
+ static const std::size_t ByteSize; // 1 byte
+ static const std::size_t ASCIISize; // 1 byte (*N)
+ static const std::size_t ShortSize; // 2 bytes
+ static const std::size_t LongSize; // 4 bytes
+ static const std::size_t RationalSize; // 8 bytes
+ static const std::size_t UndefinedSize; // 1 byte (*N)
+ static const std::size_t SLongSize; // 4 bytes
+ static const std::size_t SRationalSize; // 8 bytes
/**
* Id values used by Exif to identify type
static const Rationals timeTToExifGpsTimeStamp(time_t time);
static std::string timeTToExifGpsDateStamp(time_t time);
- static size_t getSizeOfExifFormatType(ExifFormat format);
+ static std::size_t getSizeOfExifFormatType(ExifFormat format);
static void printExifEntryInfo(ExifEntry* entry, ExifData* exif_data);
static void extractFromTimeT(const time_t time,
#include <string>
#include <utility>
-#include "common/platform_exception.h"
+#include "common/platform_result.h"
#include "common/logger.h"
#include "exif/exif_util.h"
namespace extension {
namespace exif {
+using common::PlatformResult;
+using common::ErrorCode;
+
struct ExifDataHolder {
ExifData* exif_data;
JsonObject* result_obj_ptr;
return true;
}
-void GetExifInfo::ProcessEntry(ExifEntry* entry,
+PlatformResult GetExifInfo::ProcessEntry(ExifEntry* entry,
ExifData* exif_data,
JsonObject* result_obj) {
char buf[2000];
const ExifIfd cur_ifd = exif_entry_get_ifd(entry);
if (EXIF_IFD_INTEROPERABILITY == cur_ifd || EXIF_IFD_1 == cur_ifd) {
- return;
+ return PlatformResult(ErrorCode::NO_ERROR);
}
std::pair<std::string, JsonValue> pair;
entry->data) {
const ExifByteOrder order = exif_data_get_byte_order(exif_data);
unsigned char* read_ptr = entry->data;
- const size_t size_per_member =
+ const std::size_t size_per_member =
ExifUtil::getSizeOfExifFormatType(entry->format);
JsonArray array = JsonArray();
result_obj->insert(pair);
} else {
LoggerE("iso speed ratings: format or components count is invalid!");
- throw common::TypeMismatchException("iso speed ratings: format or"
- " components count is invalid!");
+ return PlatformResult(ErrorCode::TYPE_MISMATCH_ERR,
+ "iso speed ratings: format or components count is invalid!");
}
break;
}
}
} else {
LoggerE("exposure time: format or components count is invalid!");
- throw common::TypeMismatchException("exposure time: format or"
- " components count is invalid!");
+ return PlatformResult(ErrorCode::TYPE_MISMATCH_ERR,
+ "exposure time: format or components count is invalid!");
}
break;
}
break;
}
}
+
+ return PlatformResult(ErrorCode::NO_ERROR);
}
void GetExifInfo::ContentForeachFunctionProxy(ExifEntry *entry, void *user_data) {
ExifDataHolder* holder = static_cast<ExifDataHolder*>(user_data);
if (!holder) {
LoggerE("holder is NULL");
+ return;
}
if (!holder->exif_data) {
JsonObject* result_obj_ptr = holder->result_obj_ptr;
- try {
- ProcessEntry(entry, holder->exif_data, result_obj_ptr);
- }
- catch(...) {
+ PlatformResult status = ProcessEntry(entry, holder->exif_data, result_obj_ptr);
+ if (!status) {
LoggerE("Unsupported error while processing Exif entry.");
}
}
exif_content_foreach_entry(content, ContentForeachFunctionProxy, user_data);
}
-JsonValue GetExifInfo::LoadFromURI(const std::string& uri) {
+PlatformResult GetExifInfo::LoadFromURI(const std::string& uri,
+ JsonValue* result) {
+ // TODO(r.galka) it can be done on JS side
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());
- throw common::UnknownException("Error reading exif from file");
+ return PlatformResult(ErrorCode::UNKNOWN_ERR,
+ "Error reading exif from file");
}
LoggerD("loadFromURI_into_json exif_data_foreach_content START");
- JsonValue result = JsonValue(JsonObject());
- JsonObject& result_obj = result.get<JsonObject>();
+ JsonObject& result_obj = result->get<JsonObject>();
ExifDataHolder holder;
holder.exif_data = ed;
holder.result_obj_ptr = &result_obj;
- exif_data_foreach_content(ed, DataForeachFunction, static_cast<void*>(&holder));
+ exif_data_foreach_content(ed, DataForeachFunction,
+ static_cast<void *>(&holder));
LoggerD("loadFromURI_into_json exif_data_foreach_content END");
exif_data_unref(ed);
- ed = NULL;
// uri is not taken from jgp Exif, so we add it here
holder.result_obj_ptr->insert(std::make_pair("uri", JsonValue(uri)));
- return result;
+ return PlatformResult(ErrorCode::NO_ERROR);
}
} // namespace exif
#include "common/extension.h"
#include "common/picojson.h"
+#include "common/platform_result.h"
#include "exif/exif_gps_location.h"
namespace extension {
namespace exif {
-extern const size_t EXIF_UNDEFINED_TYPE_LENGTH;
+extern const std::size_t EXIF_UNDEFINED_TYPE_LENGTH;
class GetExifInfo {
public:
- static void ProcessEntry(ExifEntry* entry,
- ExifData* exif_data,
- JsonObject* result_obj);
- static JsonValue LoadFromURI(const std::string& uri);
+ static common::PlatformResult ProcessEntry(ExifEntry* entry,
+ ExifData* exif_data,
+ JsonObject* result_obj);
+
+ static common::PlatformResult LoadFromURI(const std::string& uri,
+ JsonValue* result);
private:
GetExifInfo() { } // private ctor - class can not be created
// For details of JPEG file format see:
// http://www.media.mit.edu/pia/Research/deepview/exif.html
-#include "jpeg_file.h"
+#include "exif/jpeg_file.h"
#include <iomanip>
#include <limits>
+#include "common/assert.h"
#include "common/logger.h"
-#include "common/platform_exception.h"
+#include "common/platform_result.h"
namespace extension {
namespace exif {
+using common::PlatformResult;
+using common::ErrorCode;
+
/**
* Size of maximal JPEG's section data length
* (since it is stored as unsigned short limit is 2^16 -1)
}
}
-JpegFilePtr JpegFile::loadFile(const std::string& path) {
+PlatformResult JpegFile::loadFile(const std::string& path, JpegFilePtr* jpg_ptr) {
JpegFile* new_jpg = new (std::nothrow) JpegFile();
if (!new_jpg) {
LoggerE("Couldn't allocate Jpegfile!");
- throw common::UnknownException("Memory allocation failed");
+ return PlatformResult(ErrorCode::UNKNOWN_ERR, "Memory allocation failed");
+ }
+
+ jpg_ptr->reset(new_jpg);
+
+ PlatformResult result = (*jpg_ptr)->load(path);
+ if (!result) {
+ return result;
}
- JpegFilePtr jpg_ptr(new_jpg);
- jpg_ptr->load(path);
- return jpg_ptr;
+ return PlatformResult(ErrorCode::NO_ERROR);
}
-void JpegFile::load(const std::string& path) {
+PlatformResult 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 JPEG file");
+ return PlatformResult(ErrorCode::NOT_FOUND_ERR, "Could not open JPEG file");
}
fseek(m_in_file, 0, SEEK_END);
- const size_t in_file_size = static_cast<size_t>(ftell(m_in_file));
+ const std::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");
+ return PlatformResult(ErrorCode::UNKNOWN_ERR, "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");
+ return PlatformResult(ErrorCode::UNKNOWN_ERR, "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);
+ const std::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");
+ return PlatformResult(ErrorCode::UNKNOWN_ERR, "Could not read JPEG file");
}
if (fclose(m_in_file) == EOF) {
}
m_in_file = NULL;
- generateListOfSections();
+ return generateListOfSections();
}
-std::string JpegFile::getPartOfFile(const size_t offset,
- const size_t num_bytes_before,
- const size_t num_bytes_after) {
+std::string JpegFile::getPartOfFile(const std::size_t offset,
+ const std::size_t num_bytes_before,
+ const std::size_t num_bytes_after) {
long long int start = static_cast<long long int>(offset) - num_bytes_before;
if (start < 0) {
start = 0;
}
-void JpegFile::generateListOfSections() {
+common::PlatformResult JpegFile::generateListOfSections() {
LoggerD("Entered");
// JPEG starts with:
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;
+ const std::size_t search_len = 10;
+ std::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 (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");
+ return PlatformResult(ErrorCode::UNKNOWN_ERR, "JPEG file is invalid");
}
- const size_t section_offset = offset + search_offset - 1;
+ const std::size_t section_offset = offset + search_offset - 1;
unsigned char* section_begin = m_in_data + section_offset;
offset = section_offset; // Move to section begin
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");
+ return PlatformResult(ErrorCode::UNKNOWN_ERR, "JPEG file is invalid");
}
const JpegMarker cur_marker = castToJpegMarker(section_begin[1]);
JpegFileSection* sec = new (std::nothrow) JpegFileSection();
if (!sec) {
LoggerE("Couldn't allocate JpegFileSection");
- throw common::UnknownException("Memory allocation failed");
+ return PlatformResult(ErrorCode::UNKNOWN_ERR, "Memory allocation failed");
}
section = JpegFileSectionPtr(sec);
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");
+ return PlatformResult(ErrorCode::UNKNOWN_ERR, "JPEG file is invalid");
}
if (section_offset + 2 + total_section_len > m_in_data_size) {
offset, cur_marker,
section_offset, total_section_len,
section_offset + total_section_len, m_in_data_size);
- throw common::UnknownException("JPEG file is invalid");
+ return PlatformResult(ErrorCode::UNKNOWN_ERR, "JPEG file is invalid");
}
if (JPEG_MARKER_APP1 == cur_marker) {
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;
+ const std::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;
+ std::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;
+ std::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) {
}
}
}
+
+ return PlatformResult(ErrorCode::NO_ERROR);
}
bool JpegFile::searchForTagInBuffer(const unsigned char* buffer_start,
const unsigned char* buffer_end,
const JpegMarker marker,
- size_t& out_index) {
+ std::size_t& out_index) {
LoggerD("Entered start:%p end:%p marker:0x%x",
buffer_start, buffer_end, marker);
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");
- }
+PlatformResult JpegFile::setNewExifData(ExifData* new_exif_data) {
+ AssertMsg(new_exif_data, "Trying to set NULL exif_data!");
JpegFileSectionPtr exif = getExifSection();
if (!exif) {
JpegFileSection* new_sec = new (std::nothrow) JpegFileSection();
if (!new_sec) {
LoggerE("Couldn't allocate JpegFileSection");
- throw common::UnknownException("Memory allocation failed");
+ return PlatformResult(ErrorCode::UNKNOWN_ERR,
+ "Memory allocation failed");
}
new_sec->type = JPEG_MARKER_APP1;
if (!soi_is_present) {
LoggerW("SOI section is missing");
- throw common::UnknownException("JPEG file is invalid");
+ return PlatformResult(ErrorCode::UNKNOWN_ERR, "JPEG file is invalid");
}
// Insert new Exif sections just after SOI
exif_data_unref(exif->exif_data);
exif_data_ref(new_exif_data);
exif->exif_data = new_exif_data;
+
+ return PlatformResult(ErrorCode::NO_ERROR);
}
ExifData* JpegFile::getExifData() {
return exif->exif_data;
}
-void JpegFile::saveToFile(const std::string& out_path) {
+PlatformResult 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!", out_path.c_str());
- } 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());
- }
- }
+ PlatformResult status = saveToFilePriv(out_path);
+
+ if (status)
+ return status;
+
+ 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!", out_path.c_str());
+ return PlatformResult(ErrorCode::UNKNOWN_ERR,
+ "Couldn't open output file");
+ }
+
+ std::size_t bytes_wrote = fwrite(m_in_data, 1, m_in_data_size, outf);
+ if (bytes_wrote != m_in_data_size) {
+ fclose(outf);
+
+ LoggerE("Couldn't restore whole JPEG! "
+ "Only %d of %d bytes have been wrote!",
+ bytes_wrote, m_in_data_size);
+ return PlatformResult(ErrorCode::UNKNOWN_ERR,
+ "Couldn't restore whole file");
+ }
+ if (EOF == fclose(outf)) {
+ LoggerE("Couldn't close restore output file: [%s]", out_path.c_str());
}
- throw;
+ return PlatformResult(ErrorCode::NO_ERROR);
}
+
+ return status;
}
-void JpegFile::saveToFilePriv(const std::string& out_path) {
+PlatformResult 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");
+ return PlatformResult(ErrorCode::UNKNOWN_ERR, "Could not write JPEG file");
}
unsigned char tmp_buf[128];
- size_t offset = 0;
+ std::size_t offset = 0;
int section_index = 0;
for (SectionsVec::iterator it = m_sections.begin();
LoggerD("offset:%d | Section: %d marker 0x%x",
offset, section_index, cur_marker);
- size_t bytes_to_write = 0;
- size_t bytes_wrote = 0;
+ std::size_t bytes_to_write = 0;
+ std::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;
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");
+ return PlatformResult(ErrorCode::UNKNOWN_ERR,
+ "Could not save Exif in JPEG file");
}
LoggerD("offset:%d | Generated Exif RAW Data length:%d", offset,
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");
+ return PlatformResult(ErrorCode::UNKNOWN_ERR,
+ "Exif data is to big to be saved in JPEG file");
}
section_size += exif_output_size;
write_exif_data = true;
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");
+ return PlatformResult(ErrorCode::UNKNOWN_ERR,
+ "Could not write JPEG file");
}
if (write_section_data && cur->size > 0) {
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");
+ return PlatformResult(ErrorCode::UNKNOWN_ERR,
+ "Could not write JPEG file");
}
}
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");
+ return PlatformResult(ErrorCode::UNKNOWN_ERR,
+ "Could not write JPEG file");
}
}
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");
+ return PlatformResult(ErrorCode::UNKNOWN_ERR,
+ "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,
+ const std::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");
+ return PlatformResult(ErrorCode::UNKNOWN_ERR,
+ "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);
}
+
+ m_out_file = NULL;
+
+ return PlatformResult(ErrorCode::NO_ERROR);
}
JpegFileSectionPtr JpegFile::getExifSection() {
- size_t num_exif_sections = 0;
+ std::size_t num_exif_sections = 0;
JpegFileSectionPtr first_exif_section;
for (SectionsVec::iterator it = m_sections.begin();
#include <string>
#include <vector>
+#include "common/platform_result.h"
+
namespace extension {
namespace exif {
class JpegFile {
public:
- static JpegFilePtr loadFile(const std::string& path);
+ static common::PlatformResult loadFile(const std::string& path,
+ JpegFilePtr* jpg_ptr);
~JpegFile();
- void setNewExifData(ExifData* new_exif_data);
+ common::PlatformResult setNewExifData(ExifData* new_exif_data);
/**
* You are responsible to unreference returned data with: exif_data_unref(...)
*/
ExifData* getExifData();
- void saveToFile(const std::string& out_path);
+ common::PlatformResult 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);
+ common::PlatformResult load(const std::string &path);
+
+ common::PlatformResult generateListOfSections();
+
+ std::string getPartOfFile(const std::size_t offset,
+ const std::size_t num_bytes_before = 10,
+ const std::size_t num_bytes_after = 10);
JpegFileSectionPtr getExifSection();
- void saveToFilePriv(const std::string& out_path);
+
+ common::PlatformResult saveToFilePriv(const std::string &out_path);
/**
- * Search for first occurence of specific tag inside buffer.
+ * Search for first occurrence of specific tag inside buffer.
*
* buffer_end is the first byte that should not be checked:
* [buffer_start ... buffer_end)
static bool searchForTagInBuffer(const unsigned char* buffer_start,
const unsigned char* buffer_end,
const JpegMarker marker,
- size_t& out_index);
+ std::size_t& out_index);
std::string m_source_file_path;
unsigned char* m_in_data;
- size_t m_in_data_size;
+ std::size_t m_in_data_size;
unsigned char* m_image_data;
- size_t m_image_size;
+ std::size_t m_image_size;
/**
* This contains any bytes after EOI.
* some cameras saves extra bytes (for example Android).
*/
unsigned char* m_padding_data;
- size_t m_padding_data_size;
+ std::size_t m_padding_data_size;
FILE* m_in_file;
FILE* m_out_file;
// limitations under the License.
//
-#include "rational.h"
+#include "exif/rational.h"
#include <cmath>
#include <sstream>
-#include "common/platform_exception.h"
#include "common/logger.h"
-#include "exif_util.h"
+#include "exif/exif_util.h"
namespace extension {
namespace exif {