Grok  9.7.5
MemManager.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2016-2022 Grok Image Compression Inc.
3  *
4  * This source code is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU Affero General Public License, version 3,
6  * as published by the Free Software Foundation.
7  *
8  * This source code is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU Affero General Public License for more details.
12  *
13  * You should have received a copy of the GNU Affero General Public License
14  * along with this program. If not, see <http://www.gnu.org/licenses/>.
15  *
16  *
17  * This source code incorporates work covered by the BSD 2-clause license.
18  * Please see the LICENSE file in the root directory for details.
19  *
20  */
21 #pragma once
22 
23 #if defined(__GNUC__) && !defined(GROK_SKIP_POISON)
24 #pragma GCC poison malloc calloc realloc free
25 #endif
26 
27 #include <cstddef>
28 
29 namespace grk
30 {
31 uint32_t grkMakeAlignedWidth(uint32_t width);
37 void* grkMalloc(size_t size);
44 void* grkCalloc(size_t numOfElements, size_t sizeOfElements);
50 void* grkAlignedMalloc(size_t size);
51 void grkAlignedFree(void* ptr);
58 void* grkRealloc(void* m, size_t s);
63 void grkFree(void* m);
64 
65 template<typename T>
67 {
68  T* alloc(size_t length)
69  {
70  return new T[length];
71  }
72  void dealloc(T* buf)
73  {
74  delete[] buf;
75  }
76 };
77 template<typename T>
79 {
80  T* alloc(size_t length)
81  {
82  return (T*)grkAlignedMalloc(length * sizeof(T));
83  }
84  void dealloc(T* buf)
85  {
86  grkAlignedFree(buf);
87  }
88 };
89 template<typename T, template<typename TT> typename A>
90 struct grk_buf : A<T>
91 {
92  grk_buf(T* buffer, size_t off, size_t length, bool ownsData)
93  : buf(buffer), offset(off), len(length), owns_data(ownsData)
94  {}
95  grk_buf(T* buffer, size_t length) : grk_buf(buffer, 0, length, false) {}
96  grk_buf() : grk_buf(0, 0, 0, false) {}
97  grk_buf(T* buffer, size_t length, bool ownsData) : grk_buf(buffer, 0, length, ownsData) {}
98  virtual ~grk_buf()
99  {
100  dealloc();
101  }
102  explicit grk_buf(const grk_buf& rhs)
103  {
104  this->operator=(rhs);
105  }
106  grk_buf& operator=(const grk_buf& rhs) // copy assignment
107  {
108  return operator=(&rhs);
109  }
110  grk_buf& operator=(const grk_buf* rhs) // copy assignment
111  {
112  if(this != rhs)
113  { // self-assignment check expected
114  buf = rhs->buf;
115  offset = rhs->offset;
116  len = rhs->len;
117  owns_data = false;
118  }
119  return *this;
120  }
121  inline bool canRead(void)
122  {
123  return offset < len;
124  }
125  inline T read(void)
126  {
127  return buf[offset++];
128  }
129  inline bool write(T val)
130  {
131  if(offset == len)
132  return false;
133  buf[offset++] = val;
134 
135  return true;
136  }
137  inline bool write(T* b, size_t size)
138  {
139  if(offset + size > len)
140  return false;
141  memcpy(buf + offset, b, size);
142  offset += size;
143 
144  return true;
145  }
146  virtual bool alloc(size_t length)
147  {
148  if(buf && len > length)
149  return true;
150  dealloc();
151  buf = A<T>::alloc(length);
152  if(!buf)
153  return false;
154  len = length;
155  offset = 0;
156  owns_data = true;
157 
158  return true;
159  }
160  virtual void dealloc()
161  {
162  if(owns_data)
163  A<T>::dealloc(buf);
164  buf = nullptr;
165  owns_data = false;
166  offset = 0;
167  len = 0;
168  }
169  // set buf to buf without owning it
170  void attach(T* buffer)
171  {
173  buf = buffer;
174  }
175  // set buf to buf and own it
176  void acquire(T* buffer)
177  {
179  buffer = buf;
180  owns_data = true;
181  }
182  // transfer buf to buffer, and cease owning it
183  void transfer(T** buffer)
184  {
185  if(buffer)
186  {
187  assert(!buf || owns_data);
188  *buffer = buf;
189  buf = nullptr;
190  owns_data = false;
191  }
192  }
193  size_t remainingLength(void)
194  {
195  return len - offset;
196  }
197  void incrementOffset(ptrdiff_t off)
198  {
199  /* we allow the offset to move to one location beyond end of buffer segment*/
200  if(off > 0)
201  {
202  if(offset > (size_t)(SIZE_MAX - (size_t)off))
203  {
204  GRK_WARN("grk_buf8: overflow");
205  offset = len;
206  }
207  else if(offset + (size_t)off > len)
208  {
209 #ifdef DEBUG_SEG_BUF
210  GRK_WARN("grk_buf8: attempt to increment buffer offset out of bounds");
211 #endif
212  offset = len;
213  }
214  else
215  {
216  offset = offset + (size_t)off;
217  }
218  }
219  else if(off < 0)
220  {
221  if(offset < (size_t)(-off))
222  {
223  GRK_WARN("grk_buf8: underflow");
224  offset = 0;
225  }
226  else
227  {
228  offset = (size_t)((ptrdiff_t)offset + off);
229  }
230  }
231  }
232  T* currPtr(void) const
233  {
234  if(!buf)
235  return nullptr;
236  return buf + offset;
237  }
238  T* buf; /* internal array*/
239  size_t offset; /* current offset into array */
240  size_t len; /* length of array */
241  bool owns_data; /* true if buffer manages the buf array */
242 };
243 
246 
247 template<typename T>
249 {
251  grk_buf2d_simple(T* buf, uint32_t stride) : buf_(buf), stride_(stride) {}
252  grk_buf2d_simple incX_IPL(size_t deltaX)
253  {
254  buf_ += deltaX;
255 
256  return *this;
257  }
258  grk_buf2d_simple incX(size_t deltaX)
259  {
260  return grk_buf2d_simple(buf_ + deltaX, stride_);
261  }
262  grk_buf2d_simple incY_IPL(size_t deltaY)
263  {
264  buf_ += deltaY * stride_;
265 
266  return *this;
267  }
268  grk_buf2d_simple incY(size_t deltaY)
269  {
270  return grk_buf2d_simple(buf_ + deltaY * stride_, stride_);
271  }
272  T* buf_;
273  uint32_t stride_;
274 };
275 
276 template<typename T, template<typename TT> typename A>
277 struct grk_buf2d : protected grk_buf<T, A>, public grk_rect32
278 {
279  grk_buf2d(T* buffer, bool ownsData, uint32_t w, uint32_t strd, uint32_t h)
280  : grk_buf<T, A>(buffer, ownsData), grk_rect32(0, 0, w, h), stride(strd)
281  {}
282  grk_buf2d(uint32_t w, uint32_t strd, uint32_t h) : grk_buf2d(nullptr, false, w, strd, h) {}
283  grk_buf2d(uint32_t w, uint32_t h) : grk_buf2d(w, 0, h) {}
284  explicit grk_buf2d(const grk_rect32* b)
285  : grk_buf<T, A>(nullptr, false), grk_rect32(b->x0, b->y0, b->x1, b->y1), stride(0)
286  {}
287  grk_buf2d(void) : grk_buf2d(nullptr, 0, 0, 0, false) {}
288  explicit grk_buf2d(const grk_buf2d& rhs)
289  : grk_buf<T, A>(rhs), grk_rect32(rhs), stride(rhs.stride)
290  {}
292  {
293  return grk_buf2d_simple<T>(this->buf, this->stride);
294  }
296  {
297  return grk_buf2d_simple<float>((float*)this->buf, this->stride);
298  }
299  grk_buf2d& operator=(const grk_buf2d& rhs) // copy assignment
300  {
301  return operator=(&rhs);
302  }
303  grk_buf2d& operator=(const grk_buf2d* rhs) // copy assignment
304  {
305  if(this != rhs)
306  { // self-assignment check expected
309  stride = rhs->stride;
310  }
311  return *this;
312  }
313  virtual ~grk_buf2d() = default;
314  bool alloc2d(bool clear)
315  {
316  if(!this->buf && width() && height())
317  {
318  if(!stride)
320  uint64_t data_size_needed = (uint64_t)stride * height() * sizeof(T);
321  if(!data_size_needed)
322  return true;
323  if(!grk_buf<T, A>::alloc(data_size_needed))
324  {
325  grk::GRK_ERROR("Failed to allocate aligned memory buffer of dimensions %u x %u",
326  stride, height());
327  return false;
328  }
329  if(clear)
330  memset(this->buf, 0, data_size_needed);
331  }
332 
333  return true;
334  }
335  // set buf to buf without owning it
336  void attach(T* buffer, uint32_t strd)
337  {
338  grk_buf<T, A>::attach(buffer);
339  stride = strd;
340  }
341  // set buf to buf and own it
342  void acquire(T* buffer, uint32_t strd)
343  {
344  grk_buf<T, A>::acquire(buffer);
345  stride = strd;
346  }
347  // transfer buf to buf, and cease owning it
348  void transfer(T** buffer, uint32_t* strd)
349  {
350  if(buffer)
351  {
352  grk_buf<T, A>::transfer(buffer);
353  *strd = stride;
354  }
355  }
356 
363  {
364  return !(win.x0 >= x1 || win.x1 <= x0 || win.x1 > x1 || win.y0 >= y1 || win.y1 <= win.y0 ||
365  win.y1 > y1);
366  }
367 
378  bool read(grk_rect32 window, int32_t* dest, const uint32_t destColStride,
379  const uint32_t destStride)
380  {
381  GRK_UNUSED(dest);
382  GRK_UNUSED(destColStride);
383  GRK_UNUSED(destStride);
384 
385  if(!isWindowValid(window))
386  return false;
387 
388  // 1. calculate overlap
389 
390  return true;
391  }
392 
402  bool write(grk_rect32 window, const int32_t* src, const uint32_t srcColStride,
403  const uint32_t srcStride)
404  {
405  GRK_UNUSED(src);
406  GRK_UNUSED(srcColStride);
407  GRK_UNUSED(srcStride);
408 
409  if(!isWindowValid(window))
410  return false;
411 
412  return true;
413  }
414 
415  bool copy_data(T* dest, uint32_t dest_w, uint32_t dest_h, uint32_t dest_stride) const
416  {
417  assert(dest_w <= width());
418  assert(dest_h <= height());
419  assert(dest_stride <= stride);
420  if(dest_w > width() || dest_h > height() || dest_stride > stride)
421  return false;
422  if(!this->buf)
423  return false;
424  auto src_ptr = this->buf;
425  auto dest_ptr = dest;
426  for(uint32_t j = 0; j < dest_h; ++j)
427  {
428  memcpy(dest_ptr, src_ptr, dest_w * sizeof(T));
429  dest_ptr += dest_stride;
430  src_ptr += stride;
431  }
432  return true;
433  }
434  // rhs coordinates are in "this" coordinate system
435  template<typename F>
436  void copy(const grk_buf2d& rhs, F filter)
437  {
438  auto inter = this->intersection(rhs);
439  if(inter.empty())
440  return;
441 
442  T* dest = this->buf + (inter.y0 * stride + inter.x0);
443  T* src = rhs.buf + ((inter.y0 - rhs.y0) * rhs.stride + inter.x0 - rhs.x0);
444  uint32_t len = inter.width();
445  for(uint32_t j = inter.y0; j < inter.y1; ++j)
446  {
447  filter.copy(dest, src, len);
448  dest += stride;
449  src += rhs.stride;
450  }
451  }
452  T* getBuffer(void) const
453  {
454  return this->currPtr();
455  }
456  uint32_t stride;
457 };
458 
459 } // namespace grk
#define SIZE_MAX
Definition: MemManager.cpp:30
#define GRK_UNUSED(x)
Definition: grk_includes.h:87
Copyright (C) 2016-2022 Grok Image Compression Inc.
Definition: ICacheable.h:20
void grkAlignedFree(void *ptr)
Definition: MemManager.cpp:127
void grkFree(void *ptr)
Deallocates or frees a memory block.
Definition: MemManager.cpp:149
void GRK_ERROR(const char *fmt,...)
Definition: logger.cpp:58
void GRK_WARN(const char *fmt,...)
Definition: logger.cpp:49
void * grkAlignedMalloc(size_t size)
Allocate memory aligned to a 16 byte boundary.
Definition: MemManager.cpp:123
void * grkMalloc(size_t size)
Allocate an uninitialized memory block.
Definition: MemManager.cpp:108
void * grkCalloc(size_t num, size_t size)
Allocate a memory block with elements initialized to 0.
Definition: MemManager.cpp:115
void * grkRealloc(void *ptr, size_t new_size)
Reallocate memory blocks.
Definition: MemManager.cpp:142
uint32_t grkMakeAlignedWidth(uint32_t width)
Definition: MemManager.cpp:40
Definition: MemManager.h:79
void dealloc(T *buf)
Definition: MemManager.h:84
T * alloc(size_t length)
Definition: MemManager.h:80
Definition: MemManager.h:67
T * alloc(size_t length)
Definition: MemManager.h:68
void dealloc(T *buf)
Definition: MemManager.h:72
Definition: MemManager.h:249
grk_buf2d_simple incY_IPL(size_t deltaY)
Definition: MemManager.h:262
grk_buf2d_simple()
Definition: MemManager.h:250
T * buf_
Definition: MemManager.h:272
grk_buf2d_simple incX_IPL(size_t deltaX)
Definition: MemManager.h:252
grk_buf2d_simple incX(size_t deltaX)
Definition: MemManager.h:258
grk_buf2d_simple incY(size_t deltaY)
Definition: MemManager.h:268
uint32_t stride_
Definition: MemManager.h:273
grk_buf2d_simple(T *buf, uint32_t stride)
Definition: MemManager.h:251
Definition: MemManager.h:278
void transfer(T **buffer, uint32_t *strd)
Definition: MemManager.h:348
grk_buf2d(uint32_t w, uint32_t h)
Definition: MemManager.h:283
void attach(T *buffer, uint32_t strd)
Definition: MemManager.h:336
bool write(grk_rect32 window, const int32_t *src, const uint32_t srcColStride, const uint32_t srcStride)
Write the contents of a rectangular window from a user buffer.
Definition: MemManager.h:402
bool copy_data(T *dest, uint32_t dest_w, uint32_t dest_h, uint32_t dest_stride) const
Definition: MemManager.h:415
grk_buf2d_simple< T > simple(void) const
Definition: MemManager.h:291
grk_buf2d(uint32_t w, uint32_t strd, uint32_t h)
Definition: MemManager.h:282
bool alloc2d(bool clear)
Definition: MemManager.h:314
void copy(const grk_buf2d &rhs, F filter)
Definition: MemManager.h:436
grk_buf2d & operator=(const grk_buf2d *rhs)
Definition: MemManager.h:303
grk_buf2d(void)
Definition: MemManager.h:287
grk_buf2d_simple< float > simpleF(void) const
Definition: MemManager.h:295
grk_buf2d(const grk_buf2d &rhs)
Definition: MemManager.h:288
grk_buf2d(const grk_rect32 *b)
Definition: MemManager.h:284
bool read(grk_rect32 window, int32_t *dest, const uint32_t destColStride, const uint32_t destStride)
Read the contents of a rectangular window into a user buffer.
Definition: MemManager.h:378
virtual ~grk_buf2d()=default
grk_buf2d(T *buffer, bool ownsData, uint32_t w, uint32_t strd, uint32_t h)
Definition: MemManager.h:279
void acquire(T *buffer, uint32_t strd)
Definition: MemManager.h:342
T * getBuffer(void) const
Definition: MemManager.h:452
uint32_t stride
Definition: MemManager.h:456
bool isWindowValid(grk_rect32 win)
Returns whether window bounds are valid (non empty and within buffer bounds)
Definition: MemManager.h:362
grk_buf2d & operator=(const grk_buf2d &rhs)
Definition: MemManager.h:299
Definition: MemManager.h:91
size_t remainingLength(void)
Definition: MemManager.h:193
void attach(T *buffer)
Definition: MemManager.h:170
grk_buf & operator=(const grk_buf *rhs)
Definition: MemManager.h:110
T read(void)
Definition: MemManager.h:125
grk_buf(T *buffer, size_t length)
Definition: MemManager.h:95
bool owns_data
Definition: MemManager.h:241
grk_buf & operator=(const grk_buf &rhs)
Definition: MemManager.h:106
size_t len
Definition: MemManager.h:240
void incrementOffset(ptrdiff_t off)
Definition: MemManager.h:197
void acquire(T *buffer)
Definition: MemManager.h:176
bool write(T *b, size_t size)
Definition: MemManager.h:137
void transfer(T **buffer)
Definition: MemManager.h:183
grk_buf(T *buffer, size_t off, size_t length, bool ownsData)
Definition: MemManager.h:92
grk_buf()
Definition: MemManager.h:96
bool write(T val)
Definition: MemManager.h:129
virtual bool alloc(size_t length)
Definition: MemManager.h:146
grk_buf(const grk_buf &rhs)
Definition: MemManager.h:102
bool canRead(void)
Definition: MemManager.h:121
grk_buf(T *buffer, size_t length, bool ownsData)
Definition: MemManager.h:97
T * currPtr(void) const
Definition: MemManager.h:232
virtual ~grk_buf()
Definition: MemManager.h:98
virtual void dealloc()
Definition: MemManager.h:160
T * buf
Definition: MemManager.h:238
size_t offset
Definition: MemManager.h:239
uint32_t width() const
Definition: util.h:246
uint32_t y1
Definition: util.h:109
uint32_t x0
Definition: util.h:109
uint32_t x1
Definition: util.h:109
grk_rect< uint32_t > & operator=(const grk_rect< uint32_t > &rhs)
Definition: util.h:133
uint32_t height() const
Definition: util.h:250
grk_rect< uint32_t > intersection(const grk_rect< uint32_t > rhs) const
Definition: util.h:200
uint32_t y0
Definition: util.h:109