Grok 14.0.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 Logger::logger_.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),
250 (T)(y0 / deny), (T)ceildiv<uint64_t>(x1, denx),
251 (T)ceildiv<uint64_t>(y1, deny));
252 }
253 grk_rect<T> scaleDownPow2(uint32_t powx, uint32_t powy) const
254 {
255 return grk_rect<T>((T)(origin_x0 >> powx), (T)(origin_y0 >> powy), (T)(x0 >> powx),
256 (T)(y0 >> powy), (T)ceildivpow2<uint64_t>(x1, powx),
257 (T)ceildivpow2<uint64_t>(y1, powy));
258 }
260 {
261 return scaleDownPow2(pow.x, pow.y);
262 }
263 grk_rect<T> scaleDownCeil(uint64_t denx, uint64_t deny) const
264 {
268 }
269 grk_rect<T> scaleDownCeilPow2(uint32_t power) const
270 {
271 return grk_rect<T>(ceildivpow2(origin_x0, power), ceildivpow2(origin_y0, power),
272 ceildivpow2(x0, power), ceildivpow2(y0, power), ceildivpow2(x1, power),
273 ceildivpow2(y1, power));
274 }
275 grk_rect<T> scaleDownCeilPow2(uint32_t powx, uint32_t powy) const
276 {
281 }
283 {
285
286 return intersection(&rhs);
287 }
288 bool isContainedIn(const grk_rect<T> rhs) const
289 {
290 return (intersection(&rhs) == *this);
291 }
292 grk_rect<T> clip(const grk_rect<T>* rhs) const
293 {
295 return grk_rect<T>(std::max<T>(x0, rhs->x0), std::max<T>(y0, rhs->y0),
296 std::min<T>(x1, rhs->x1), std::min<T>(y1, rhs->y1));
297 }
298 grk_rect<T> clip(const grk_rect<T>& rhs) const
299 {
300 return clip(&rhs);
301 }
303 {
305 *this = grk_rect<T>(std::max<T>(x0, rhs.x0), std::max<T>(y0, rhs.y0), std::min<T>(x1, rhs.x1),
306 std::min<T>(y1, rhs.y1));
307
308 return *this;
309 }
311 {
313 return grk_rect<T>(std::max<T>(x0, rhs->x0), std::max<T>(y0, rhs->y0),
314 std::min<T>(x1, rhs->x1), std::min<T>(y1, rhs->y1));
315 }
316 bool nonEmptyIntersection(const grk_rect<T>* rhs) const
317 {
319 return std::max<T>(x0, rhs->x0) < std::min<T>(x1, rhs->x1) &&
320 std::max<T>(y0, rhs->y0) < std::min<T>(y1, rhs->y1);
321 }
323 {
325 return grk_rect<T>(std::min<T>(x0, rhs->x0), std::min<T>(y0, rhs->y0),
326 std::max<T>(x1, rhs->x1), std::max<T>(y1, rhs->y1));
327 }
329 {
330 return rectUnion(&rhs);
331 }
332 uint64_t area(void) const
333 {
334 return (uint64_t)(x1 - x0) * (y1 - y0);
335 }
336 T width() const
337 {
338 return x1 - x0;
339 }
340 T height() const
341 {
342 return y1 - y0;
343 }
345 {
346 return grk_line<T>(x0, x1);
347 }
349 {
350 return grk_line<T>(y0, y1);
351 }
352 // pan doesn't affect origin
353 grk_rect<T> pan(int64_t x, int64_t y) const
354 {
355 auto rc = (*this);
356
357 return rc.pan_IN_PLACE(x, y);
358 }
359 grk_rect<T>& pan_IN_PLACE(int64_t x, int64_t y)
360 {
361 x0 = satAdd<T>((int64_t)x0, (int64_t)x);
362 y0 = satAdd<T>((int64_t)y0, (int64_t)y);
363 x1 = satAdd<T>((int64_t)x1, (int64_t)x);
364 y1 = satAdd<T>((int64_t)y1, (int64_t)y);
365
366 return *this;
367 }
368 // grow doesn't affect origin
370 {
371 return grow_IN_PLACE(boundary, boundary, (std::numeric_limits<T>::max)(),
372 (std::numeric_limits<T>::max)());
373 }
374 grk_rect<T>& grow_IN_PLACE(T boundaryx, T boundaryy)
375 {
376 return grow_IN_PLACE(boundaryx, boundaryy, (std::numeric_limits<T>::max)(),
377 (std::numeric_limits<T>::max)());
378 }
379 grk_rect<T>& grow_IN_PLACE(T boundary, T maxX, T maxY)
380 {
381 return grow_IN_PLACE(boundary, boundary, maxX, maxY);
382 }
383 grk_rect<T>& grow_IN_PLACE(T boundaryx, T boundaryy, T maxX, T maxY)
384 {
385 return grow_IN_PLACE(boundaryx, boundaryy, grk_rect<T>((T)0, (T)0, maxX, maxY));
386 }
388 {
389 return grow_IN_PLACE(boundary, boundary, bounds);
390 }
391 grk_rect<T>& grow_IN_PLACE(T boundaryx, T boundaryy, grk_rect<T> bounds)
392 {
393 x0 = std::max<T>(satSub<T>(x0, boundaryx), bounds.x0);
394 y0 = std::max<T>(satSub<T>(y0, boundaryy), bounds.y0);
395 x1 = std::min<T>(satAdd<T>(x1, boundaryx), bounds.x1);
396 y1 = std::min<T>(satAdd<T>(y1, boundaryy), bounds.y1);
397
398 return *this;
399 }
400 T parityX(void) const
401 {
402 return T(x0 & 1);
403 }
404 T parityY(void) const
405 {
406 return T(y0 & 1);
407 }
408};
409
410using grk_rect32 = grk_rect<uint32_t>;
411using grk_rect16 = grk_rect<uint16_t>;
412
413} // namespace grk
Copyright (C) 2016-2024 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
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_rect< uint16_t > grk_rect16
Definition geometry.h:62
T ceildivpow2(T a, uint32_t b)
Definition grk_intmath.h:40
void info(const char *fmt,...) override
Definition Logger.h:35
static Logger logger_
Definition Logger.h:70
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:103
uint64_t area(void) const
Definition geometry.h:332
T width() const
Definition geometry.h:336
grk_rect< T > & pan_IN_PLACE(int64_t x, int64_t y)
Definition geometry.h:359
bool absoluteCoordinates
Definition geometry.h:123
grk_rect< T > pan(int64_t x, int64_t y) const
Definition geometry.h:353
void setRect(grk_rect< T > rhs)
Definition geometry.h:233
T y1
Definition geometry.h:125
grk_rect< T > & setOrigin(T origx, T origy, bool absolute)
Definition geometry.h:127
T x0
Definition geometry.h:125
grk_rect< T > intersection(const grk_rect< T > rhs) const
Definition geometry.h:282
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:374
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:391
T x1
Definition geometry.h:125
grk_rect< T > clip(const grk_rect< T > *rhs) const
Definition geometry.h:292
grk_rect< T > scaleDownCeil(uint64_t denx, uint64_t deny) const
Definition geometry.h:263
T origin_y0
Definition geometry.h:124
T height() const
Definition geometry.h:340
bool valid(void) const
Definition geometry.h:186
T parityY(void) const
Definition geometry.h:404
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:387
grk_line< T > dimX() const
Definition geometry.h:344
grk_rect< T > & clip_IN_PLACE(const grk_rect< T > &rhs)
Definition geometry.h:302
bool nonEmptyIntersection(const grk_rect< T > *rhs) const
Definition geometry.h:316
T parityX(void) const
Definition geometry.h:400
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:328
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:269
grk_rect< T > & grow_IN_PLACE(T boundary, T maxX, T maxY)
Definition geometry.h:379
bool contains(grk_pt< T > pt)
Definition geometry.h:194
grk_rect< T > & grow_IN_PLACE(T boundary)
Definition geometry.h:369
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:259
T origin_x0
Definition geometry.h:124
virtual void print(void) const
Definition geometry.h:175
grk_line< T > dimY() const
Definition geometry.h:348
grk_rect< T > clip(const grk_rect< T > &rhs) const
Definition geometry.h:298
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:322
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:288
grk_rect(const grk_rect &rhs)
Definition geometry.h:109
grk_rect< T > scaleDownCeilPow2(uint32_t powx, uint32_t powy) const
Definition geometry.h:275
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:383
grk_rect< T > & setOrigin(grk_rect< T > &rhs, bool absolute)
Definition geometry.h:139
T y0
Definition geometry.h:125
grk_rect< T > intersection(const grk_rect< T > *rhs) const
Definition geometry.h:310
grk_rect< T > scaleDownPow2(uint32_t powx, uint32_t powy) const
Definition geometry.h:253