diff options
author | Eino-Ville Talvala <etalvala@google.com> | 2018-11-15 16:07:46 -0800 |
---|---|---|
committer | Eino-Ville Talvala <etalvala@google.com> | 2018-11-15 16:07:46 -0800 |
commit | 2d6d3250dcb304c8ad081dedc8eef6ea48fd669d (patch) | |
tree | 68cc8d5a9bf5a558f46025d740c47cb292eea9f0 /src/jpeg/jpeg_xmp_data_extractor.cc | |
parent | 840fc3b66a9e6593d542ada6fe14d91107fab98d (diff) | |
download | image_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.cc | 103 |
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 |