summaryrefslogtreecommitdiff
path: root/src/jpeg/jpeg_xmp_data_extractor.cc
diff options
context:
space:
mode:
authorEino-Ville Talvala <etalvala@google.com>2018-11-15 16:07:46 -0800
committerEino-Ville Talvala <etalvala@google.com>2018-11-15 16:07:46 -0800
commit2d6d3250dcb304c8ad081dedc8eef6ea48fd669d (patch)
tree68cc8d5a9bf5a558f46025d740c47cb292eea9f0 /src/jpeg/jpeg_xmp_data_extractor.cc
parent840fc3b66a9e6593d542ada6fe14d91107fab98d (diff)
downloadimage_io-2d6d3250dcb304c8ad081dedc8eef6ea48fd669d.tar.gz
Initial commit of libimage_io
Image_io is a library for manipulating image files, especially XMP metadata within them. Test: m libimage_io Bug: 109735087 Bug: 119211681 Change-Id: I657f307be0459fe40154806c7cd388b97bcb0ea5
Diffstat (limited to 'src/jpeg/jpeg_xmp_data_extractor.cc')
-rw-r--r--src/jpeg/jpeg_xmp_data_extractor.cc103
1 files changed, 103 insertions, 0 deletions
diff --git a/src/jpeg/jpeg_xmp_data_extractor.cc b/src/jpeg/jpeg_xmp_data_extractor.cc
new file mode 100644
index 0000000..f59dea5
--- /dev/null
+++ b/src/jpeg/jpeg_xmp_data_extractor.cc
@@ -0,0 +1,103 @@
+#include "image_io/jpeg/jpeg_xmp_data_extractor.h"
+
+#include <iomanip>
+#include <sstream>
+#include <string>
+
+#include "image_io/base/message_handler.h"
+#include "image_io/jpeg/jpeg_marker.h"
+#include "image_io/jpeg/jpeg_segment.h"
+
+/// Set this flag to 1 for debugging output.
+#define PHOTOS_EDITING_FORMATS_IMAGE_IO_JPEG_JPEG_XMP_DATA_EXTRACTOR_DEBUG 0
+
+namespace photos_editing_formats {
+namespace image_io {
+
+using std::string;
+using std::stringstream;
+
+void JpegXmpDataExtractor::StartTransfer() {
+ data_destination_->StartTransfer();
+}
+
+DataDestination::TransferStatus JpegXmpDataExtractor::Transfer(
+ const DataRange& transfer_range, const DataSegment& data_segment) {
+ if (HasError()) {
+ return kTransferError;
+ }
+#if PHOTOS_EDITING_FORMATS_IMAGE_IO_JPEG_JPEG_XMP_DATA_EXTRACTOR_DEBUG
+ stringstream sstream1;
+ sstream1 << "Segment " << segment_index_ << " of " << last_segment_index_
+ << " - data range from " << transfer_range.GetBegin() << " to "
+ << transfer_range.GetEnd();
+ MessageHandler::Get()->ReportMessage(Message::kStatus, sstream1.str());
+#endif // PHOTOS_EDITING_FORMATS_IMAGE_IO_JPEG_JPEG_XMP_DATA_EXTRACTOR_DEBUG
+ const size_t xmp_header_length = JpegMarker::kLength +
+ JpegSegment::kVariablePayloadDataOffset +
+ kXmpExtendedHeaderSize;
+ size_t encoded_data_begin = transfer_range.GetBegin() + xmp_header_length;
+ size_t xmp_data_begin = encoded_data_begin;
+ size_t xmp_data_end = transfer_range.GetEnd();
+ if (segment_index_ == 0) {
+ string property_name = JpegXmpInfo::GetDataPropertyName(xmp_info_type_);
+ size_t gdepth_data_location = data_segment.Find(
+ encoded_data_begin, property_name.c_str(), property_name.length());
+ if (gdepth_data_location != transfer_range.GetEnd()) {
+ size_t quote_location = data_segment.Find(gdepth_data_location, '"');
+ if (quote_location != transfer_range.GetEnd()) {
+ xmp_data_begin = quote_location + 1;
+ }
+ }
+ if (xmp_data_begin == encoded_data_begin) {
+ MessageHandler::Get()->ReportMessage(Message::kStringNotFoundError,
+ property_name + "=\"");
+ has_error_ = true;
+ return kTransferError;
+ }
+ }
+ if (segment_index_ == last_segment_index_) {
+ xmp_data_end = data_segment.Find(xmp_data_begin, '"');
+ if (xmp_data_end == transfer_range.GetEnd()) {
+ MessageHandler::Get()->ReportMessage(Message::kStringNotFoundError, "\"");
+ has_error_ = true;
+ return kTransferError;
+ }
+ }
+
+ DataRange xmp_data_range(xmp_data_begin, xmp_data_end);
+#if PHOTOS_EDITING_FORMATS_IMAGE_IO_JPEG_JPEG_XMP_DATA_EXTRACTOR_DEBUG
+ string strb((const char*)data_segment.GetBuffer(xmp_data_range.GetBegin()),
+ 50);
+ string stre((const char*)data_segment.GetBuffer(xmp_data_end - 50), 50);
+ stringstream sstream2;
+ sstream2 << " " << xmp_data_begin << ":" << xmp_data_end << " = "
+ << xmp_data_range.GetLength() << " bytes: [" << strb << "..." << stre
+ << "] - ";
+ MessageHandler::Get()->ReportMessage(Message::kStatus, sstream2.str());
+ for (size_t i = transfer_range.GetBegin(); i < data_segment.GetEnd();
+ i += 32) {
+ stringstream hex_stream, ascii_stream;
+ hex_stream << std::hex << std::setfill('0') << std::setw(2)
+ << std::uppercase;
+ for (size_t j = 0; j < 32 && (i + j) < data_segment.GetEnd(); ++j) {
+ Byte value = data_segment.GetValidatedByte(i + j).value;
+ hex_stream << " " << size_t(value);
+ ascii_stream << (isprint(value) ? static_cast<char>(value) : '.');
+ }
+ stringstream sstream3;
+ sstream3 << " * " << std::hex << std::setfill('0') << std::setw(8)
+ << std::uppercase << i;
+ sstream3 << ":" << hex_stream.str() << " [" << ascii_stream.str() << "]";
+ MessageHandler::Get()->ReportMessage(Message::kStatus, sstream3.str());
+ }
+#endif // PHOTOS_EDITING_FORMATS_IMAGE_IO_JPEG_JPEG_XMP_DATA_EXTRACTOR_DEBUG
+ return data_destination_->Transfer(xmp_data_range, data_segment);
+}
+
+void JpegXmpDataExtractor::FinishTransfer() {
+ data_destination_->FinishTransfer();
+}
+
+} // namespace image_io
+} // namespace photos_editing_formats