Grok  10.0.3
geometry.h
Go to the documentation of this file.
1 
17 #pragma once
18 
19 #include "grok.h"
20 
21 #include <iostream>
22 #include <cstdint>
23 #include <limits>
24 #include <sstream>
25 #include <atomic>
26 
27 #include "logger.h"
28 #include "grk_intmath.h"
29 
30 namespace grk
31 {
32 template<typename T>
33 struct grk_pt
34 {
35  grk_pt() : x(0), y(0) {}
36  grk_pt(T _x, T _y) : x(_x), y(_y) {}
37  T x;
38  T y;
39 };
42 
43 template<typename T>
44 struct grk_line
45 {
46  grk_line() : x0(0), x1(0) {}
47  grk_line(T _x0, T _x1) : x0(_x0), x1(_x1) {}
48  T x0;
49  T x1;
50 
51  T length() const
52  {
53  assert(x1 >= x0);
54  return (T)(x1 - x0);
55  }
56 };
58 
59 template<typename T>
60 struct grk_rect;
64 
65 template<typename T>
66 T clip(int64_t val)
67 {
68  static_assert(sizeof(T) <= 4);
69  if(val < (std::numeric_limits<T>::min)())
70  val = (std::numeric_limits<T>::min)();
71  else if(val > (std::numeric_limits<T>::max)())
72  val = (std::numeric_limits<T>::max)();
73  return (T)val;
74 }
75 
76 template<typename T>
77 T satAdd(int64_t lhs, int64_t rhs)
78 {
79  return clip<T>(lhs + rhs);
80 }
81 
82 template<typename T>
83 T satAdd(T lhs, T rhs)
84 {
85  return clip<T>((int64_t)lhs + rhs);
86 }
87 
88 template<typename T>
89 T satSub(T lhs, T rhs)
90 {
91  return clip<T>((int64_t)lhs - rhs);
92 }
93 
94 template<typename T>
95 T satSub(int64_t lhs, int64_t rhs)
96 {
97  return clip<T>(lhs - rhs);
98 }
99 
100 template<typename T>
101 struct grk_rect
102 {
103  grk_rect(T origin_x0, T origin_y0, T x0, T y0, T x1, T y1)
105  x1(x1), y1(y1)
106  {}
107  grk_rect(T x0, T y0, T x1, T y1) : grk_rect(x0, y0, x0, y0, x1, y1) {}
108  grk_rect(const grk_rect& rhs) : grk_rect(&rhs) {}
109  grk_rect(const grk_rect* rhs)
110  {
111  origin_x0 = rhs->origin_x0;
112  origin_y0 = rhs->origin_y0;
113  x0 = rhs->x0;
114  y0 = rhs->y0;
115  x1 = rhs->x1;
116  y1 = rhs->y1;
118  }
119  grk_rect(void) : grk_rect(0, 0, 0, 0) {}
120  virtual ~grk_rect() = default;
121 
124  T x0, y0, x1, y1;
125 
126  grk_rect<T>& setOrigin(T origx, T origy, bool absolute)
127  {
128  absoluteCoordinates = absolute;
129 
130  assert(x0 >= origx);
131  assert(y0 >= origy);
132 
133  origin_x0 = origx;
134  origin_y0 = origy;
135 
136  return *this;
137  }
138  grk_rect<T>& setOrigin(grk_rect<T>& rhs, bool absolute)
139  {
140  return setOrigin(&rhs, absolute);
141  }
142  grk_rect<T>& setOrigin(grk_rect<T>* rhs, bool absolute)
143  {
144  absoluteCoordinates = absolute;
145 
146  if(rhs)
147  {
148  assert(x0 >= rhs->origin_x0);
149  assert(y0 >= rhs->origin_y0);
150  origin_x0 = rhs->origin_x0;
151  origin_y0 = rhs->origin_y0;
152  }
153 
154  return *this;
155  }
157  {
158  assert(x0 >= origin_x0);
159  assert(y0 >= origin_y0);
161  pan_IN_PLACE(-(int64_t)origin_x0, -(int64_t)origin_y0);
162  absoluteCoordinates = false;
163 
164  return *this;
165  }
167  {
170  absoluteCoordinates = true;
171 
172  return *this;
173  }
174  virtual void print(void) const
175  {
176  GRK_INFO("[%u,%u,%u,%u,%u,%u]", origin_x0, origin_y0, x0, y0, x1, y1);
177  }
178  std::string boundsString() const
179  {
180  std::ostringstream os;
181  os << "[" << origin_x0 << "," << origin_y0 << "," << x0 << "," << y0 << "," << x1 << ","
182  << y1 << "]";
183  return os.str();
184  }
185  bool valid(void) const
186  {
187  return x0 <= x1 && y0 <= y1;
188  }
189  bool empty(void) const
190  {
191  return x0 >= x1 || y0 >= y1;
192  }
194  {
195  return contains(pt.x, pt.y);
196  }
197  bool contains(T x, T y)
198  {
199  return x >= x0 && y >= y0 && x < x1 && y < y1;
200  }
202  {
203  return operator=(&rhs);
204  }
206  {
207  assert(rhs);
208  if(rhs && (this != rhs))
209  { // self-assignment check expected
211  origin_x0 = rhs->origin_x0;
212  origin_y0 = rhs->origin_y0;
213  x0 = rhs->x0;
214  y0 = rhs->y0;
215  x1 = rhs->x1;
216  y1 = rhs->y1;
217  }
218  return *this;
219  }
220  bool operator==(const grk_rect<T>& rhs) const
221  {
222  if(this == &rhs)
223  return true;
225  origin_y0 == rhs.origin_y0 && x0 == rhs.x0 && y0 == rhs.y0 && x1 == rhs.x1 &&
226  y1 == rhs.y1;
227  }
228  void setRect(grk_rect<T>* rhs)
229  {
230  *this = *rhs;
231  }
233  {
234  setRect(&rhs);
235  }
236  grk_rect<T> scaleDownCeil(uint32_t den) const
237  {
238  return grk_rect<T>(ceildiv(origin_x0, den), ceildiv(origin_y0, den), ceildiv(x0, den),
239  ceildiv(y0, den), ceildiv(x1, den), ceildiv(y1, den));
240  }
241  grk_rect<T> scale(uint32_t scalex, uint32_t scaley) const
242  {
243  return grk_rect<T>(origin_x0 * scalex, origin_y0 * scaley, x0 * scalex, y0 * scaley,
244  x1 * scalex, y1 * scaley);
245  }
246  grk_rect<T> scaleDown(uint64_t denx, uint64_t deny) const
247  {
248  return grk_rect<T>((T)(origin_x0 / denx), (T)(origin_y0 / deny), (T)(x0 / denx),
249  (T)(y0 / deny), (T)ceildiv<uint64_t>(x1, denx),
250  (T)ceildiv<uint64_t>(y1, deny));
251  }
252  grk_rect<T> scaleDownPow2(uint32_t powx, uint32_t powy) const
253  {
254  return grk_rect<T>((T)(origin_x0 >> powx), (T)(origin_y0 >> powy), (T)(x0 >> powx),
255  (T)(y0 >> powy), (T)ceildivpow2<uint64_t>(x1, powx),
256  (T)ceildivpow2<uint64_t>(y1, powy));
257  }
259  {
260  return scaleDownPow2(pow.x, pow.y);
261  }
262  grk_rect<T> scaleDownCeil(uint64_t denx, uint64_t deny) const
263  {
264  return grk_rect<T>(ceildiv<uint64_t>(origin_x0, denx), ceildiv<uint64_t>(origin_y0, deny),
265  ceildiv<uint64_t>(x0, denx), ceildiv<uint64_t>(y0, deny),
266  ceildiv<uint64_t>(x1, denx), ceildiv<uint64_t>(y1, deny));
267  }
268  grk_rect<T> scaleDownCeilPow2(uint32_t power) const
269  {
270  return grk_rect<T>(ceildivpow2(origin_x0, power), ceildivpow2(origin_y0, power),
271  ceildivpow2(x0, power), ceildivpow2(y0, power), ceildivpow2(x1, power),
272  ceildivpow2(y1, power));
273  }
274  grk_rect<T> scaleDownCeilPow2(uint32_t powx, uint32_t powy) const
275  {
276  return grk_rect<T>(ceildivpow2<uint64_t>(origin_x0, powx),
277  ceildivpow2<uint64_t>(origin_y0, powy), ceildivpow2<uint64_t>(x0, powx),
278  ceildivpow2<uint64_t>(y0, powy), ceildivpow2<uint64_t>(x1, powx),
279  ceildivpow2<uint64_t>(y1, powy));
280  }
282  {
284 
285  return intersection(&rhs);
286  }
287  bool isContainedIn(const grk_rect<T> rhs) const
288  {
289  return (intersection(&rhs) == *this);
290  }
291  grk_rect<T> clip(const grk_rect<T>* rhs) const
292  {
294  return grk_rect<T>(std::max<T>(x0, rhs->x0), std::max<T>(y0, rhs->y0),
295  std::min<T>(x1, rhs->x1), std::min<T>(y1, rhs->y1));
296  }
297  grk_rect<T> clip(const grk_rect<T>& rhs) const
298  {
299  return clip(&rhs);
300  }
302  {
304  *this = grk_rect<T>(std::max<T>(x0, rhs.x0), std::max<T>(y0, rhs.y0),
305  std::min<T>(x1, rhs.x1), std::min<T>(y1, rhs.y1));
306 
307  return *this;
308  }
310  {
312  return grk_rect<T>(std::max<T>(x0, rhs->x0), std::max<T>(y0, rhs->y0),
313  std::min<T>(x1, rhs->x1), std::min<T>(y1, rhs->y1));
314  }
315  bool nonEmptyIntersection(const grk_rect<T>* rhs) const
316  {
318  return std::max<T>(x0, rhs->x0) < std::min<T>(x1, rhs->x1) &&
319  std::max<T>(y0, rhs->y0) < std::min<T>(y1, rhs->y1);
320  }
322  {
324  return grk_rect<T>(std::min<T>(x0, rhs->x0), std::min<T>(y0, rhs->y0),
325  std::max<T>(x1, rhs->x1), std::max<T>(y1, rhs->y1));
326  }
328  {
329  return rectUnion(&rhs);
330  }
331  uint64_t area(void) const
332  {
333  return (uint64_t)(x1 - x0) * (y1 - y0);
334  }
335  T width() const
336  {
337  return x1 - x0;
338  }
339  T height() const
340  {
341  return y1 - y0;
342  }
344  {
345  return grk_line<T>(x0, x1);
346  }
348  {
349  return grk_line<T>(y0, y1);
350  }
351  // pan doesn't affect origin
352  grk_rect<T> pan(int64_t x, int64_t y) const
353  {
354  auto rc = (*this);
355 
356  return rc.pan_IN_PLACE(x, y);
357  }
358  grk_rect<T>& pan_IN_PLACE(int64_t x, int64_t y)
359  {
360  x0 = satAdd<T>((int64_t)x0, (int64_t)x);
361  y0 = satAdd<T>((int64_t)y0, (int64_t)y);
362  x1 = satAdd<T>((int64_t)x1, (int64_t)x);
363  y1 = satAdd<T>((int64_t)y1, (int64_t)y);
364 
365  return *this;
366  }
367  // grow doesn't affect origin
369  {
370  return grow_IN_PLACE(boundary, boundary, (std::numeric_limits<T>::max)(),
371  (std::numeric_limits<T>::max)());
372  }
373  grk_rect<T>& grow_IN_PLACE(T boundaryx, T boundaryy)
374  {
375  return grow_IN_PLACE(boundaryx, boundaryy, (std::numeric_limits<T>::max)(),
376  (std::numeric_limits<T>::max)());
377  }
378  grk_rect<T>& grow_IN_PLACE(T boundary, T maxX, T maxY)
379  {
380  return grow_IN_PLACE(boundary, boundary, maxX, maxY);
381  }
382  grk_rect<T>& grow_IN_PLACE(T boundaryx, T boundaryy, T maxX, T maxY)
383  {
384  return grow_IN_PLACE(boundaryx, boundaryy, grk_rect<T>((T)0, (T)0, maxX, maxY));
385  }
386  grk_rect<T>& grow_IN_PLACE(T boundary, grk_rect<T> bounds)
387  {
388  return grow_IN_PLACE(boundary, boundary, bounds);
389  }
390  grk_rect<T>& grow_IN_PLACE(T boundaryx, T boundaryy, grk_rect<T> bounds)
391  {
392  x0 = std::max<T>(satSub<T>(x0, boundaryx), bounds.x0);
393  y0 = std::max<T>(satSub<T>(y0, boundaryy), bounds.y0);
394  x1 = std::min<T>(satAdd<T>(x1, boundaryx), bounds.x1);
395  y1 = std::min<T>(satAdd<T>(y1, boundaryy), bounds.y1);
396 
397  return *this;
398  }
399  T parityX(void) const
400  {
401  return T(x0 & 1);
402  }
403  T parityY(void) const
404  {
405  return T(y0 & 1);
406  }
407 };
408 
409 using grk_rect32 = grk_rect<uint32_t>;
410 using grk_rect16 = grk_rect<uint16_t>;
411 
412 } // namespace grk
Copyright (C) 2016-2022 Grok Image Compression Inc.
Definition: ICacheable.h:20
grk_rect< uint16_t > grk_rect16
Definition: geometry.h:62
T satAdd(int64_t lhs, int64_t rhs)
Definition: geometry.h:77
T clip(int64_t val)
Definition: geometry.h:66
void GRK_INFO(const char *fmt,...)
Definition: logger.cpp:40
uint32_t ceildiv(T a, T b)
Divide an integer by another integer and round upwards.
Definition: grk_intmath.h:33
T satSub(T lhs, T rhs)
Definition: geometry.h:89
grk_rect< uint32_t > grk_rect32
Definition: geometry.h:61
T ceildivpow2(T a, uint32_t b)
Definition: grk_intmath.h:40
Definition: geometry.h:45
T x0
Definition: geometry.h:48
grk_line(T _x0, T _x1)
Definition: geometry.h:47
grk_line()
Definition: geometry.h:46
T x1
Definition: geometry.h:49
T length() const
Definition: geometry.h:51
Definition: geometry.h:34
T x
Definition: geometry.h:37
T y
Definition: geometry.h:38
grk_pt(T _x, T _y)
Definition: geometry.h:36
grk_pt()
Definition: geometry.h:35
Definition: geometry.h:102
uint64_t area(void) const
Definition: geometry.h:331
grk_rect< T > & grow_IN_PLACE(T boundaryx, T boundaryy)
Definition: geometry.h:373
T width() const
Definition: geometry.h:335
grk_rect< T > rectUnion(const grk_rect< T > &rhs) const
Definition: geometry.h:327
grk_rect< T > & setOrigin(grk_rect< T > &rhs, bool absolute)
Definition: geometry.h:138
bool absoluteCoordinates
Definition: geometry.h:122
void setRect(grk_rect< T > rhs)
Definition: geometry.h:232
T y1
Definition: geometry.h:124
grk_rect< T > scaleDownCeilPow2(uint32_t powx, uint32_t powy) const
Definition: geometry.h:274
grk_rect< T > & grow_IN_PLACE(T boundary)
Definition: geometry.h:368
T x0
Definition: geometry.h:124
bool operator==(const grk_rect< T > &rhs) const
Definition: geometry.h:220
T x1
Definition: geometry.h:124
grk_rect< T > scaleDownPow2(uint32_t powx, uint32_t powy) const
Definition: geometry.h:252
grk_rect< T > & clip_IN_PLACE(const grk_rect< T > &rhs)
Definition: geometry.h:301
grk_rect< T > & operator=(const grk_rect< T > &rhs)
Definition: geometry.h:201
grk_rect< T > & toRelative(void)
Definition: geometry.h:156
T origin_y0
Definition: geometry.h:123
T height() const
Definition: geometry.h:339
bool valid(void) const
Definition: geometry.h:185
T parityY(void) const
Definition: geometry.h:403
grk_rect< T > clip(const grk_rect< T > *rhs) const
Definition: geometry.h:291
grk_rect< T > scaleDownCeilPow2(uint32_t power) const
Definition: geometry.h:268
grk_rect< T > & pan_IN_PLACE(int64_t x, int64_t y)
Definition: geometry.h:358
grk_rect< T > scaleDown(uint64_t denx, uint64_t deny) const
Definition: geometry.h:246
grk_rect< T > & grow_IN_PLACE(T boundary, T maxX, T maxY)
Definition: geometry.h:378
grk_rect< T > pan(int64_t x, int64_t y) const
Definition: geometry.h:352
grk_rect< T > & grow_IN_PLACE(T boundaryx, T boundaryy, T maxX, T maxY)
Definition: geometry.h:382
grk_rect< T > scale(uint32_t scalex, uint32_t scaley) const
Definition: geometry.h:241
bool nonEmptyIntersection(const grk_rect< T > *rhs) const
Definition: geometry.h:315
grk_rect< T > clip(const grk_rect< T > &rhs) const
Definition: geometry.h:297
T parityX(void) const
Definition: geometry.h:399
grk_rect< T > scaleDownPow2(grk_pt< T > pow) const
Definition: geometry.h:258
virtual ~grk_rect()=default
grk_rect< T > & setOrigin(T origx, T origy, bool absolute)
Definition: geometry.h:126
grk_rect< T > scaleDownCeil(uint64_t denx, uint64_t deny) const
Definition: geometry.h:262
grk_rect< T > scaleDownCeil(uint32_t den) const
Definition: geometry.h:236
grk_rect< T > rectUnion(const grk_rect< T > *rhs) const
Definition: geometry.h:321
grk_rect< T > intersection(const grk_rect< T > rhs) const
Definition: geometry.h:281
bool contains(grk_pt< T > pt)
Definition: geometry.h:193
bool empty(void) const
Definition: geometry.h:189
grk_rect< T > & grow_IN_PLACE(T boundaryx, T boundaryy, grk_rect< T > bounds)
Definition: geometry.h:390
grk_rect< T > intersection(const grk_rect< T > *rhs) const
Definition: geometry.h:309
grk_rect(T x0, T y0, T x1, T y1)
Definition: geometry.h:107
grk_rect(const grk_rect *rhs)
Definition: geometry.h:109
T origin_x0
Definition: geometry.h:123
grk_line< T > dimY() const
Definition: geometry.h:347
virtual void print(void) const
Definition: geometry.h:174
grk_line< T > dimX() const
Definition: geometry.h:343
void setRect(grk_rect< T > *rhs)
Definition: geometry.h:228
grk_rect(void)
Definition: geometry.h:119
bool contains(T x, T y)
Definition: geometry.h:197
grk_rect< T > & setOrigin(grk_rect< T > *rhs, bool absolute)
Definition: geometry.h:142
bool isContainedIn(const grk_rect< T > rhs) const
Definition: geometry.h:287
grk_rect(const grk_rect &rhs)
Definition: geometry.h:108
grk_rect< T > & grow_IN_PLACE(T boundary, grk_rect< T > bounds)
Definition: geometry.h:386
grk_rect< T > & toAbsolute(void)
Definition: geometry.h:166
grk_rect(T origin_x0, T origin_y0, T x0, T y0, T x1, T y1)
Definition: geometry.h:103
std::string boundsString() const
Definition: geometry.h:178
grk_rect< T > & operator=(const grk_rect< T > *rhs)
Definition: geometry.h:205
T y0
Definition: geometry.h:124