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