aboutsummaryrefslogtreecommitdiff
path: root/third_party/image_io/src/base/byte_buffer.cc
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/image_io/src/base/byte_buffer.cc')
-rw-r--r--third_party/image_io/src/base/byte_buffer.cc81
1 files changed, 81 insertions, 0 deletions
diff --git a/third_party/image_io/src/base/byte_buffer.cc b/third_party/image_io/src/base/byte_buffer.cc
new file mode 100644
index 0000000..ac4d387
--- /dev/null
+++ b/third_party/image_io/src/base/byte_buffer.cc
@@ -0,0 +1,81 @@
+#include "image_io/base/byte_buffer.h"
+
+#include <cstring>
+#include <utility>
+
+namespace photos_editing_formats {
+namespace image_io {
+
+using std::string;
+using std::unique_ptr;
+
+/// @param byte_data The byte data to write to the buffer at pos.
+/// @param pos The location in a buffer to write the byte data to.
+/// @return The number of bytes written to the buffer at pos.
+static size_t WriteBytes(const ByteData& byte_data, Byte* pos) {
+ size_t byte_count = byte_data.GetByteCount();
+ if (!byte_count) {
+ return 0;
+ }
+ if (byte_data.GetType() == ByteData::kHex) {
+ const string& value = byte_data.GetValue();
+ for (size_t index = 0; index < byte_count; ++index) {
+ if (!ByteData::Hex2Byte(value[2 * index], value[2 * index + 1], pos++)) {
+ return 0;
+ }
+ }
+ } else {
+ std::memcpy(pos, byte_data.GetValue().c_str(), byte_count);
+ }
+ return byte_count;
+}
+
+ByteBuffer::ByteBuffer(size_t size, std::unique_ptr<Byte[]> buffer)
+ : buffer_(std::move(buffer)), size_(size) {
+ if (!buffer_) {
+ size_ = 0;
+ }
+ if (!size_) {
+ buffer_.reset();
+ }
+}
+
+ByteBuffer::ByteBuffer(const std::vector<ByteData>& byte_data_vector) {
+ size_ = 0;
+ for (const auto& byte_data : byte_data_vector) {
+ size_ += byte_data.GetByteCount();
+ }
+ if (!size_) {
+ return;
+ }
+ // Note that within google3, std::make_unique is not available, and clangtidy
+ // says use absl::make_unique. This library attempts to minimize the number of
+ // dependencies on google3, hence the no lint on the next line.
+ buffer_.reset(new Byte[size_]); // NOLINT
+ Byte* pos = buffer_.get();
+ for (const auto& byte_data : byte_data_vector) {
+ size_t bytes_written = WriteBytes(byte_data, pos);
+ if (bytes_written == 0 && byte_data.GetByteCount() != 0) {
+ size_ = 0;
+ buffer_.reset(nullptr);
+ }
+ pos += bytes_written;
+ }
+}
+
+bool ByteBuffer::SetBigEndianValue(size_t location, std::uint16_t value) {
+ if (location + 1 >= size_) {
+ return false;
+ }
+ buffer_[location] = static_cast<Byte>(value >> 8);
+ buffer_[location + 1] = static_cast<Byte>(value & 0xFF);
+ return true;
+}
+
+Byte* ByteBuffer::Release() {
+ size_ = 0;
+ return buffer_.release();
+}
+
+} // namespace image_io
+} // namespace photos_editing_formats