digiKam
bitstream.h
Go to the documentation of this file.
1 /*
2  * HEIF codec.
3  * Copyright (c) 2017 struktur AG, Dirk Farin <farin@struktur.de>
4  *
5  * This file is part of libheif.
6  *
7  * libheif is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU Lesser General Public License as
9  * published by the Free Software Foundation, either version 3 of
10  * the License, or (at your option) any later version.
11  *
12  * libheif is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public License
18  * along with libheif. If not, see <http://www.gnu.org/licenses/>.
19  */
20 
21 #ifndef LIBHEIF_BITSTREAM_H
22 #define LIBHEIF_BITSTREAM_H
23 
24 #if defined(HAVE_CONFIG_H)
25 #include "config.h"
26 #endif
27 
28 #include <cinttypes>
29 #include <cstddef>
30 
31 #include <vector>
32 #include <string>
33 #include <memory>
34 #include <limits>
35 #include <istream>
36 #include <string>
37 
38 #include "error.h"
39 
40 
41 namespace heif {
42 
44  {
45  public:
46  virtual ~StreamReader() { }
47 
48  virtual int64_t get_position() const = 0;
49 
50  enum grow_status {
51  size_reached, // requested size has been reached
52  timeout, // size has not been reached yet, but it may still grow further
53  size_beyond_eof // size has not been reached and never will. The file has grown to its full size
54  };
55 
56  // a StreamReader can maintain a timeout for waiting for new data
57  virtual grow_status wait_for_file_size(int64_t target_size) = 0;
58 
59  // returns 'false' when we read out of the available file size
60  virtual bool read(void* data, size_t size) = 0;
61 
62  virtual bool seek(int64_t position) = 0;
63 
64  bool seek_cur(int64_t position_offset) {
65  return seek(get_position() + position_offset);
66  }
67  };
68 
69 
71  {
72  public:
73  StreamReader_istream(std::unique_ptr<std::istream>&& istr);
74 
75  int64_t get_position() const override;
76 
77  grow_status wait_for_file_size(int64_t target_size) override;
78 
79  bool read(void* data, size_t size) override;
80 
81  bool seek(int64_t position) override;
82 
83  private:
84  std::unique_ptr<std::istream> m_istr;
85  int64_t m_length;
86  };
87 
88 
90  {
91  public:
92  StreamReader_memory(const uint8_t* data, int64_t size, bool copy);
94 
95  int64_t get_position() const override;
96 
97  grow_status wait_for_file_size(int64_t target_size) override;
98 
99  bool read(void* data, size_t size) override;
100 
101  bool seek(int64_t position) override;
102 
103  private:
104  const uint8_t* m_data;
105  int64_t m_length;
106  int64_t m_position;
107 
108  // if we made a copy of the data, we store a pointer to the owned memory area here
109  uint8_t* m_owned_data = nullptr;
110  };
111 
112 
114  {
115  public:
116  StreamReader_CApi(const heif_reader* func_table, void* userdata);
117 
118  int64_t get_position() const override { return m_func_table->get_position(m_userdata); }
119 
120  StreamReader::grow_status wait_for_file_size(int64_t target_size) override;
121 
122  bool read(void* data, size_t size) override { return !m_func_table->read(data,size,m_userdata); }
123  bool seek(int64_t position) override { return !m_func_table->seek(position,m_userdata); }
124 
125  private:
126  const heif_reader* m_func_table;
127  void* m_userdata;
128  };
129 
130 
131  // This class simplifies safely reading part of a file (e.g. a box).
132  // It makes sure that we do not read past the boundaries of a box.
134  {
135  public:
136  BitstreamRange(std::shared_ptr<StreamReader> istr,
137  uint64_t length,
138  BitstreamRange* parent = nullptr);
139 
140  // This function tries to make sure that the full data of this range is
141  // available. You should call this before starting reading the range.
142  // If you don't, you have to make sure that you do not read past the available data.
144 
145  uint8_t read8();
146  uint16_t read16();
147  uint32_t read32();
148  std::string read_string();
149 
150  bool prepare_read(int64_t nBytes);
151 
153 
155  // we do not actually move the file position here (because the stream may still be incomplete),
156  // but we set all m_remaining to zero
157  m_remaining = 0;
158 
159  if (m_parent_range) {
160  m_parent_range->skip_to_end_of_file();
161  }
162  }
163 
165  if (m_remaining>0) {
166  if (m_parent_range) {
167  // also advance position in parent range
168  m_parent_range->skip_without_advancing_file_pos(m_remaining);
169  }
170 
171  m_istr->seek_cur(m_remaining);
172  m_remaining = 0;
173  }
174  }
175 
177  m_remaining = 0;
178 
179  if (m_parent_range) {
180  m_parent_range->set_eof_while_reading();
181  }
182 
183  m_error = true;
184  }
185 
186  bool eof() const {
187  return m_remaining == 0;
188  }
189 
190  bool error() const {
191  return m_error;
192  }
193 
194  Error get_error() const {
195  if (m_error) {
198  }
199  else {
200  return Error::Ok;
201  }
202  }
203 
204  std::shared_ptr<StreamReader> get_istream() { return m_istr; }
205 
206  int get_nesting_level() const { return m_nesting_level; }
207 
208  int64_t get_remaining_bytes() const { return m_remaining; }
209 
210 private:
211  std::shared_ptr<StreamReader> m_istr;
212  BitstreamRange* m_parent_range = nullptr;
213  int m_nesting_level = 0;
214 
215  int64_t m_remaining;
216  bool m_error = false;
217 
218  // Note: 'nBytes' may not be larger than the number of remaining bytes
219  void skip_without_advancing_file_pos(int64_t nBytes);
220  };
221 
222 
223 
224  class BitReader
225  {
226  public:
227  BitReader(const uint8_t* buffer, int len);
228 
229  int get_bits(int n);
230  int get_bits_fast(int n);
231  int peek_bits(int n);
232  void skip_bits(int n);
233  void skip_bits_fast(int n);
235  bool get_uvlc(int* value);
236  bool get_svlc(int* value);
237 
239  return data_length - bytes_remaining - nextbits_cnt/8;
240  }
241 
242  private:
243  const uint8_t* data;
244  int data_length;
245  int bytes_remaining;
246 
247  uint64_t nextbits; // left-aligned bits
248  int nextbits_cnt;
249 
250  void refill(); // refill to at least 56+1 bits
251  };
252 
253 
254 
256  {
257  public:
258  void write8(uint8_t);
259  void write16(uint16_t);
260  void write32(uint32_t);
261  void write64(uint64_t);
262  void write(int size, uint64_t value);
263  void write(const std::string&);
264  void write(const std::vector<uint8_t>&);
265  void write(const StreamWriter&);
266 
267  void skip(int n);
268 
269  void insert(int nBytes);
270 
271  size_t data_size() const { return m_data.size(); }
272 
273  size_t get_position() const { return m_position; }
274  void set_position(size_t pos) { m_position=pos; }
275  void set_position_to_end() { m_position=m_data.size(); }
276 
277  const std::vector<uint8_t> get_data() const { return m_data; }
278 
279  private:
280  std::vector<uint8_t> m_data;
281  size_t m_position = 0;
282  };
283 }
284 
285 #endif
Definition: bitstream.h:225
int peek_bits(int n)
void skip_bits_fast(int n)
int get_bits_fast(int n)
bool get_svlc(int *value)
BitReader(const uint8_t *buffer, int len)
int get_bits(int n)
void skip_to_byte_boundary()
void skip_bits(int n)
bool get_uvlc(int *value)
int get_current_byte_index() const
Definition: bitstream.h:238
Definition: bitstream.h:134
bool eof() const
Definition: bitstream.h:186
void skip_to_end_of_box()
Definition: bitstream.h:164
int get_nesting_level() const
Definition: bitstream.h:206
StreamReader::grow_status wait_for_available_bytes(int64_t nBytes)
void skip_to_end_of_file()
Definition: bitstream.h:154
int64_t get_remaining_bytes() const
Definition: bitstream.h:208
std::shared_ptr< StreamReader > get_istream()
Definition: bitstream.h:204
void set_eof_while_reading()
Definition: bitstream.h:176
BitstreamRange(std::shared_ptr< StreamReader > istr, uint64_t length, BitstreamRange *parent=nullptr)
StreamReader::grow_status wait_until_range_is_available()
Error get_error() const
Definition: bitstream.h:194
bool prepare_read(int64_t nBytes)
std::string read_string()
bool error() const
Definition: bitstream.h:190
Definition: error.h:75
static Error Ok
Definition: error.h:87
Definition: bitstream.h:114
StreamReader_CApi(const heif_reader *func_table, void *userdata)
int64_t get_position() const override
Definition: bitstream.h:118
bool seek(int64_t position) override
Definition: bitstream.h:123
StreamReader::grow_status wait_for_file_size(int64_t target_size) override
bool read(void *data, size_t size) override
Definition: bitstream.h:122
Definition: bitstream.h:71
bool seek(int64_t position) override
grow_status wait_for_file_size(int64_t target_size) override
bool read(void *data, size_t size) override
StreamReader_istream(std::unique_ptr< std::istream > &&istr)
int64_t get_position() const override
Definition: bitstream.h:90
grow_status wait_for_file_size(int64_t target_size) override
StreamReader_memory(const uint8_t *data, int64_t size, bool copy)
bool read(void *data, size_t size) override
int64_t get_position() const override
bool seek(int64_t position) override
Definition: bitstream.h:44
grow_status
Definition: bitstream.h:50
@ size_beyond_eof
Definition: bitstream.h:53
@ timeout
Definition: bitstream.h:52
@ size_reached
Definition: bitstream.h:51
bool seek_cur(int64_t position_offset)
Definition: bitstream.h:64
virtual bool read(void *data, size_t size)=0
virtual ~StreamReader()
Definition: bitstream.h:46
virtual bool seek(int64_t position)=0
virtual grow_status wait_for_file_size(int64_t target_size)=0
virtual int64_t get_position() const =0
Definition: bitstream.h:256
void write16(uint16_t)
void insert(int nBytes)
void write8(uint8_t)
void skip(int n)
size_t data_size() const
Definition: bitstream.h:271
void set_position_to_end()
Definition: bitstream.h:275
void write(const std::string &)
void write64(uint64_t)
void write(const StreamWriter &)
const std::vector< uint8_t > get_data() const
Definition: bitstream.h:277
void write(const std::vector< uint8_t > &)
void write(int size, uint64_t value)
size_t get_position() const
Definition: bitstream.h:273
void set_position(size_t pos)
Definition: bitstream.h:274
void write32(uint32_t)
@ heif_suberror_End_of_data
Definition: heif.h:131
@ heif_error_Invalid_input
Definition: heif.h:99
qulonglong value
Definition: itemviewutilities.cpp:592
Definition: bitstream.h:41
Definition: heif.h:355
int64_t(* get_position)(void *userdata)
Definition: heif.h:360
int(* read)(void *data, size_t size, void *userdata)
Definition: heif.h:364
int(* seek)(int64_t position, void *userdata)
Definition: heif.h:367
Definition: scan.h:26