1*ca0779ebSJerome Gaillard #include "image_io/base/byte_buffer.h"
2*ca0779ebSJerome Gaillard
3*ca0779ebSJerome Gaillard #include <cstring>
4*ca0779ebSJerome Gaillard #include <utility>
5*ca0779ebSJerome Gaillard
6*ca0779ebSJerome Gaillard namespace photos_editing_formats {
7*ca0779ebSJerome Gaillard namespace image_io {
8*ca0779ebSJerome Gaillard
9*ca0779ebSJerome Gaillard using std::string;
10*ca0779ebSJerome Gaillard using std::unique_ptr;
11*ca0779ebSJerome Gaillard
12*ca0779ebSJerome Gaillard /// @param byte_data The byte data to write to the buffer at pos.
13*ca0779ebSJerome Gaillard /// @param pos The location in a buffer to write the byte data to.
14*ca0779ebSJerome Gaillard /// @return The number of bytes written to the buffer at pos.
WriteBytes(const ByteData & byte_data,Byte * pos)15*ca0779ebSJerome Gaillard static size_t WriteBytes(const ByteData& byte_data, Byte* pos) {
16*ca0779ebSJerome Gaillard size_t byte_count = byte_data.GetByteCount();
17*ca0779ebSJerome Gaillard if (!byte_count) {
18*ca0779ebSJerome Gaillard return 0;
19*ca0779ebSJerome Gaillard }
20*ca0779ebSJerome Gaillard if (byte_data.GetType() == ByteData::kHex) {
21*ca0779ebSJerome Gaillard const string& value = byte_data.GetValue();
22*ca0779ebSJerome Gaillard for (size_t index = 0; index < byte_count; ++index) {
23*ca0779ebSJerome Gaillard if (!ByteData::Hex2Byte(value[2 * index], value[2 * index + 1], pos++)) {
24*ca0779ebSJerome Gaillard return 0;
25*ca0779ebSJerome Gaillard }
26*ca0779ebSJerome Gaillard }
27*ca0779ebSJerome Gaillard } else {
28*ca0779ebSJerome Gaillard std::memcpy(pos, byte_data.GetValue().c_str(), byte_count);
29*ca0779ebSJerome Gaillard }
30*ca0779ebSJerome Gaillard return byte_count;
31*ca0779ebSJerome Gaillard }
32*ca0779ebSJerome Gaillard
ByteBuffer(size_t size,std::unique_ptr<Byte[]> buffer)33*ca0779ebSJerome Gaillard ByteBuffer::ByteBuffer(size_t size, std::unique_ptr<Byte[]> buffer)
34*ca0779ebSJerome Gaillard : buffer_(std::move(buffer)), size_(size) {
35*ca0779ebSJerome Gaillard if (!buffer_) {
36*ca0779ebSJerome Gaillard size_ = 0;
37*ca0779ebSJerome Gaillard }
38*ca0779ebSJerome Gaillard if (!size_) {
39*ca0779ebSJerome Gaillard buffer_.reset();
40*ca0779ebSJerome Gaillard }
41*ca0779ebSJerome Gaillard }
42*ca0779ebSJerome Gaillard
ByteBuffer(const std::vector<ByteData> & byte_data_vector)43*ca0779ebSJerome Gaillard ByteBuffer::ByteBuffer(const std::vector<ByteData>& byte_data_vector) {
44*ca0779ebSJerome Gaillard size_ = 0;
45*ca0779ebSJerome Gaillard for (const auto& byte_data : byte_data_vector) {
46*ca0779ebSJerome Gaillard size_ += byte_data.GetByteCount();
47*ca0779ebSJerome Gaillard }
48*ca0779ebSJerome Gaillard if (!size_) {
49*ca0779ebSJerome Gaillard return;
50*ca0779ebSJerome Gaillard }
51*ca0779ebSJerome Gaillard // Note that within google3, std::make_unique is not available, and clangtidy
52*ca0779ebSJerome Gaillard // says use absl::make_unique. This library attempts to minimize the number of
53*ca0779ebSJerome Gaillard // dependencies on google3, hence the no lint on the next line.
54*ca0779ebSJerome Gaillard buffer_.reset(new Byte[size_]); // NOLINT
55*ca0779ebSJerome Gaillard Byte* pos = buffer_.get();
56*ca0779ebSJerome Gaillard for (const auto& byte_data : byte_data_vector) {
57*ca0779ebSJerome Gaillard size_t bytes_written = WriteBytes(byte_data, pos);
58*ca0779ebSJerome Gaillard if (bytes_written == 0 && byte_data.GetByteCount() != 0) {
59*ca0779ebSJerome Gaillard size_ = 0;
60*ca0779ebSJerome Gaillard buffer_.reset(nullptr);
61*ca0779ebSJerome Gaillard }
62*ca0779ebSJerome Gaillard pos += bytes_written;
63*ca0779ebSJerome Gaillard }
64*ca0779ebSJerome Gaillard }
65*ca0779ebSJerome Gaillard
SetBigEndianValue(size_t location,std::uint16_t value)66*ca0779ebSJerome Gaillard bool ByteBuffer::SetBigEndianValue(size_t location, std::uint16_t value) {
67*ca0779ebSJerome Gaillard if (location + 1 >= size_) {
68*ca0779ebSJerome Gaillard return false;
69*ca0779ebSJerome Gaillard }
70*ca0779ebSJerome Gaillard buffer_[location] = static_cast<Byte>(value >> 8);
71*ca0779ebSJerome Gaillard buffer_[location + 1] = static_cast<Byte>(value & 0xFF);
72*ca0779ebSJerome Gaillard return true;
73*ca0779ebSJerome Gaillard }
74*ca0779ebSJerome Gaillard
Release()75*ca0779ebSJerome Gaillard Byte* ByteBuffer::Release() {
76*ca0779ebSJerome Gaillard size_ = 0;
77*ca0779ebSJerome Gaillard return buffer_.release();
78*ca0779ebSJerome Gaillard }
79*ca0779ebSJerome Gaillard
80*ca0779ebSJerome Gaillard } // namespace image_io
81*ca0779ebSJerome Gaillard } // namespace photos_editing_formats
82