Grok  7.6.0
util.h
Go to the documentation of this file.
1 
19 #pragma once
20 
21 #include <thread>
22 #include <climits>
23 #include <stdint.h>
24 #include "grok_intmath.h"
25 
26 namespace grk {
27 
28 inline bool mult_will_overflow(uint32_t a, uint32_t b) {
29  return (b && (a > UINT_MAX / b));
30 }
31 inline bool mult64_will_overflow(uint64_t a, uint64_t b) {
32  return (b && (a > UINT64_MAX / b));
33 }
34 
35 template<typename T> struct grk_point {
36  grk_point() : x(0), y(0){}
37  grk_point(T _x, T _y) : x(_x), y(_y){}
38  T x;
39  T y;
40 };
42 
43 
44 template<typename T> struct grk_rectangle;
47 
48 template<typename T> struct grk_rectangle {
49  T x0;
50  T y0;
51  T x1;
52  T y1;
53 
54  grk_rectangle(T x0, T y0, T x1, T y1) :
55  x0(x0), y0(y0), x1(x1), y1(y1) {
56  }
57 
59  *this = rhs;
60  }
61 
63  return grk_rect_u32((uint32_t)x0,(uint32_t)y0,(uint32_t)x1,(uint32_t)y1);
64  }
65 
66 
67  void print(void) {
68  std::cout << "[" << x0 << "," << y0 << "," << x1 << "," << y1 << "]"
69  << std::endl;
70  }
71 
72  grk_rectangle(void) :
73  x0(0), y0(0), x1(0), y1(0) {
74  }
75 
76  bool is_valid(void) {
77  return x0 <= x1 && y0 <= y1;
78  }
79 
80  bool is_non_degenerate(void) {
81  return x0 < x1 && y0 < y1;
82  }
83 
84  bool clip(grk_rectangle<T> &r2, grk_rectangle<T> *result) {
85  bool rc;
86  grk_rectangle<T> temp;
87 
88  if (!result)
89  return false;
90 
91  temp.x0 = std::max<T>(x0, r2.x0);
92  temp.y0 = std::max<T>(y0, r2.y0);
93 
94  temp.x1 = std::min<T>(x1, r2.x1);
95  temp.y1 = std::min<T>(y1, r2.y1);
96 
97  rc = temp.is_valid();
98 
99  if (rc)
100  *result = temp;
101  return rc;
102  }
103 
105  {
106  if (this != &rhs) { // self-assignment check expected
107  x0 = rhs.x0;
108  y0 = rhs.y0;
109  x1 = rhs.x1;
110  y1 = rhs.y1;
111  }
112 
113  return *this;
114  }
115 
116 
118  {
119  x0 -= rhs.x0;
120  y0 -= rhs.y0;
121  x1 -= rhs.x1;
122  y1 -= rhs.y1;
123 
124  return *this;
125  }
127  {
128  x0 -= rhs.x0;
129  y0 -= rhs.y0;
130  x1 -= rhs.x1;
131  y1 -= rhs.y1;
132 
133  return *this;
134  }
135 
137  x0 = ceildivpow2(x0, power);
138  y0 = ceildivpow2(y0, power);
139  x1 = ceildivpow2(x1, power);
140  y1 = ceildivpow2(y1, power);
141 
142  return *this;
143 
144  }
145 
146  grk_rectangle<T>& mulpow2(uint32_t power) {
147  x0 *= 1 << power;
148  y0 *= 1 << power;
149  x1 *= 1 << power;
150  y1 *= 1 << power;
151 
152  return *this;
153 
154  }
155 
157  return grk_rectangle<T>( std::max<T>(x0,rhs.x0),
158  std::max<T>(y0,rhs.y0),
159  std::min<T>(x1,rhs.x1),
160  std::min<T>(y1,rhs.y1));
161  }
162 
163  uint64_t area(void) {
164  return (uint64_t)(x1 - x0) * (y1 - y0);
165  }
166 
167  T width(){
168  return x1 - x0;
169  }
170  T height(){
171  return y1 - y0;
172  }
173 
174 
175  grk_rectangle<T>& pan(T x, T y) {
176  x0 += x;
177  y0 += y;
178  x1 += x;
179  y1 += y;
180 
181  return *this;
182  }
183  grk_rectangle<T>& subsample(uint32_t dx, uint32_t dy) {
184  x0 = ceildiv(x0, (T) dx);
185  y0 = ceildiv(y0, (T) dy);
186  x1 = ceildiv(x1, (T) dx);
187  y1 = ceildiv(y1, (T) dy);
188  }
189 
190  grk_rectangle<T>& grow(T boundary) {
191  return grow(boundary, boundary);
192  }
193 
194  grk_rectangle<T>& grow(T boundaryx, T boundaryy) {
195 
196  x0 -= boundaryx;
197  y0 -= boundaryy;
198  x1 += boundaryx;
199  y1 += boundaryy;
200 
201  return *this;
202  }
203 
204 };
205 
206 using grk_rect = grk_rectangle<int64_t>;
207 using grk_rect_u32 = grk_rectangle<uint32_t>;
208 
209 template <typename T> struct grk_buffer {
210 
211  grk_buffer(T *buffer, size_t off, size_t length, bool ownsData) : buf(buffer),
212  offset(off),
213  len(length),
214  owns_data(ownsData)
215  {}
216 
217  grk_buffer(T *buffer, size_t length, bool ownsData) : grk_buffer(buffer,0,length,ownsData)
218  {}
219 
220  virtual ~grk_buffer() {
221  if (owns_data)
222  delete[] buf;
223  buf = nullptr;
224  owns_data = false;
225  offset = 0;
226  len = 0;
227  }
228 
229  void incr_offset(ptrdiff_t off) {
230  /* we allow the offset to move to one location beyond end of buffer segment*/
231  if (off > 0 ){
232  if (offset > (size_t)(SIZE_MAX - (size_t)off)){
233  GROK_WARN("grk_buf: overflow");
234  offset = len;
235  } else if (offset + (size_t)off > len){
236  #ifdef DEBUG_SEG_BUF
237  GROK_WARN("grk_buf: attempt to increment buffer offset out of bounds");
238  #endif
239  offset = len;
240  } else {
241  offset = offset + (size_t)off;
242  }
243  }
244  else if (off < 0){
245  if (offset < (size_t)(-off)) {
246  GROK_WARN("grk_buf: underflow");
247  offset = 0;
248  } else {
249  offset = (size_t)((ptrdiff_t)offset + off);
250  }
251  }
252 
253  }
254 
255  T* curr_ptr(){
256  if (!buf)
257  return nullptr;
258  return buf + offset;
259  }
260 
261 
262  T *buf; /* internal array*/
263  size_t offset; /* current offset into array */
264  size_t len; /* length of array */
265  bool owns_data; /* true if buffer manages the buf array */
266 } ;
268 
269 
270 template <typename T> struct grk_buffer_2d : public grk_rect_u32 {
271 
272  grk_buffer_2d(T *buffer,bool ownsData, uint32_t w, uint32_t strd, uint32_t h) : grk_rect_u32(0,0,w,h),
273  data(buffer),
274  owns_data(ownsData),
275  stride(strd)
276  {}
277  grk_buffer_2d(T *buffer,bool ownsData, uint32_t w, uint32_t h) : grk_buffer_2d(buffer,ownsData,w,w,h)
278  {}
279  grk_buffer_2d(uint32_t w, uint32_t strd, uint32_t h) : grk_buffer_2d(nullptr,false,w,strd,h)
280  {}
281  grk_buffer_2d(uint32_t w, uint32_t h) : grk_buffer_2d(w,w,h)
282  {}
284  {}
285  grk_buffer_2d(void) : grk_buffer_2d(nullptr,0,0,0,false)
286  {}
287  virtual ~grk_buffer_2d() {
288  if (owns_data)
290  }
291 
292  bool alloc(bool clear){
293  if (!data) {
295  uint64_t data_size_needed = stride * height() * sizeof(T);
296  if (!data_size_needed)
297  return true;
298  data = (T*) grk_aligned_malloc(data_size_needed);
299  if (!data)
300  return false;
301  if (clear)
302  memset(data, 0, data_size_needed);
303  owns_data = true;
304  }
305 
306  return true;
307  }
308 
309  // set data to buf without owning it
310  void attach(T* buffer, uint32_t strd){
311  if (owns_data)
313  data = buffer;
314  owns_data = false;
315  stride = strd;
316  }
317  // set data to buf and own it
318  void acquire(T* buffer, uint32_t strd){
319  if (owns_data)
321  buffer = data;
322  owns_data = true;
323  stride = strd;
324  }
325  // transfer data to buf, and cease owning it
326  void transfer(T** buffer, bool* owns, uint32_t *strd){
327  if (buffer && owns){
328  *buffer = data;
329  data = nullptr;
330  *owns = owns_data;
331  owns_data = false;
332  *strd = stride;
333  }
334  }
335 
336  T *data; /* internal array*/
337  bool owns_data; /* true if buffer manages the buf array */
338  uint32_t stride;
339 } ;
340 
341 }
342 
grk::grk_rectangle::subsample
grk_rectangle< T > & subsample(uint32_t dx, uint32_t dy)
Definition: util.h:183
grk::grk_buffer::grk_buffer
grk_buffer(T *buffer, size_t length, bool ownsData)
Definition: util.h:217
grk::grk_point
Definition: util.h:35
grk::grk_rectangle::to_u32
grk_rect_u32 to_u32()
Definition: util.h:62
grk::grk_buffer_2d::transfer
void transfer(T **buffer, bool *owns, uint32_t *strd)
Definition: util.h:326
grk::grk_rectangle::rectceildivpow2
grk_rectangle< T > & rectceildivpow2(uint32_t power)
Definition: util.h:136
grk::grk_buffer_2d::~grk_buffer_2d
virtual ~grk_buffer_2d()
Definition: util.h:287
grk::grk_buffer
Definition: util.h:209
grk::grk_aligned_free
void grk_aligned_free(void *ptr)
grk::grk_buffer::grk_buffer
grk_buffer(T *buffer, size_t off, size_t length, bool ownsData)
Definition: util.h:211
grk::grk_rectangle
Definition: util.h:44
grk::mult_will_overflow
bool mult_will_overflow(uint32_t a, uint32_t b)
Definition: util.h:28
grk::grk_buffer::~grk_buffer
virtual ~grk_buffer()
Definition: util.h:220
grk::grk_rectangle::pan
grk_rectangle< T > & pan(T x, T y)
Definition: util.h:175
grk::grk_buffer::offset
size_t offset
Definition: util.h:263
grk::grk_buffer_2d::owns_data
bool owns_data
Definition: util.h:337
grk::grk_rectangle::operator-=
grk_rectangle< T > & operator-=(const grk_rectangle< T > &rhs)
Definition: util.h:126
grk::grk_buffer_2d::acquire
void acquire(T *buffer, uint32_t strd)
Definition: util.h:318
grk::grk_rectangle::is_non_degenerate
bool is_non_degenerate(void)
Definition: util.h:80
grk::grk_rectangle::grk_rectangle
grk_rectangle(T x0, T y0, T x1, T y1)
Definition: util.h:54
grk::grk_rectangle::grow
grk_rectangle< T > & grow(T boundaryx, T boundaryy)
Definition: util.h:194
grk::grk_rect
grk_rectangle< int64_t > grk_rect
Definition: util.h:45
grk::grk_buffer_2d::grk_buffer_2d
grk_buffer_2d(uint32_t w, uint32_t h)
Definition: util.h:281
grk::grk_buffer_2d::attach
void attach(T *buffer, uint32_t strd)
Definition: util.h:310
grk::grk_rectangle::clip
bool clip(grk_rectangle< T > &r2, grk_rectangle< T > *result)
Definition: util.h:84
grk::grk_buffer_2d::alloc
bool alloc(bool clear)
Definition: util.h:292
grk::ceildivpow2
T ceildivpow2(T a, uint32_t b)
Definition: grok_intmath.h:57
grk::grk_rectangle::x1
T x1
Definition: util.h:51
grk::grk_rectangle::intersection
grk_rectangle< T > intersection(const grk_rectangle< T > &rhs)
Definition: util.h:156
grk::ceildiv
uint32_t ceildiv(T a, T b)
Divide an integer by another integer and round upwards.
Definition: grok_intmath.h:52
grk::grk_buffer::owns_data
bool owns_data
Definition: util.h:265
grk::grk_buffer_2d::grk_buffer_2d
grk_buffer_2d(T *buffer, bool ownsData, uint32_t w, uint32_t h)
Definition: util.h:277
grk::grk_rectangle::grk_rectangle
grk_rectangle(const grk_rectangle &rhs)
Definition: util.h:58
grk::grk_buffer::curr_ptr
T * curr_ptr()
Definition: util.h:255
grk::grk_make_aligned_width
uint32_t grk_make_aligned_width(uint32_t width)
grk::grk_rectangle::area
uint64_t area(void)
Definition: util.h:163
grk::grk_point::grk_point
grk_point(T _x, T _y)
Definition: util.h:37
grk::grk_point::x
T x
Definition: util.h:38
grk::grk_rectangle::grow
grk_rectangle< T > & grow(T boundary)
Definition: util.h:190
grk::grk_buffer::buf
T * buf
Definition: util.h:262
grk::grk_rectangle::print
void print(void)
Definition: util.h:67
grk::GROK_WARN
void GROK_WARN(const char *fmt,...)
grk::grk_buffer_2d::grk_buffer_2d
grk_buffer_2d(void)
Definition: util.h:285
grk::grk_point::grk_point
grk_point()
Definition: util.h:36
grk::grk_buffer_2d::stride
uint32_t stride
Definition: util.h:338
grk::grk_rectangle::height
T height()
Definition: util.h:170
grk::grk_rectangle::operator-
grk_rectangle< T > & operator-(const grk_rectangle< T > &rhs)
Definition: util.h:117
grk::grk_buffer_2d
Definition: util.h:270
grk
Copyright (C) 2016-2020 Grok Image Compression Inc.
Definition: BitIO.h:27
grk::grk_point::y
T y
Definition: util.h:39
grok_intmath.h
grk::grk_buffer::len
size_t len
Definition: util.h:264
grk::grk_rect_u32
grk_rectangle< uint32_t > grk_rect_u32
Definition: util.h:46
grk::grk_rectangle::mulpow2
grk_rectangle< T > & mulpow2(uint32_t power)
Definition: util.h:146
grk::grk_buffer::incr_offset
void incr_offset(ptrdiff_t off)
Definition: util.h:229
grk::grk_rectangle::width
T width()
Definition: util.h:167
grk::grk_buffer_2d::grk_buffer_2d
grk_buffer_2d(uint32_t w, uint32_t strd, uint32_t h)
Definition: util.h:279
grk::grk_aligned_malloc
void * grk_aligned_malloc(size_t size)
Allocate memory aligned to a 16 byte boundary.
grk::grk_buffer_2d::data
T * data
Definition: util.h:336
grk::grk_rectangle::operator=
grk_rectangle< T > & operator=(const grk_rectangle< T > &rhs)
Definition: util.h:104
grk::grk_rectangle::x0
T x0
Definition: util.h:49
grk::grk_rectangle::y1
T y1
Definition: util.h:52
grk::mult64_will_overflow
bool mult64_will_overflow(uint64_t a, uint64_t b)
Definition: util.h:31
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:272
grk::grk_buffer_2d::grk_buffer_2d
grk_buffer_2d(grk_rect_u32 b)
Definition: util.h:283
grk::grk_rectangle::y0
T y0
Definition: util.h:50
grk::grk_rectangle::is_valid
bool is_valid(void)
Definition: util.h:76
grk::grk_rectangle::grk_rectangle
grk_rectangle(void)
Definition: util.h:72