Grok  7.6.6
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(uint64_t a, uint64_t b) {
31  return (b && (a > UINT64_MAX / b));
32 }
33 
34 template<typename T> struct grk_point {
35  grk_point() : x(0), y(0){}
36  grk_point(T _x, T _y) : x(_x), y(_y){}
37  T x;
38  T y;
39 };
41 
42 template<typename T> struct grk_line {
43  grk_line() : x0(0), x1(0){}
44  grk_line(T _x0, T _x1) : x0(_x0), x1(_x1){}
45  T x0;
46  T x1;
47  T length(){
48  assert(x1 >= x0);
49  return (T)(x1-x0);
50  }
51 };
53 
54 template<typename T> struct grk_rectangle;
57 
58 template<typename T> T clip(int64_t val) {
59  static_assert(sizeof(T) <= 4);
60  if(val < (std::numeric_limits<T>::min)())
61  val = (std::numeric_limits<T>::min)();
62  else if (val > (std::numeric_limits<T>::max)())
63  val = (std::numeric_limits<T>::max)();
64  return (T)val;
65 }
66 
67 template<typename T> T sat_add(int64_t lhs, int64_t rhs) {
68  return clip<T>(lhs + rhs);
69 }
70 
71 template<typename T> T sat_add(T lhs, T rhs) {
72  return clip<T>((int64_t)lhs + rhs);
73 }
74 
75 template<typename T> T sat_sub(T lhs, T rhs) {
76  return clip<T>((int64_t)lhs - rhs);
77 }
78 
79 template<typename T> T sat_sub(int64_t lhs, int64_t rhs) {
80  return clip<T>(lhs - rhs);
81 }
82 
83 template<typename T> struct grk_rectangle {
84  T x0, y0,x1,y1;
85 
86  grk_rectangle(T x0, T y0, T x1, T y1) :
87  x0(x0), y0(y0), x1(x1), y1(y1) {
88  }
90  *this = rhs;
91  }
92  grk_rectangle(void) :
93  x0(0), y0(0), x1(0), y1(0) {
94  }
95  void print(void) const{
96  std::cout << "[" << x0 << "," << y0 << "," << x1 << "," << y1 << "]"
97  << std::endl;
98  }
99  bool is_valid(void) const {
100  return x0 <= x1 && y0 <= y1;
101  }
102  bool non_empty(void) const{
103  return x0 < x1 && y0 < y1;
104  }
106  return pt.x >= x0 && pt.y >= y0 && pt.x < x1 && pt.y < y1;
107  }
109  {
110  if (this != &rhs) { // self-assignment check expected
111  x0 = rhs.x0;
112  y0 = rhs.y0;
113  x1 = rhs.x1;
114  y1 = rhs.y1;
115  }
116 
117  return *this;
118  }
119  bool operator== (const grk_rectangle<T> &rhs) const
120  {
121  if (this == &rhs)
122  return true;
123  return x0 == rhs.x0 && y0 == rhs.y0 && x1 == rhs.x1 && y1 == rhs.y1;
124  }
125 
127  *this = *rhs;
128  }
129 
131  set_rect(&rhs);
132  }
133  grk_rectangle<T> rectceildivpow2(uint32_t power) const{
134  return grk_rectangle<T>(ceildivpow2(x0, power),
135  ceildivpow2(y0, power),
136  ceildivpow2(x1, power),
137  ceildivpow2(y1, power));
138  }
139  grk_rectangle<T> rectceildiv(uint32_t den) const{
140  return grk_rectangle<T>(ceildiv(x0, den),
141  ceildiv(y0, den),
142  ceildiv(x1, den),
143  ceildiv(y1, den));
144  }
145  grk_rectangle<T> rectceildiv(uint32_t denx, uint32_t deny) const{
146  return grk_rectangle<T>(ceildiv(x0, denx),
147  ceildiv(y0, deny),
148  ceildiv(x1, denx),
149  ceildiv(y1, deny));
150  }
152  return intersection(&rhs);
153  }
154  bool isContainedIn(const grk_rectangle<T> rhs) const{
155  return (intersection(&rhs)== *this);
156  }
157  void clip(const grk_rectangle<T> *rhs){
158  *this = grk_rectangle<T>(std::max<T>(x0,rhs->x0),
159  std::max<T>(y0,rhs->y0),
160  std::min<T>(x1,rhs->x1),
161  std::min<T>(y1,rhs->y1));
162  }
163 
165  return grk_rectangle<T>(std::max<T>(x0,rhs->x0),
166  std::max<T>(y0,rhs->y0),
167  std::min<T>(x1,rhs->x1),
168  std::min<T>(y1,rhs->y1));
169  }
170 
172  return grk_rectangle<T>(std::min<T>(x0,rhs->x0),
173  std::min<T>(y0,rhs->y0),
174  std::max<T>(x1,rhs->x1),
175  std::max<T>(y1,rhs->y1));
176  }
178  return rect_union(&rhs);
179  }
180  uint64_t area(void) const {
181  return (uint64_t)(x1 - x0) * (y1 - y0);
182  }
183  T width() const{
184  return x1 - x0;
185  }
186  T height() const{
187  return y1 - y0;
188  }
190  return grk_line<T>(x0,x1);
191  }
193  return grk_line<T>(y0,y1);
194  }
195  grk_rectangle<T> pan(int64_t x, int64_t y) const {
196  auto rc = *this;
197  rc.pan_inplace(x,y);
198  return rc;
199  }
200  void pan_inplace(int64_t x, int64_t y) {
201  x0 = sat_add<T>((int64_t)x0, (int64_t)x);
202  y0 = sat_add<T>((int64_t)y0, (int64_t)y);
203  x1 = sat_add<T>((int64_t)x1, (int64_t)x);
204  y1 = sat_add<T>((int64_t)y1, (int64_t)y);
205  }
206  grk_rectangle<T>& grow(T boundary) {
207  return grow(boundary, boundary,(std::numeric_limits<T>::max)(),(std::numeric_limits<T>::max)());
208  }
209  grk_rectangle<T>& grow(T boundaryx, T boundaryy) {
210  return grow(boundaryx, boundaryy,(std::numeric_limits<T>::max)(),(std::numeric_limits<T>::max)());
211  }
212  grk_rectangle<T>& grow(T boundary, T maxX, T maxY) {
213  return grow(boundary, boundary,maxX,maxY);
214  }
215  grk_rectangle<T>& grow(T boundaryx, T boundaryy, T maxX, T maxY) {
216  return grow(boundaryx,boundaryy, grk_rectangle<T>((T)0,(T)0,maxX,maxY));
217  }
218  grk_rectangle<T>& grow(T boundary, grk_rectangle<T> bounds) {
219  return grow(boundary,boundary, bounds);
220  }
221  grk_rectangle<T>& grow(T boundaryx, T boundaryy, grk_rectangle<T> bounds) {
222  x0 = std::max<T>( sat_sub<T>(x0, boundaryx), bounds.x0);
223  y0 = std::max<T>( sat_sub<T>(y0, boundaryy), bounds.y0);
224  x1 = std::min<T>( sat_add<T>(x1, boundaryx), bounds.x1);
225  y1 = std::min<T>( sat_add<T>(y1, boundaryy), bounds.y1);
226 
227  return *this;
228  }
229 };
230 
231 using grk_rect = grk_rectangle<int64_t>;
232 using grk_rect_u32 = grk_rectangle<uint32_t>;
233 
234 template <typename T> struct grk_buffer {
235  grk_buffer(T *buffer, size_t off, size_t length, bool ownsData) : buf(buffer),
236  offset(off),
237  len(length),
238  owns_data(ownsData)
239  {}
240 
241  grk_buffer() : grk_buffer(0,0,0,false)
242  {}
243 
244  grk_buffer(T *buffer, size_t length, bool ownsData) : grk_buffer(buffer,0,length,ownsData)
245  {}
246 
247  virtual ~grk_buffer() {
248  dealloc();
249  }
250 
251  void alloc(size_t length) {
252  dealloc();
253  buf = new T[length];
254  len = length;
255  offset = 0;
256  owns_data = true;
257  }
258 
259  virtual void dealloc(){
260  if (owns_data)
261  delete[] buf;
262  buf = nullptr;
263  owns_data = false;
264  offset = 0;
265  len = 0;
266  }
267 
268  size_t get_remaining_length(void){
269  return len - offset;
270  }
271 
272  void incr_offset(ptrdiff_t off) {
273  /* we allow the offset to move to one location beyond end of buffer segment*/
274  if (off > 0 ){
275  if (offset > (size_t)(SIZE_MAX - (size_t)off)){
276  GRK_WARN("grk_buf: overflow");
277  offset = len;
278  } else if (offset + (size_t)off > len){
279  #ifdef DEBUG_SEG_BUF
280  GRK_WARN("grk_buf: attempt to increment buffer offset out of bounds");
281  #endif
282  offset = len;
283  } else {
284  offset = offset + (size_t)off;
285  }
286  }
287  else if (off < 0){
288  if (offset < (size_t)(-off)) {
289  GRK_WARN("grk_buf: underflow");
290  offset = 0;
291  } else {
292  offset = (size_t)((ptrdiff_t)offset + off);
293  }
294  }
295 
296  }
297 
298  T* curr_ptr(){
299  if (!buf)
300  return nullptr;
301  return buf + offset;
302  }
303 
304  T *buf; /* internal array*/
305  size_t offset; /* current offset into array */
306  size_t len; /* length of array */
307  bool owns_data; /* true if buffer manages the buf array */
308 } ;
310 
311 template <typename T> struct grk_buffer_2d : public grk_rect_u32 {
312 
313  grk_buffer_2d(T *buffer,bool ownsData, uint32_t w, uint32_t strd, uint32_t h) : grk_rect_u32(0,0,w,h),
314  data(buffer),
315  owns_data(ownsData),
316  stride(strd)
317  {}
318  grk_buffer_2d(uint32_t w, uint32_t strd, uint32_t h) : grk_buffer_2d(nullptr,false,w,strd,h)
319  {}
320  grk_buffer_2d(uint32_t w, uint32_t h) : grk_buffer_2d(w,0,h)
321  {}
322  explicit grk_buffer_2d(grk_rect_u32 b) : grk_rect_u32(b.x0,b.y0,b.x1,b.y1),
323  data(nullptr),
324  owns_data(false),
325  stride(0)
326  {}
327  grk_buffer_2d(void) : grk_buffer_2d(nullptr,0,0,0,false)
328  {}
329 
330  grk_buffer_2d& operator=(const grk_buffer_2d& rhs) // copy assignment
331  {
332  return operator=(&rhs);
333  }
334  grk_buffer_2d& operator=(const grk_buffer_2d* rhs) // copy assignment
335  {
336  if (this != rhs) { // self-assignment check expected
337  data = rhs->data;
338  owns_data = false;
339  stride = rhs->stride;
340  *((grk_rect_u32*)this) = *((grk_rect_u32*)rhs);
341  }
342  return *this;
343  }
344  virtual ~grk_buffer_2d() {
345  if (owns_data)
347  }
349  x0 = b.x0;
350  x1 = b.x1;
351  y0 = b.y0;
352  y1 = b.y1;
353  }
354  bool alloc(bool clear){
355  if (!data && width() && height()) {
357  uint64_t data_size_needed = (uint64_t)stride * height() * sizeof(T);
358  if (!data_size_needed)
359  return true;
360  data = (T*) grk_aligned_malloc(data_size_needed);
361  if (!data) {
362  grk::GRK_ERROR("Failed to allocate aligned memory buffer of dimensions %u x %u "
363  "@ alignment %d",stride, height(), grk::default_align);
364  return false;
365  }
366  if (clear)
367  memset(data, 0, data_size_needed);
368  owns_data = true;
369  }
370 
371  return true;
372  }
373 
374  // set data to buf without owning it
375  void attach(T* buffer, uint32_t strd){
376  if (owns_data)
378  data = buffer;
379  owns_data = false;
380  stride = strd;
381  }
382  // set data to buf and own it
383  void acquire(T* buffer, uint32_t strd){
384  if (owns_data)
386  buffer = data;
387  owns_data = true;
388  stride = strd;
389  }
390  // transfer data to buf, and cease owning it
391  void transfer(T** buffer, bool* owns, uint32_t *strd){
392  if (buffer && owns){
393  *buffer = data;
394  data = nullptr;
395  *owns = owns_data;
396  owns_data = false;
397  *strd = stride;
398  }
399  }
400 
401  bool copy_data(T* dest, uint32_t dest_w, uint32_t dest_h, uint32_t dest_stride) const{
402  assert(dest_w <= width());
403  assert(dest_h <= height());
404  assert(dest_stride <= stride);
405  if (dest_w > width() || dest_h > height() || dest_stride > stride)
406  return false;
407  if (!data)
408  return false;
409  auto src_ptr = data;
410  auto dest_ptr = dest;
411  for (uint32_t j = 0; j < dest_h; ++j) {
412  memcpy(dest_ptr,src_ptr, dest_w* sizeof(T));
413  dest_ptr += dest_stride;
414  src_ptr += stride;
415  }
416  return true;
417  }
418 
419  // rhs coordinates are in "this" coordinate system
420  template<typename F> void copy(grk_buffer_2d &rhs, F filter){
421  auto inter = this->intersection(rhs);
422  if (!inter.non_empty())
423  return;
424 
425  T* dest = data + (inter.y0 * stride + inter.x0);
426  T* src = rhs.data + ((inter.y0 - rhs.y0) * rhs.stride + inter.x0 - rhs.x0);
427  uint32_t len = inter.width();
428  for (uint32_t j = inter.y0; j < inter.y1; ++j){
429  filter.copy(dest,src, len);
430  dest += stride;
431  src += rhs.stride;
432  }
433  }
434 
435  T *data; /* internal array*/
436  bool owns_data; /* true if buffer manages the data array */
437  uint32_t stride;
438 } ;
439 
440 grk_rect_u32 getTileCompBandWindow(uint8_t num_res,
441  uint8_t resno,
442  uint8_t orientation,
443  grk_rect_u32 unreducedTileCompWindow);
444 
445 
446 }
#define SIZE_MAX
Definition: MemManager.cpp:33
Copyright (C) 2016-2021 Grok Image Compression Inc.
Definition: BitIO.cpp:23
grk_rectangle< int64_t > grk_rect
Definition: util.h:55
T clip(int64_t val)
Definition: util.h:58
grk_rect_u32 getTileCompBandWindow(uint8_t num_res, uint8_t resno, uint8_t orientation, grk_rect_u32 unreducedTileCompWindow)
Get band window in tile component coordinates for specified resolution and band orientation.
Definition: util.cpp:32
bool mult_will_overflow(uint64_t a, uint64_t b)
Definition: util.h:30
uint32_t grk_make_aligned_width(uint32_t width)
Definition: MemManager.cpp:40
T sat_sub(T lhs, T rhs)
Definition: util.h:75
uint32_t ceildiv(T a, T b)
Divide an integer by another integer and round upwards.
Definition: grk_intmath.h:32
void GRK_ERROR(const char *fmt,...)
Definition: logger.cpp:57
const size_t default_align
Definition: MemManager.h:28
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:119
T sat_add(int64_t lhs, int64_t rhs)
Definition: util.h:67
grk_rectangle< uint32_t > grk_rect_u32
Definition: util.h:56
void grk_aligned_free(void *ptr)
Definition: MemManager.cpp:123
T ceildivpow2(T a, uint32_t b)
Definition: grk_intmath.h:37
Definition: util.h:311
bool copy_data(T *dest, uint32_t dest_w, uint32_t dest_h, uint32_t dest_stride) const
Definition: util.h:401
grk_buffer_2d & operator=(const grk_buffer_2d &rhs)
Definition: util.h:330
bool alloc(bool clear)
Definition: util.h:354
void attach(T *buffer, uint32_t strd)
Definition: util.h:375
void copy_rect(grk_rect_u32 b)
Definition: util.h:348
bool owns_data
Definition: util.h:436
T * data
Definition: util.h:435
void copy(grk_buffer_2d &rhs, F filter)
Definition: util.h:420
grk_buffer_2d(T *buffer, bool ownsData, uint32_t w, uint32_t strd, uint32_t h)
Definition: util.h:313
void transfer(T **buffer, bool *owns, uint32_t *strd)
Definition: util.h:391
grk_buffer_2d(uint32_t w, uint32_t strd, uint32_t h)
Definition: util.h:318
virtual ~grk_buffer_2d()
Definition: util.h:344
uint32_t stride
Definition: util.h:437
grk_buffer_2d(grk_rect_u32 b)
Definition: util.h:322
grk_buffer_2d(uint32_t w, uint32_t h)
Definition: util.h:320
grk_buffer_2d(void)
Definition: util.h:327
grk_buffer_2d & operator=(const grk_buffer_2d *rhs)
Definition: util.h:334
void acquire(T *buffer, uint32_t strd)
Definition: util.h:383
Definition: util.h:234
virtual ~grk_buffer()
Definition: util.h:247
void alloc(size_t length)
Definition: util.h:251
bool owns_data
Definition: util.h:307
size_t offset
Definition: util.h:305
virtual void dealloc()
Definition: util.h:259
size_t len
Definition: util.h:306
T * buf
Definition: util.h:304
grk_buffer(T *buffer, size_t length, bool ownsData)
Definition: util.h:244
size_t get_remaining_length(void)
Definition: util.h:268
grk_buffer(T *buffer, size_t off, size_t length, bool ownsData)
Definition: util.h:235
void incr_offset(ptrdiff_t off)
Definition: util.h:272
grk_buffer()
Definition: util.h:241
T * curr_ptr()
Definition: util.h:298
Definition: util.h:42
T x0
Definition: util.h:45
grk_line(T _x0, T _x1)
Definition: util.h:44
grk_line()
Definition: util.h:43
T x1
Definition: util.h:46
T length()
Definition: util.h:47
Definition: util.h:34
T x
Definition: util.h:37
grk_point()
Definition: util.h:35
grk_point(T _x, T _y)
Definition: util.h:36
T y
Definition: util.h:38
Definition: util.h:83
grk_line< T > dimY()
Definition: util.h:192
grk_rectangle< T > & grow(T boundaryx, T boundaryy)
Definition: util.h:209
grk_rectangle< T > rect_union(const grk_rectangle< T > &rhs) const
Definition: util.h:177
void print(void) const
Definition: util.h:95
T x0
Definition: util.h:84
grk_rectangle< T > rect_union(const grk_rectangle< T > *rhs) const
Definition: util.h:171
grk_rectangle< T > & grow(T boundaryx, T boundaryy, T maxX, T maxY)
Definition: util.h:215
void set_rect(grk_rectangle< T > rhs)
Definition: util.h:130
T y1
Definition: util.h:84
bool contains(grk_point< T > pt)
Definition: util.h:105
bool isContainedIn(const grk_rectangle< T > rhs) const
Definition: util.h:154
grk_rectangle(void)
Definition: util.h:92
grk_rectangle< T > & operator=(const grk_rectangle< T > &rhs)
Definition: util.h:108
grk_rectangle< T > & grow(T boundary, T maxX, T maxY)
Definition: util.h:212
grk_rectangle< T > pan(int64_t x, int64_t y) const
Definition: util.h:195
grk_rectangle< T > & grow(T boundary, grk_rectangle< T > bounds)
Definition: util.h:218
bool non_empty(void) const
Definition: util.h:102
grk_rectangle< T > & grow(T boundaryx, T boundaryy, grk_rectangle< T > bounds)
Definition: util.h:221
T y0
Definition: util.h:84
bool operator==(const grk_rectangle< T > &rhs) const
Definition: util.h:119
bool is_valid(void) const
Definition: util.h:99
uint64_t area(void) const
Definition: util.h:180
grk_rectangle< T > rectceildivpow2(uint32_t power) const
Definition: util.h:133
grk_rectangle< T > intersection(const grk_rectangle< T > rhs) const
Definition: util.h:151
grk_rectangle(const grk_rectangle &rhs)
Definition: util.h:89
T height() const
Definition: util.h:186
grk_rectangle< T > rectceildiv(uint32_t den) const
Definition: util.h:139
grk_rectangle< T > rectceildiv(uint32_t denx, uint32_t deny) const
Definition: util.h:145
T width() const
Definition: util.h:183
grk_line< T > dimX()
Definition: util.h:189
grk_rectangle< T > & grow(T boundary)
Definition: util.h:206
grk_rectangle< T > intersection(const grk_rectangle< T > *rhs) const
Definition: util.h:164
T x1
Definition: util.h:84
void clip(const grk_rectangle< T > *rhs)
Definition: util.h:157
void set_rect(grk_rectangle< T > *rhs)
Definition: util.h:126
grk_rectangle(T x0, T y0, T x1, T y1)
Definition: util.h:86
void pan_inplace(int64_t x, int64_t y)
Definition: util.h:200