Grok  10.0.3
buffer.h
Go to the documentation of this file.
1 
17 #pragma once
18 
19 namespace grk
20 {
21 
22 template<typename T>
24 {
25  T* alloc(size_t length)
26  {
27  return new T[length];
28  }
29  void dealloc(T* buf)
30  {
31  delete[] buf;
32  }
33 };
34 template<typename T>
36 {
37  T* alloc(size_t length)
38  {
39  return (T*)grk_aligned_malloc(length * sizeof(T));
40  }
41  void dealloc(T* buf)
42  {
43  grk_aligned_free(buf);
44  }
45 };
46 template<typename T, template<typename TT> typename A>
47 struct grk_buf : A<T>
48 {
49  grk_buf(T* buffer, size_t off, size_t length, bool ownsData)
50  : buf(buffer), offset(off), len(length), owns_data(ownsData)
51  {}
52  grk_buf(T* buffer, size_t length) : grk_buf(buffer, 0, length, false) {}
53  grk_buf() : grk_buf(0, 0, 0, false) {}
54  grk_buf(T* buffer, size_t length, bool ownsData) : grk_buf(buffer, 0, length, ownsData) {}
55  virtual ~grk_buf()
56  {
57  dealloc();
58  }
59  explicit grk_buf(const grk_buf& rhs)
60  {
61  this->operator=(rhs);
62  }
63  grk_buf& operator=(const grk_buf& rhs) // copy assignment
64  {
65  return operator=(&rhs);
66  }
67  grk_buf& operator=(const grk_buf* rhs) // copy assignment
68  {
69  if(this != rhs)
70  { // self-assignment check expected
71  buf = rhs->buf;
72  offset = rhs->offset;
73  len = rhs->len;
74  owns_data = false;
75  }
76  return *this;
77  }
78  inline bool canRead(void)
79  {
80  return offset < len;
81  }
82  inline T read(void)
83  {
84  return buf[offset++];
85  }
86  inline bool write(T val)
87  {
88  if(offset == len)
89  return false;
90  buf[offset++] = val;
91 
92  return true;
93  }
94  inline bool write(T* b, size_t size)
95  {
96  if(offset + size > len)
97  return false;
98  memcpy(buf + offset, b, size);
99  offset += size;
100 
101  return true;
102  }
103  virtual bool alloc(size_t length)
104  {
105  if(buf && len > length)
106  return true;
107  dealloc();
108  buf = A<T>::alloc(length);
109  if(!buf)
110  return false;
111  len = length;
112  offset = 0;
113  owns_data = true;
114 
115  return true;
116  }
117  virtual void dealloc()
118  {
119  if(owns_data)
120  A<T>::dealloc(buf);
121  buf = nullptr;
122  owns_data = false;
123  offset = 0;
124  len = 0;
125  }
126  // set buf to buf without owning it
127  void attach(T* buffer)
128  {
130  buf = buffer;
131  }
132  // set buf to buf and own it
133  void acquire(T* buffer)
134  {
136  buffer = buf;
137  owns_data = true;
138  }
139  // transfer buf to buffer, and cease owning it
140  void transfer(T** buffer)
141  {
142  if(buffer)
143  {
144  assert(!buf || owns_data);
145  *buffer = buf;
146  buf = nullptr;
147  owns_data = false;
148  }
149  }
150  size_t remainingLength(void)
151  {
152  return len - offset;
153  }
154  void incrementOffset(ptrdiff_t off)
155  {
156  /* we allow the offset to move to one location beyond end of buffer segment*/
157  if(off > 0)
158  {
159  if(offset > (size_t)(SIZE_MAX - (size_t)off))
160  {
161  GRK_WARN("grk_buf8: overflow");
162  offset = len;
163  }
164  else if(offset + (size_t)off > len)
165  {
166 #ifdef DEBUG_SEG_BUF
167  GRK_WARN("grk_buf8: attempt to increment buffer offset out of bounds");
168 #endif
169  offset = len;
170  }
171  else
172  {
173  offset = offset + (size_t)off;
174  }
175  }
176  else if(off < 0)
177  {
178  if(offset < (size_t)(-off))
179  {
180  GRK_WARN("grk_buf8: underflow");
181  offset = 0;
182  }
183  else
184  {
185  offset = (size_t)((ptrdiff_t)offset + off);
186  }
187  }
188  }
189  T* currPtr(void) const
190  {
191  if(!buf)
192  return nullptr;
193  return buf + offset;
194  }
195  T* buf; /* internal array*/
196  size_t offset; /* current offset into array */
197  size_t len; /* length of array */
198  bool owns_data; /* true if buffer manages the buf array */
199 };
200 
203 
204 template<typename T>
206 {
207  grk_buf2d_simple() : grk_buf2d_simple(nullptr, 0, 0) {}
208  grk_buf2d_simple(T* buf, uint32_t stride, uint32_t height)
209  : buf_(buf), stride_(stride), height_(height)
210  {}
212  {
213  buf_ += deltaX;
214 
215  return *this;
216  }
218  {
219  buf_ += deltaY * stride_;
220 
221  return *this;
222  }
223  T* buf_;
224  uint32_t stride_;
225  uint32_t height_;
226 };
227 
228 template<typename T, template<typename TT> typename A>
229 struct grk_buf2d : protected grk_buf<T, A>, public grk_rect32
230 {
231  grk_buf2d(T* buffer, bool ownsData, uint32_t w, uint32_t strd, uint32_t h)
232  : grk_buf<T, A>(buffer, ownsData), grk_rect32(0, 0, w, h), stride(strd)
233  {}
234  grk_buf2d(uint32_t w, uint32_t h) : grk_buf2d(nullptr, false, w, 0, h) {}
235  explicit grk_buf2d(const grk_rect32* b)
236  : grk_buf<T, A>(nullptr, false), grk_rect32(b->x0, b->y0, b->x1, b->y1), stride(0)
237  {}
238  explicit grk_buf2d(const grk_rect32& b)
239  : grk_buf<T, A>(nullptr, false), grk_rect32(b.x0, b.y0, b.x1, b.y1), stride(0)
240  {}
241  grk_buf2d(const grk_rect32& b, [[maybe_unused]] bool useOrigin)
242  : grk_buf<T, A>(nullptr, false), grk_rect32(b), stride(0)
243  {}
244  grk_buf2d(void) : grk_buf2d(nullptr, 0, 0, 0, false) {}
245  explicit grk_buf2d(const grk_buf2d& rhs)
246  : grk_buf<T, A>(rhs), grk_rect32(rhs), stride(rhs.stride)
247  {}
249  {
250  return grk_buf2d_simple<T>(this->buf, this->stride, this->height());
251  }
253  {
254  return grk_buf2d_simple<float>((float*)this->buf, this->stride, this->height());
255  }
256  grk_buf2d& operator=(const grk_buf2d& rhs) // copy assignment
257  {
258  return operator=(&rhs);
259  }
260  grk_buf2d& operator=(const grk_buf2d* rhs) // copy assignment
261  {
262  if(this != rhs)
263  { // self-assignment check expected
266  stride = rhs->stride;
267  }
268  return *this;
269  }
270  virtual ~grk_buf2d() = default;
271  bool alloc2d(bool clear)
272  {
273  if(!this->buf && width() && height())
274  {
275  if(!stride)
277  uint64_t data_size_needed = (uint64_t)stride * height() * sizeof(T);
278  if(!data_size_needed)
279  return true;
280  if(!grk_buf<T, A>::alloc(data_size_needed))
281  {
282  grk::GRK_ERROR("Failed to allocate aligned memory buffer of dimensions %u x %u",
283  stride, height());
284  return false;
285  }
286  if(clear)
287  memset(this->buf, 0, data_size_needed);
288  }
289 
290  return true;
291  }
292  // set buf to buffer without owning it
293  void attach(T* buffer, uint32_t strd)
294  {
295  grk_buf<T, A>::attach(buffer);
296  stride = strd;
297  }
298  void attach(grk_buf2d& rhs, uint32_t x, uint32_t y)
299  {
300  attach(&rhs, x, y);
301  }
302  void attach(grk_buf2d& rhs)
303  {
304  attach(&rhs, 0, 0);
305  }
306  void attach(grk_buf2d* rhs, uint32_t x, uint32_t y)
307  {
308  if(!rhs)
309  return;
311  this->buf = rhs->address(x, y);
312  this->len = rhs->len;
313  this->owns_data = false;
314  stride = rhs->stride;
315  }
316  void attach(grk_buf2d* rhs)
317  {
318  attach(rhs, 0, 0);
319  }
320  // set buf to buf and own it
321  void acquire(T* buffer, uint32_t strd)
322  {
323  grk_buf<T, A>::acquire(buffer);
324  stride = strd;
325  }
326  // transfer buf to buf, and cease owning it
327  void transfer(T** buffer, uint32_t* strd)
328  {
329  if(buffer)
330  {
331  grk_buf<T, A>::transfer(buffer);
332  *strd = stride;
333  }
334  }
335 
342  {
343  return !(win.x0 >= x1 || win.x1 <= x0 || win.x1 > x1 || win.y0 >= y1 || win.y1 <= win.y0 ||
344  win.y1 > y1);
345  }
346  // rhs coordinates are in "this" coordinate system
347  template<typename F>
348  void copyFrom(const grk_buf2d& src, F filter)
349  {
350  return copyFrom(&src, filter);
351  }
352  // rhs coordinates are in "this" coordinate system
353  template<typename F>
354  void copyFrom(const grk_buf2d* src, F filter)
355  {
356  auto inter = intersection(src);
357  if(inter.empty())
358  return;
359 
360  if(!src->buf)
361  return;
362 
363  T* ptr = this->buf + (inter.y0 * stride + inter.x0);
364  T* srcPtr = src->buf + ((inter.y0 - src->y0) * src->stride + inter.x0 - src->x0);
365  uint32_t len = inter.width();
366  for(uint32_t j = inter.y0; j < inter.y1; ++j)
367  {
368  filter.copy(ptr, srcPtr, len);
369  ptr += stride;
370  srcPtr += src->stride;
371  }
372  }
373  struct memcpy_from
374  {
375  void copy(T* dst, T* src, uint32_t len)
376  {
377  memcpy(dst, src, len);
378  }
379  };
380  void copyFrom(const grk_buf2d& src)
381  {
382  copy(src, memcpy_from());
383  }
384  T* getBuffer(void) const
385  {
386  return this->currPtr();
387  }
388  T* address(uint32_t x, uint32_t y)
389  {
390  return this->currPtr() + (uint64_t)x + (uint64_t)y * stride;
391  }
392  uint32_t stride;
393 };
394 
395 } // namespace grk
#define SIZE_MAX
Definition: MemManager.cpp:29
Copyright (C) 2016-2022 Grok Image Compression Inc.
Definition: ICacheable.h:20
uint32_t grk_make_aligned_width(uint32_t width)
Definition: MemManager.cpp:35
void GRK_ERROR(const char *fmt,...)
Definition: logger.cpp:58
void GRK_WARN(const char *fmt,...)
Definition: logger.cpp:49
void * grk_aligned_malloc(size_t size)
Allocate memory aligned to a 16 byte boundary.
Definition: MemManager.cpp:76
void grk_aligned_free(void *ptr)
Definition: MemManager.cpp:80
Definition: buffer.h:36
void dealloc(T *buf)
Definition: buffer.h:41
T * alloc(size_t length)
Definition: buffer.h:37
Definition: buffer.h:24
T * alloc(size_t length)
Definition: buffer.h:25
void dealloc(T *buf)
Definition: buffer.h:29
Definition: buffer.h:374
void copy(T *dst, T *src, uint32_t len)
Definition: buffer.h:375
Definition: buffer.h:206
grk_buf2d_simple & incX_IN_PLACE(size_t deltaX)
Definition: buffer.h:211
grk_buf2d_simple(T *buf, uint32_t stride, uint32_t height)
Definition: buffer.h:208
grk_buf2d_simple()
Definition: buffer.h:207
T * buf_
Definition: buffer.h:223
grk_buf2d_simple & incY_IN_PLACE(size_t deltaY)
Definition: buffer.h:217
uint32_t height_
Definition: buffer.h:225
uint32_t stride_
Definition: buffer.h:224
Definition: buffer.h:230
void transfer(T **buffer, uint32_t *strd)
Definition: buffer.h:327
void copyFrom(const grk_buf2d &src, F filter)
Definition: buffer.h:348
grk_buf2d(uint32_t w, uint32_t h)
Definition: buffer.h:234
void attach(T *buffer, uint32_t strd)
Definition: buffer.h:293
void attach(grk_buf2d *rhs, uint32_t x, uint32_t y)
Definition: buffer.h:306
grk_buf2d(const grk_rect32 &b, [[maybe_unused]] bool useOrigin)
Definition: buffer.h:241
void attach(grk_buf2d *rhs)
Definition: buffer.h:316
grk_buf2d_simple< T > simple(void) const
Definition: buffer.h:248
void attach(grk_buf2d &rhs, uint32_t x, uint32_t y)
Definition: buffer.h:298
void copyFrom(const grk_buf2d &src)
Definition: buffer.h:380
bool alloc2d(bool clear)
Definition: buffer.h:271
void copyFrom(const grk_buf2d *src, F filter)
Definition: buffer.h:354
grk_buf2d & operator=(const grk_buf2d *rhs)
Definition: buffer.h:260
grk_buf2d(void)
Definition: buffer.h:244
grk_buf2d(const grk_rect32 &b)
Definition: buffer.h:238
grk_buf2d_simple< float > simpleF(void) const
Definition: buffer.h:252
grk_buf2d(const grk_buf2d &rhs)
Definition: buffer.h:245
grk_buf2d(const grk_rect32 *b)
Definition: buffer.h:235
virtual ~grk_buf2d()=default
grk_buf2d(T *buffer, bool ownsData, uint32_t w, uint32_t strd, uint32_t h)
Definition: buffer.h:231
void acquire(T *buffer, uint32_t strd)
Definition: buffer.h:321
T * getBuffer(void) const
Definition: buffer.h:384
uint32_t stride
Definition: buffer.h:392
bool isWindowValid(grk_rect32 win)
Returns whether window bounds are valid (non empty and within buffer bounds)
Definition: buffer.h:341
void attach(grk_buf2d &rhs)
Definition: buffer.h:302
grk_buf2d & operator=(const grk_buf2d &rhs)
Definition: buffer.h:256
T * address(uint32_t x, uint32_t y)
Definition: buffer.h:388
Definition: buffer.h:48
size_t remainingLength(void)
Definition: buffer.h:150
void attach(T *buffer)
Definition: buffer.h:127
grk_buf & operator=(const grk_buf *rhs)
Definition: buffer.h:67
T read(void)
Definition: buffer.h:82
grk_buf(T *buffer, size_t length)
Definition: buffer.h:52
bool owns_data
Definition: buffer.h:198
grk_buf & operator=(const grk_buf &rhs)
Definition: buffer.h:63
size_t len
Definition: buffer.h:197
void incrementOffset(ptrdiff_t off)
Definition: buffer.h:154
void acquire(T *buffer)
Definition: buffer.h:133
bool write(T *b, size_t size)
Definition: buffer.h:94
void transfer(T **buffer)
Definition: buffer.h:140
grk_buf(T *buffer, size_t off, size_t length, bool ownsData)
Definition: buffer.h:49
grk_buf()
Definition: buffer.h:53
bool write(T val)
Definition: buffer.h:86
virtual bool alloc(size_t length)
Definition: buffer.h:103
grk_buf(const grk_buf &rhs)
Definition: buffer.h:59
bool canRead(void)
Definition: buffer.h:78
grk_buf(T *buffer, size_t length, bool ownsData)
Definition: buffer.h:54
T * currPtr(void) const
Definition: buffer.h:189
virtual ~grk_buf()
Definition: buffer.h:55
virtual void dealloc()
Definition: buffer.h:117
T * buf
Definition: buffer.h:195
size_t offset
Definition: buffer.h:196
uint32_t width() const
Definition: geometry.h:335
uint32_t y1
Definition: geometry.h:124
uint32_t x0
Definition: geometry.h:124
uint32_t x1
Definition: geometry.h:124
grk_rect< uint32_t > & operator=(const grk_rect< uint32_t > &rhs)
Definition: geometry.h:201
uint32_t height() const
Definition: geometry.h:339
grk_rect< uint32_t > intersection(const grk_rect< uint32_t > rhs) const
Definition: geometry.h:281
uint32_t y0
Definition: geometry.h:124