Grok  7.6.2
util.h
Go to the documentation of this file.
1 
19 #pragma once
20 
21 #include "grok.h"
22 #include "logger.h"
23 #include <iostream>
24 #include <cstdint>
25 #include "grk_intmath.h"
26 #include <limits> // std::numeric_limits
27 
28 namespace grk {
29 
30 inline bool mult_will_overflow(uint32_t a, uint32_t b) {
31  return (b && (a > UINT_MAX / b));
32 }
33 inline bool mult64_will_overflow(uint64_t a, uint64_t b) {
34  return (b && (a > UINT64_MAX / b));
35 }
36 
37 template<typename T> struct grk_point {
38  grk_point() : x(0), y(0){}
39  grk_point(T _x, T _y) : x(_x), y(_y){}
40  T x;
41  T y;
42 };
44 
45 
46 template<typename T> struct grk_rectangle;
49 
50 
51 template<typename T> T clip(int64_t val) {
52  if(val < (std::numeric_limits<T>::min)())
53  val = (std::numeric_limits<T>::min)();
54  else if (val > (std::numeric_limits<T>::max)())
55  val = (std::numeric_limits<T>::max)();
56  return (T)val;
57 }
58 
59 template<typename T> T sat_add(int64_t lhs, int64_t rhs) {
60  return clip<T>(lhs + rhs);
61 }
62 
63 template<typename T> T sat_add(T lhs, T rhs) {
64  return clip<T>((int64_t)lhs + rhs);
65 }
66 
67 template<typename T> T sat_sub(T lhs, T rhs) {
68  return clip<T>((int64_t)lhs - rhs);
69 }
70 
71 template<typename T> T sat_sub(int64_t lhs, int64_t rhs) {
72  return clip<T>(lhs - rhs);
73 }
74 
75 template<typename T> struct grk_rectangle {
76  T x0, y0,x1,y1;
77 
78  grk_rectangle(T x0, T y0, T x1, T y1) :
79  x0(x0), y0(y0), x1(x1), y1(y1) {
80  }
82  *this = rhs;
83  }
84  grk_rectangle(void) :
85  x0(0), y0(0), x1(0), y1(0) {
86  }
87  void print(void) const{
88  std::cout << "[" << x0 << "," << y0 << "," << x1 << "," << y1 << "]"
89  << std::endl;
90  }
91  bool is_valid(void) const {
92  return x0 <= x1 && y0 <= y1;
93  }
94  bool non_empty(void) const{
95  return x0 < x1 && y0 < y1;
96  }
98  return pt.x >= x0 && pt.y >= y0 && pt.x < x1 && pt.y < y1;
99  }
101  {
102  if (this != &rhs) { // self-assignment check expected
103  x0 = rhs.x0;
104  y0 = rhs.y0;
105  x1 = rhs.x1;
106  y1 = rhs.y1;
107  }
108 
109  return *this;
110  }
111  bool operator== (const grk_rectangle<T> &rhs)
112  {
113  if (this == &rhs)
114  return true;
115  return x0 == rhs.x0 && y0 == rhs.y0 && x1 == rhs.x1 && y1 == rhs.y1;
116  }
117 
119  *this = *rhs;
120  }
121 
123  set_rect(&rhs);
124  }
125  grk_rectangle<T> rectceildivpow2(uint32_t power) const{
126  return grk_rectangle<T>(ceildivpow2(x0, power),
127  ceildivpow2(y0, power),
128  ceildivpow2(x1, power),
129  ceildivpow2(y1, power));
130  }
131  grk_rectangle<T> ceildiv(uint32_t den) const{
132  return grk_rectangle<T>(ceildiv(x0, den),
133  ceildiv(y0, den),
134  ceildiv(x1, den),
135  ceildiv(y1, den));
136  }
138  return intersection(&rhs);
139  }
140  bool isContainedIn(const grk_rectangle<T> rhs) const{
141  return (intersection(&rhs)== *this);
142  }
144  return grk_rectangle<T>(std::max<T>(x0,rhs->x0),
145  std::max<T>(y0,rhs->y0),
146  std::min<T>(x1,rhs->x1),
147  std::min<T>(y1,rhs->y1));
148  }
149 
151  return grk_rectangle<T>(std::min<T>(x0,rhs->x0),
152  std::min<T>(y0,rhs->y0),
153  std::max<T>(x1,rhs->x1),
154  std::max<T>(y1,rhs->y1));
155  }
157  return rect_union(&rhs);
158  }
159  uint64_t area(void) const {
160  return (uint64_t)(x1 - x0) * (y1 - y0);
161  }
162  T width() const{
163  return x1 - x0;
164  }
165  T height() const{
166  return y1 - y0;
167  }
168 
169  grk_rectangle<T> pan(int64_t x, int64_t y) const {
170  return grk_rectangle<T>( sat_add<T>((int64_t)x0, (int64_t)x),
171  sat_add<T>((int64_t)y0, (int64_t)y),
172  sat_add<T>((int64_t)x1, (int64_t)x),
173  sat_add<T>((int64_t)y1, (int64_t)y));
174  }
175  grk_rectangle<T>& grow(T boundary) {
176  return grow(boundary, boundary,(std::numeric_limits<T>::max)(),(std::numeric_limits<T>::max)());
177  }
178  grk_rectangle<T>& grow(T boundaryx, T boundaryy) {
179  return grow(boundaryx, boundaryy,(std::numeric_limits<T>::max)(),(std::numeric_limits<T>::max)());
180  }
181  grk_rectangle<T>& grow(T boundary, T maxX, T maxY) {
182  return grow(boundary, boundary,maxX,maxY);
183  }
184  grk_rectangle<T>& grow(T boundaryx, T boundaryy, T maxX, T maxY) {
185  x0 = sat_sub<T>(x0, boundaryx);
186  y0 = sat_sub<T>(y0, boundaryy);
187  x1 = sat_add<T>(x1, boundaryx);
188  y1 = sat_add<T>(y1, boundaryx);
189  if (x1 > maxX)
190  x1 = maxX;
191  if (y1 > maxY)
192  y1 = maxY;
193  return *this;
194  }
195 };
196 
197 using grk_rect = grk_rectangle<int64_t>;
198 using grk_rect_u32 = grk_rectangle<uint32_t>;
199 
200 template <typename T> struct grk_buffer {
201  grk_buffer() : buf(nullptr), offset(0), len(0), owns_data(false)
202  {}
203 
204  grk_buffer(T *buffer, size_t off, size_t length, bool ownsData) : buf(buffer),
205  offset(off),
206  len(length),
207  owns_data(ownsData)
208  {}
209 
210  grk_buffer(T *buffer, size_t length, bool ownsData) : grk_buffer(buffer,0,length,ownsData)
211  {}
212 
213  virtual ~grk_buffer() {
214  dealloc();
215  }
216 
217  void dealloc(){
218  if (owns_data)
219  delete[] buf;
220  buf = nullptr;
221  owns_data = false;
222  offset = 0;
223  len = 0;
224  }
225 
226  size_t get_remaining_length(void){
227  return len - offset;
228  }
229 
230  void incr_offset(ptrdiff_t off) {
231  /* we allow the offset to move to one location beyond end of buffer segment*/
232  if (off > 0 ){
233  if (offset > (size_t)(SIZE_MAX - (size_t)off)){
234  GRK_WARN("grk_buf: overflow");
235  offset = len;
236  } else if (offset + (size_t)off > len){
237  #ifdef DEBUG_SEG_BUF
238  GRK_WARN("grk_buf: attempt to increment buffer offset out of bounds");
239  #endif
240  offset = len;
241  } else {
242  offset = offset + (size_t)off;
243  }
244  }
245  else if (off < 0){
246  if (offset < (size_t)(-off)) {
247  GRK_WARN("grk_buf: underflow");
248  offset = 0;
249  } else {
250  offset = (size_t)((ptrdiff_t)offset + off);
251  }
252  }
253 
254  }
255 
256  T* curr_ptr(){
257  if (!buf)
258  return nullptr;
259  return buf + offset;
260  }
261 
262 
263  T *buf; /* internal array*/
264  size_t offset; /* current offset into array */
265  size_t len; /* length of array */
266  bool owns_data; /* true if buffer manages the buf array */
267 } ;
269 
270 
271 template <typename T> struct grk_buffer_2d : public grk_rect_u32 {
272 
273  grk_buffer_2d(T *buffer,bool ownsData, uint32_t w, uint32_t strd, uint32_t h) : grk_rect_u32(0,0,w,h),
274  data(buffer),
275  owns_data(ownsData),
276  stride(strd)
277  {}
278  grk_buffer_2d(uint32_t w, uint32_t strd, uint32_t h) : grk_buffer_2d(nullptr,false,w,strd,h)
279  {}
280  grk_buffer_2d(uint32_t w, uint32_t h) : grk_buffer_2d(w,0,h)
281  {}
282  explicit grk_buffer_2d(grk_rect_u32 b) : grk_rect_u32(b.x0,b.y0,b.x1,b.y1),
283  data(nullptr),
284  owns_data(false),
285  stride(0)
286  {}
287  grk_buffer_2d(void) : grk_buffer_2d(nullptr,0,0,0,false)
288  {}
289 
290  grk_buffer_2d& operator=(const grk_buffer_2d& rhs) // copy assignment
291  {
292  return operator=(&rhs);
293  }
294  grk_buffer_2d& operator=(const grk_buffer_2d* rhs) // copy assignment
295  {
296  if (this != rhs) { // self-assignment check expected
297  data = rhs->data;
298  owns_data = false;
299  stride = rhs->stride;
300  *((grk_rect_u32*)this) = *((grk_rect_u32*)rhs);
301  }
302  return *this;
303  }
304 
305  virtual ~grk_buffer_2d() {
306  if (owns_data)
308  }
309 
310 
312  x0 = b.x0;
313  x1 = b.x1;
314  y0 = b.y0;
315  y1 = b.y1;
316  }
317 
318  bool alloc(bool clear){
319  if (!data && width() && height()) {
321  uint64_t data_size_needed = (uint64_t)stride * height() * sizeof(T);
322  if (!data_size_needed)
323  return true;
324  data = (T*) grk_aligned_malloc(data_size_needed);
325  if (!data) {
326  grk::GRK_ERROR("Failed to allocate aligned memory buffer of dimensions %u x %u "
327  "@ alignment %d",stride, height(), grk::default_align);
328  return false;
329  }
330  if (clear)
331  memset(data, 0, data_size_needed);
332  owns_data = true;
333  }
334 
335  return true;
336  }
337 
338  // set data to buf without owning it
339  void attach(T* buffer, uint32_t strd){
340  if (owns_data)
342  data = buffer;
343  owns_data = false;
344  stride = strd;
345  }
346  // set data to buf and own it
347  void acquire(T* buffer, uint32_t strd){
348  if (owns_data)
350  buffer = data;
351  owns_data = true;
352  stride = strd;
353  }
354  // transfer data to buf, and cease owning it
355  void transfer(T** buffer, bool* owns, uint32_t *strd){
356  if (buffer && owns){
357  *buffer = data;
358  data = nullptr;
359  *owns = owns_data;
360  owns_data = false;
361  *strd = stride;
362  }
363  }
364 
365  // rhs coordinates are in "this" coordinate system
366  template<typename F> void copy(grk_buffer_2d &rhs, F filter){
367  auto inter = this->intersection(rhs);
368  if (!inter.non_empty())
369  return;
370 
371  T* dest = data + (inter.y0 * stride + inter.x0);
372  T* src = rhs.data + ((inter.y0 - rhs.y0) * rhs.stride + inter.x0 - rhs.x0);
373  uint32_t len = inter.width();
374  for (uint32_t j = inter.y0; j < inter.y1; ++j){
375  filter.copy(dest,src, len);
376  dest += stride;
377  src += rhs.stride;
378  }
379  }
380 
381  T *data; /* internal array*/
382  bool owns_data; /* true if buffer manages the data array */
383  uint32_t stride;
384 } ;
385 
386 
387 }
388 
grk::grk_buffer::grk_buffer
grk_buffer(T *buffer, size_t length, bool ownsData)
Definition: util.h:210
grk::grk_point
Definition: util.h:37
grk::grk_buffer_2d::transfer
void transfer(T **buffer, bool *owns, uint32_t *strd)
Definition: util.h:355
grk::grk_buffer_2d::~grk_buffer_2d
virtual ~grk_buffer_2d()
Definition: util.h:305
grk::grk_buffer
Definition: util.h:200
grk::grk_aligned_free
void grk_aligned_free(void *ptr)
Definition: MemManager.cpp:123
grk::grk_buffer::grk_buffer
grk_buffer(T *buffer, size_t off, size_t length, bool ownsData)
Definition: util.h:204
grk::grk_rectangle
Definition: util.h:75
grk::grk_rectangle::height
T height() const
Definition: util.h:165
grk::mult_will_overflow
bool mult_will_overflow(uint32_t a, uint32_t b)
Definition: util.h:30
grk::grk_buffer::~grk_buffer
virtual ~grk_buffer()
Definition: util.h:213
grk::grk_buffer::offset
size_t offset
Definition: util.h:264
grk::grk_buffer_2d::owns_data
bool owns_data
Definition: util.h:382
grk::grk_rectangle::isContainedIn
bool isContainedIn(const grk_rectangle< T > rhs) const
Definition: util.h:140
logger.h
grk::grk_buffer_2d::acquire
void acquire(T *buffer, uint32_t strd)
Definition: util.h:347
grk::grk_rectangle::grow
grk_rectangle< T > & grow(T boundaryx, T boundaryy, T maxX, T maxY)
Definition: util.h:184
grk::grk_rectangle::grk_rectangle
grk_rectangle(T x0, T y0, T x1, T y1)
Definition: util.h:78
grk::grk_rectangle::grow
grk_rectangle< T > & grow(T boundaryx, T boundaryy)
Definition: util.h:178
grk::grk_rect
grk_rectangle< int64_t > grk_rect
Definition: util.h:47
grk::grk_rectangle::pan
grk_rectangle< T > pan(int64_t x, int64_t y) const
Definition: util.h:169
grk::GRK_WARN
void GRK_WARN(const char *fmt,...)
Definition: logger.cpp:49
grk::grk_rectangle::operator==
bool operator==(const grk_rectangle< T > &rhs)
Definition: util.h:111
grk::grk_buffer_2d::grk_buffer_2d
grk_buffer_2d(uint32_t w, uint32_t h)
Definition: util.h:280
grk::grk_buffer_2d::attach
void attach(T *buffer, uint32_t strd)
Definition: util.h:339
grk::grk_buffer_2d::alloc
bool alloc(bool clear)
Definition: util.h:318
grk::ceildivpow2
T ceildivpow2(T a, uint32_t b)
Definition: grk_intmath.h:37
grk::grk_rectangle::x1
T x1
Definition: util.h:76
grk::grk_rectangle::is_valid
bool is_valid(void) const
Definition: util.h:91
grk::grk_buffer_2d::operator=
grk_buffer_2d & operator=(const grk_buffer_2d &rhs)
Definition: util.h:290
grk::grk_buffer::get_remaining_length
size_t get_remaining_length(void)
Definition: util.h:226
grk::grk_rectangle::ceildiv
grk_rectangle< T > ceildiv(uint32_t den) const
Definition: util.h:131
grk::grk_buffer::owns_data
bool owns_data
Definition: util.h:266
grk_intmath.h
grk::grk_rectangle::grk_rectangle
grk_rectangle(const grk_rectangle &rhs)
Definition: util.h:81
grk::grk_buffer::curr_ptr
T * curr_ptr()
Definition: util.h:256
grk::grk_rectangle::rect_union
grk_rectangle< T > rect_union(const grk_rectangle< T > *rhs) const
Definition: util.h:150
grk::grk_buffer::dealloc
void dealloc()
Definition: util.h:217
grk::grk_make_aligned_width
uint32_t grk_make_aligned_width(uint32_t width)
Definition: MemManager.cpp:40
grk::grk_point::grk_point
grk_point(T _x, T _y)
Definition: util.h:39
grk::grk_point::x
T x
Definition: util.h:40
grk::grk_rectangle::grow
grk_rectangle< T > & grow(T boundary)
Definition: util.h:175
grk::sat_sub
T sat_sub(T lhs, T rhs)
Definition: util.h:67
grk::grk_buffer::buf
T * buf
Definition: util.h:263
grk::grk_aligned_malloc
void * grk_aligned_malloc(size_t size)
Allocate memory aligned to a 16 byte boundary.
Definition: MemManager.cpp:119
grk::grk_buffer_2d::copy
void copy(grk_buffer_2d &rhs, F filter)
Definition: util.h:366
grk::grk_buffer_2d::operator=
grk_buffer_2d & operator=(const grk_buffer_2d *rhs)
Definition: util.h:294
grk::grk_buffer_2d::grk_buffer_2d
grk_buffer_2d(void)
Definition: util.h:287
grk::grk_point::grk_point
grk_point()
Definition: util.h:38
grk::grk_buffer_2d::stride
uint32_t stride
Definition: util.h:383
grk::grk_rectangle::print
void print(void) const
Definition: util.h:87
grk::grk_rectangle::width
T width() const
Definition: util.h:162
grk::grk_rectangle::contains
bool contains(grk_point< T > pt)
Definition: util.h:97
grk::grk_rectangle::rect_union
grk_rectangle< T > rect_union(const grk_rectangle< T > &rhs) const
Definition: util.h:156
grk::grk_rectangle::intersection
grk_rectangle< T > intersection(const grk_rectangle< T > *rhs) const
Definition: util.h:143
grk::grk_buffer_2d
Definition: util.h:271
grk
Copyright (C) 2016-2020 Grok Image Compression Inc.
Definition: BitIO.cpp:23
grk::grk_point::y
T y
Definition: util.h:41
grk::grk_buffer::len
size_t len
Definition: util.h:265
grk::grk_rectangle::area
uint64_t area(void) const
Definition: util.h:159
grok.h
grk::sat_add
T sat_add(int64_t lhs, int64_t rhs)
Definition: util.h:59
grk::grk_rect_u32
grk_rectangle< uint32_t > grk_rect_u32
Definition: util.h:48
grk::grk_buffer_2d::copy_rect
void copy_rect(grk_rect_u32 b)
Definition: util.h:311
grk::grk_rectangle::intersection
grk_rectangle< T > intersection(const grk_rectangle< T > rhs) const
Definition: util.h:137
grk::grk_buffer::incr_offset
void incr_offset(ptrdiff_t off)
Definition: util.h:230
grk::grk_buffer_2d::grk_buffer_2d
grk_buffer_2d(uint32_t w, uint32_t strd, uint32_t h)
Definition: util.h:278
grk::grk_rectangle::grow
grk_rectangle< T > & grow(T boundary, T maxX, T maxY)
Definition: util.h:181
grk::grk_buffer::grk_buffer
grk_buffer()
Definition: util.h:201
grk::grk_rectangle::rectceildivpow2
grk_rectangle< T > rectceildivpow2(uint32_t power) const
Definition: util.h:125
grk::grk_rectangle::set_rect
void set_rect(grk_rectangle< T > *rhs)
Definition: util.h:118
grk::grk_rectangle::set_rect
void set_rect(grk_rectangle< T > rhs)
Definition: util.h:122
grk::grk_buffer_2d::data
T * data
Definition: util.h:381
grk::grk_rectangle::operator=
grk_rectangle< T > & operator=(const grk_rectangle< T > &rhs)
Definition: util.h:100
grk::grk_rectangle::x0
T x0
Definition: util.h:76
grk::grk_rectangle::y1
T y1
Definition: util.h:76
grk::clip
T clip(int64_t val)
Definition: util.h:51
grk::mult64_will_overflow
bool mult64_will_overflow(uint64_t a, uint64_t b)
Definition: util.h:33
grk::grk_buffer_2d::grk_buffer_2d
grk_buffer_2d(T *buffer, bool ownsData, uint32_t w, uint32_t strd, uint32_t h)
Definition: util.h:273
grk::grk_buffer_2d::grk_buffer_2d
grk_buffer_2d(grk_rect_u32 b)
Definition: util.h:282
grk::default_align
const size_t default_align
Definition: MemManager.h:28
grk::grk_rectangle::y0
T y0
Definition: util.h:76
SIZE_MAX
#define SIZE_MAX
Definition: MemManager.cpp:33
grk::GRK_ERROR
void GRK_ERROR(const char *fmt,...)
Definition: logger.cpp:57
grk::grk_rectangle::non_empty
bool non_empty(void) const
Definition: util.h:94
grk::grk_rectangle::grk_rectangle
grk_rectangle(void)
Definition: util.h:84