Grok 15.1.0
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
30namespace grk
31{
32template<typename T>
33struct 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
43template<typename T>
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
59template<typename T>
60struct grk_rect;
65
66template<typename T>
67T clip(int64_t val)
68{
69 static_assert(sizeof(T) <= 4);
70 if(val < (std::numeric_limits<T>::min)())
71 val = (std::numeric_limits<T>::min)();
72 else if(val > (std::numeric_limits<T>::max)())
73 val = (std::numeric_limits<T>::max)();
74 return (T)val;
75}
76
77template<typename T>
78T satAdd(int64_t lhs, int64_t rhs)
79{
80 return clip<T>(lhs + rhs);
81}
82
83template<typename T>
84T satAdd(T lhs, T rhs)
85{
86 return clip<T>((int64_t)lhs + rhs);
87}
88
89template<typename T>
90T satSub(T lhs, T rhs)
91{
92 return clip<T>((int64_t)lhs - rhs);
93}
94
95template<typename T>
96T satSub(int64_t lhs, int64_t rhs)
97{
98 return clip<T>(lhs - rhs);
99}
100
101template<typename T>
103{
106 x1(x1), y1(y1)
107 {}
108 grk_rect(T x0, T y0, T x1, T y1) : grk_rect(x0, y0, x0, y0, x1, y1) {}
109 grk_rect(const grk_rect& rhs) : grk_rect(&rhs) {}
110 grk_rect(const grk_rect* rhs)
111 {
112 origin_x0 = rhs->origin_x0;
113 origin_y0 = rhs->origin_y0;
114 x0 = rhs->x0;
115 y0 = rhs->y0;
116 x1 = rhs->x1;
117 y1 = rhs->y1;
119 }
120 grk_rect(void) : grk_rect(0, 0, 0, 0) {}
121 virtual ~grk_rect() = default;
122
125 T x0, y0, x1, y1;
126
127 grk_rect<T>& setOrigin(T origx, T origy, bool absolute)
128 {
129 absoluteCoordinates = absolute;
130
131 assert(x0 >= origx);
132 assert(y0 >= origy);
133
134 origin_x0 = origx;
135 origin_y0 = origy;
136
137 return *this;
138 }
139 grk_rect<T>& setOrigin(grk_rect<T>& rhs, bool absolute)
140 {
141 return setOrigin(&rhs, absolute);
142 }
143 grk_rect<T>& setOrigin(grk_rect<T>* rhs, bool absolute)
144 {
145 absoluteCoordinates = absolute;
146
147 if(rhs)
148 {
149 assert(x0 >= rhs->origin_x0);
150 assert(y0 >= rhs->origin_y0);
151 origin_x0 = rhs->origin_x0;
152 origin_y0 = rhs->origin_y0;
153 }
154
155 return *this;
156 }
158 {
159 assert(x0 >= origin_x0);
160 assert(y0 >= origin_y0);
162 pan_IN_PLACE(-(int64_t)origin_x0, -(int64_t)origin_y0);
163 absoluteCoordinates = false;
164
165 return *this;
166 }
168 {
171 absoluteCoordinates = true;
172
173 return *this;
174 }
175 virtual void print(void) const
176 {
177 grklog.info("[%u,%u,%u,%u,%u,%u]", origin_x0, origin_y0, x0, y0, x1, y1);
178 }
179 std::string boundsString() const
180 {
181 std::ostringstream os;
182 os << "[" << origin_x0 << "," << origin_y0 << "," << x0 << "," << y0 << "," << x1 << "," << y1
183 << "]";
184 return os.str();
185 }
186 bool valid(void) const
187 {
188 return x0 <= x1 && y0 <= y1;
189 }
190 bool empty(void) const
191 {
192 return x0 >= x1 || y0 >= y1;
193 }
195 {
196 return contains(pt.x, pt.y);
197 }
198 bool contains(T x, T y)
199 {
200 return x >= x0 && y >= y0 && x < x1 && y < y1;
201 }
203 {
204 return operator=(&rhs);
205 }
207 {
208 assert(rhs);
209 if(rhs && (this != rhs))
210 { // self-assignment check expected
212 origin_x0 = rhs->origin_x0;
213 origin_y0 = rhs->origin_y0;
214 x0 = rhs->x0;
215 y0 = rhs->y0;
216 x1 = rhs->x1;
217 y1 = rhs->y1;
218 }
219 return *this;
220 }
221 bool operator==(const grk_rect<T>& rhs) const
222 {
223 if(this == &rhs)
224 return true;
226 origin_y0 == rhs.origin_y0 && x0 == rhs.x0 && y0 == rhs.y0 && x1 == rhs.x1 &&
227 y1 == rhs.y1;
228 }
230 {
231 *this = *rhs;
232 }
234 {
235 setRect(&rhs);
236 }
237 grk_rect<T> scaleDownCeil(uint32_t den) const
238 {
239 return grk_rect<T>(ceildiv(origin_x0, den), ceildiv(origin_y0, den), ceildiv(x0, den),
240 ceildiv(y0, den), ceildiv(x1, den), ceildiv(y1, den));
241 }
242 grk_rect<T> scale(uint32_t scalex, uint32_t scaley) const
243 {
244 return grk_rect<T>(origin_x0 * scalex, origin_y0 * scaley, x0 * scalex, y0 * scaley,
245 x1 * scalex, y1 * scaley);
246 }
247 grk_rect<T> scaleDown(uint64_t denx, uint64_t deny) const
248 {
249 return grk_rect<T>((T)(origin_x0 / denx), (T)(origin_y0 / deny), (T)(x0 / denx), (T)(y0 / deny),
250 (T)ceildiv<uint64_t>(x1, denx), (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 {
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 {
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), std::min<T>(x1, rhs->x1),
295 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), std::min<T>(x1, rhs.x1),
305 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), std::min<T>(x1, rhs->x1),
313 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), std::max<T>(x1, rhs->x1),
325 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 }
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
409using grk_rect32 = grk_rect<uint32_t>;
410using grk_rect16 = grk_rect<uint16_t>;
411
412} // namespace grk
Copyright (C) 2016-2025 Grok Image Compression Inc.
Definition ICacheable.h:20
T satAdd(int64_t lhs, int64_t rhs)
Definition geometry.h:78
T clip(int64_t val)
Definition geometry.h:67
grk_rect< float > grk_rect_single
Definition geometry.h:63
grk_line< uint32_t > grk_line32
Definition geometry.h:57
grk_pt< uint16_t > grk_pt16
Definition geometry.h:41
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:90
grk_rect< uint32_t > grk_rect32
Definition geometry.h:61
grk_pt< uint32_t > grk_pt32
Definition geometry.h:40
grk_rect< uint16_t > grk_rect16
Definition geometry.h:62
grk_rect< double > grk_rect_double
Definition geometry.h:64
Logger & grklog
Definition Logger.cpp:20
T ceildivpow2(T a, uint32_t b)
Definition grk_intmath.h:40
Definition geometry.h:45
uint32_t x0
Definition geometry.h:48
grk_line(T _x0, T _x1)
Definition geometry.h:47
grk_line()
Definition geometry.h:46
uint32_t x1
Definition geometry.h:49
T length() const
Definition geometry.h:51
Definition geometry.h:34
uint32_t x
Definition geometry.h:37
uint32_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:103
uint64_t area(void) const
Definition geometry.h:331
T width() const
Definition geometry.h:335
grk_rect< T > & pan_IN_PLACE(int64_t x, int64_t y)
Definition geometry.h:358
bool absoluteCoordinates
Definition geometry.h:123
grk_rect< T > pan(int64_t x, int64_t y) const
Definition geometry.h:352
void setRect(grk_rect< T > rhs)
Definition geometry.h:233
uint32_t y1
Definition geometry.h:125
grk_rect< T > & setOrigin(T origx, T origy, bool absolute)
Definition geometry.h:127
uint32_t x0
Definition geometry.h:125
grk_rect< T > intersection(const grk_rect< T > rhs) const
Definition geometry.h:281
bool operator==(const grk_rect< T > &rhs) const
Definition geometry.h:221
grk_rect< T > & grow_IN_PLACE(T boundaryx, T boundaryy)
Definition geometry.h:373
grk_rect< T > & toRelative(void)
Definition geometry.h:157
grk_rect< T > & grow_IN_PLACE(T boundaryx, T boundaryy, grk_rect< T > bounds)
Definition geometry.h:390
uint32_t x1
Definition geometry.h:125
grk_rect< T > clip(const grk_rect< T > *rhs) const
Definition geometry.h:291
grk_rect< T > scaleDownCeil(uint64_t denx, uint64_t deny) const
Definition geometry.h:262
uint32_t origin_y0
Definition geometry.h:124
T height() const
Definition geometry.h:339
bool valid(void) const
Definition geometry.h:186
T parityY(void) const
Definition geometry.h:403
grk_rect< T > & toAbsolute(void)
Definition geometry.h:167
grk_rect< T > & operator=(const grk_rect< T > &rhs)
Definition geometry.h:202
grk_rect< T > & grow_IN_PLACE(T boundary, grk_rect< T > bounds)
Definition geometry.h:386
grk_line< T > dimX() const
Definition geometry.h:343
grk_rect< T > & clip_IN_PLACE(const grk_rect< T > &rhs)
Definition geometry.h:301
bool nonEmptyIntersection(const grk_rect< T > *rhs) const
Definition geometry.h:315
T parityX(void) const
Definition geometry.h:399
virtual ~grk_rect()=default
grk_rect< T > & setOrigin(grk_rect< T > *rhs, bool absolute)
Definition geometry.h:143
grk_rect< T > rectUnion(const grk_rect< T > &rhs) const
Definition geometry.h:327
grk_rect< T > scale(uint32_t scalex, uint32_t scaley) const
Definition geometry.h:242
grk_rect< T > scaleDownCeilPow2(uint32_t power) const
Definition geometry.h:268
grk_rect< T > & grow_IN_PLACE(T boundary, T maxX, T maxY)
Definition geometry.h:378
bool contains(grk_pt< T > pt)
Definition geometry.h:194
grk_rect< T > & grow_IN_PLACE(T boundary)
Definition geometry.h:368
bool empty(void) const
Definition geometry.h:190
grk_rect< T > & operator=(const grk_rect< T > *rhs)
Definition geometry.h:206
grk_rect(T x0, T y0, T x1, T y1)
Definition geometry.h:108
grk_rect(const grk_rect *rhs)
Definition geometry.h:110
grk_rect< T > scaleDownPow2(grk_pt< T > pow) const
Definition geometry.h:258
uint32_t origin_x0
Definition geometry.h:124
virtual void print(void) const
Definition geometry.h:175
grk_line< T > dimY() const
Definition geometry.h:347
grk_rect< T > clip(const grk_rect< T > &rhs) const
Definition geometry.h:297
grk_rect< T > scaleDown(uint64_t denx, uint64_t deny) const
Definition geometry.h:247
void setRect(grk_rect< T > *rhs)
Definition geometry.h:229
grk_rect(void)
Definition geometry.h:120
grk_rect< T > rectUnion(const grk_rect< T > *rhs) const
Definition geometry.h:321
grk_rect< T > scaleDownCeil(uint32_t den) const
Definition geometry.h:237
bool contains(T x, T y)
Definition geometry.h:198
bool isContainedIn(const grk_rect< T > rhs) const
Definition geometry.h:287
grk_rect(const grk_rect &rhs)
Definition geometry.h:109
grk_rect< T > scaleDownCeilPow2(uint32_t powx, uint32_t powy) const
Definition geometry.h:274
grk_rect(T origin_x0, T origin_y0, T x0, T y0, T x1, T y1)
Definition geometry.h:104
std::string boundsString() const
Definition geometry.h:179
grk_rect< T > & grow_IN_PLACE(T boundaryx, T boundaryy, T maxX, T maxY)
Definition geometry.h:382
grk_rect< T > & setOrigin(grk_rect< T > &rhs, bool absolute)
Definition geometry.h:139
uint32_t y0
Definition geometry.h:125
grk_rect< T > intersection(const grk_rect< T > *rhs) const
Definition geometry.h:309
grk_rect< T > scaleDownPow2(uint32_t powx, uint32_t powy) const
Definition geometry.h:252