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