/src/dng_sdk/source/dng_rect.h
Line | Count | Source (jump to first uncovered line) |
1 | | /*****************************************************************************/ |
2 | | // Copyright 2006-2007 Adobe Systems Incorporated |
3 | | // All Rights Reserved. |
4 | | // |
5 | | // NOTICE: Adobe permits you to use, modify, and distribute this file in |
6 | | // accordance with the terms of the Adobe license agreement accompanying it. |
7 | | /*****************************************************************************/ |
8 | | |
9 | | /* $Id: //mondo/dng_sdk_1_4/dng_sdk/source/dng_rect.h#2 $ */ |
10 | | /* $DateTime: 2012/06/01 07:28:57 $ */ |
11 | | /* $Change: 832715 $ */ |
12 | | /* $Author: tknoll $ */ |
13 | | |
14 | | /*****************************************************************************/ |
15 | | |
16 | | #ifndef __dng_rect__ |
17 | | #define __dng_rect__ |
18 | | |
19 | | /*****************************************************************************/ |
20 | | |
21 | | #include "dng_exceptions.h" |
22 | | #include "dng_point.h" |
23 | | #include "dng_safe_arithmetic.h" |
24 | | #include "dng_types.h" |
25 | | #include "dng_utils.h" |
26 | | |
27 | | /*****************************************************************************/ |
28 | | |
29 | | class dng_rect |
30 | | { |
31 | | |
32 | | public: |
33 | | |
34 | | int32 t; |
35 | | int32 l; |
36 | | int32 b; |
37 | | int32 r; |
38 | | |
39 | | public: |
40 | | |
41 | | dng_rect () |
42 | 60.4M | : t (0) |
43 | 60.4M | , l (0) |
44 | 60.4M | , b (0) |
45 | 60.4M | , r (0) |
46 | 60.4M | { |
47 | 60.4M | } |
48 | | |
49 | | // Constructs a dng_rect from the top-left and bottom-right corner. |
50 | | // Throws an exception if the resulting height or width are too large to |
51 | | // be represented as an int32. The intent of this is to protect code |
52 | | // that may be computing the height or width directly from the member |
53 | | // variables (instead of going through H() or W()). |
54 | | dng_rect (int32 tt, int32 ll, int32 bb, int32 rr) |
55 | 4.83M | : t (tt) |
56 | 4.83M | , l (ll) |
57 | 4.83M | , b (bb) |
58 | 4.83M | , r (rr) |
59 | 4.83M | { |
60 | 4.83M | int32 dummy; |
61 | 4.83M | if (!SafeInt32Sub(r, l, &dummy) || |
62 | 4.83M | !SafeInt32Sub(b, t, &dummy)) |
63 | 0 | { |
64 | 0 | ThrowProgramError ("Overflow in dng_rect constructor"); |
65 | 0 | } |
66 | 4.83M | } |
67 | | |
68 | | dng_rect (uint32 h, uint32 w) |
69 | | : t (0) |
70 | | , l (0) |
71 | 0 | { |
72 | 0 | if (!ConvertUint32ToInt32(h, &b) || |
73 | 0 | !ConvertUint32ToInt32(w, &r)) |
74 | 0 | { |
75 | 0 | ThrowProgramError ("Overflow in dng_rect constructor"); |
76 | 0 | } |
77 | 0 | } |
78 | | |
79 | | dng_rect (const dng_point &size) |
80 | 51.4k | : t (0) |
81 | 51.4k | , l (0) |
82 | 51.4k | , b (size.v) |
83 | 51.4k | , r (size.h) |
84 | 51.4k | { |
85 | 51.4k | } |
86 | | |
87 | | void Clear () |
88 | 0 | { |
89 | 0 | *this = dng_rect (); |
90 | 0 | } |
91 | | |
92 | | bool operator== (const dng_rect &rect) const; |
93 | | |
94 | | bool operator!= (const dng_rect &rect) const |
95 | 2.37M | { |
96 | 2.37M | return !(*this == rect); |
97 | 2.37M | } |
98 | | |
99 | | bool IsZero () const; |
100 | | |
101 | | bool NotZero () const |
102 | 0 | { |
103 | 0 | return !IsZero (); |
104 | 0 | } |
105 | | |
106 | | bool IsEmpty () const |
107 | 48.4M | { |
108 | 48.4M | return (t >= b) || (l >= r); |
109 | 48.4M | } |
110 | | |
111 | | bool NotEmpty () const |
112 | 15.5M | { |
113 | 15.5M | return !IsEmpty (); |
114 | 15.5M | } |
115 | | |
116 | | // Returns the width of the rectangle, or 0 if r is smaller than l. |
117 | | // Throws an exception if the width is too large to be represented as |
118 | | // a _signed_ int32 (even if it would fit in a uint32). This is |
119 | | // consciously conservative -- there are existing uses of W() where |
120 | | // the result is converted to an int32 without an overflow check, and |
121 | | // we want to make sure no overflow can occur in such cases. We provide |
122 | | // this check in addition to the check performed in the "two-corners" |
123 | | // constructor to protect client code that produes a dng_rect with |
124 | | // excessive size by initializing or modifying the member variables |
125 | | // directly. |
126 | | uint32 W () const |
127 | 34.7M | { |
128 | 34.7M | if (r >= l) |
129 | 34.7M | { |
130 | 34.7M | int32 width; |
131 | 34.7M | if (!SafeInt32Sub(r, l, &width)) |
132 | 67 | { |
133 | 67 | ThrowProgramError ("Overflow computing rectangle width"); |
134 | 67 | } |
135 | 34.7M | return static_cast<uint32>(width); |
136 | 34.7M | } |
137 | 6.83k | else |
138 | 6.83k | { |
139 | 6.83k | return 0; |
140 | 6.83k | } |
141 | 34.7M | } |
142 | | |
143 | | // Returns the height of the rectangle, or 0 if b is smaller than t. |
144 | | // Throws an exception if the height is too large to be represented as |
145 | | // a _signed_ int32 (see W() for rationale). |
146 | | uint32 H () const |
147 | 21.5M | { |
148 | 21.5M | if (b >= t) |
149 | 21.5M | { |
150 | 21.5M | int32 height; |
151 | 21.5M | if (!SafeInt32Sub(b, t, &height)) |
152 | 50 | { |
153 | 50 | ThrowProgramError ("Overflow computing rectangle height"); |
154 | 50 | } |
155 | 21.5M | return static_cast<uint32>(height); |
156 | 21.5M | } |
157 | 11.6k | else |
158 | 11.6k | { |
159 | 11.6k | return 0; |
160 | 11.6k | } |
161 | 21.5M | } |
162 | | |
163 | | dng_point TL () const |
164 | 187k | { |
165 | 187k | return dng_point (t, l); |
166 | 187k | } |
167 | | |
168 | | dng_point TR () const |
169 | 0 | { |
170 | 0 | return dng_point (t, r); |
171 | 0 | } |
172 | | |
173 | | dng_point BL () const |
174 | 0 | { |
175 | 0 | return dng_point (b, l); |
176 | 0 | } |
177 | | |
178 | | dng_point BR () const |
179 | 0 | { |
180 | 0 | return dng_point (b, r); |
181 | 0 | } |
182 | | |
183 | | dng_point Size () const |
184 | 3.28M | { |
185 | 3.28M | return dng_point ((int32) H (), (int32) W ()); |
186 | 3.28M | } |
187 | | |
188 | | real64 Diagonal () const |
189 | 0 | { |
190 | 0 | return hypot ((real64) W (), |
191 | 0 | (real64) H ()); |
192 | 0 | } |
193 | | |
194 | | }; |
195 | | |
196 | | /*****************************************************************************/ |
197 | | |
198 | | class dng_rect_real64 |
199 | | { |
200 | | |
201 | | public: |
202 | | |
203 | | real64 t; |
204 | | real64 l; |
205 | | real64 b; |
206 | | real64 r; |
207 | | |
208 | | public: |
209 | | |
210 | | dng_rect_real64 () |
211 | 0 | : t (0.0) |
212 | 0 | , l (0.0) |
213 | 0 | , b (0.0) |
214 | 0 | , r (0.0) |
215 | 0 | { |
216 | 0 | } |
217 | | |
218 | | dng_rect_real64 (real64 tt, real64 ll, real64 bb, real64 rr) |
219 | | : t (tt) |
220 | | , l (ll) |
221 | | , b (bb) |
222 | | , r (rr) |
223 | 0 | { |
224 | 0 | } |
225 | | |
226 | | dng_rect_real64 (real64 h, real64 w) |
227 | | : t (0) |
228 | | , l (0) |
229 | | , b (h) |
230 | | , r (w) |
231 | 0 | { |
232 | 0 | } |
233 | | |
234 | | dng_rect_real64 (const dng_point_real64 &size) |
235 | | : t (0) |
236 | | , l (0) |
237 | | , b (size.v) |
238 | | , r (size.h) |
239 | 0 | { |
240 | 0 | } |
241 | | |
242 | | dng_rect_real64 (const dng_point_real64 &pt1, |
243 | | const dng_point_real64 &pt2) |
244 | | : t (Min_real64 (pt1.v, pt2.v)) |
245 | | , l (Min_real64 (pt1.h, pt2.h)) |
246 | | , b (Max_real64 (pt1.v, pt2.v)) |
247 | | , r (Max_real64 (pt1.h, pt2.h)) |
248 | 0 | { |
249 | 0 | } |
250 | | |
251 | | dng_rect_real64 (const dng_rect &rect) |
252 | 0 | : t ((real64) rect.t) |
253 | 0 | , l ((real64) rect.l) |
254 | 0 | , b ((real64) rect.b) |
255 | 0 | , r ((real64) rect.r) |
256 | 0 | { |
257 | 0 | } |
258 | | |
259 | | void Clear () |
260 | 0 | { |
261 | 0 | *this = dng_point_real64 (); |
262 | 0 | } |
263 | | |
264 | | bool operator== (const dng_rect_real64 &rect) const; |
265 | | |
266 | | bool operator!= (const dng_rect_real64 &rect) const |
267 | 0 | { |
268 | 0 | return !(*this == rect); |
269 | 0 | } |
270 | | |
271 | | bool IsZero () const; |
272 | | |
273 | | bool NotZero () const |
274 | 0 | { |
275 | 0 | return !IsZero (); |
276 | 0 | } |
277 | | |
278 | | bool IsEmpty () const |
279 | 0 | { |
280 | 0 | return (t >= b) || (l >= r); |
281 | 0 | } |
282 | | |
283 | | bool NotEmpty () const |
284 | 0 | { |
285 | 0 | return !IsEmpty (); |
286 | 0 | } |
287 | | |
288 | | real64 W () const |
289 | 0 | { |
290 | 0 | return Max_real64 (r - l, 0.0); |
291 | 0 | } |
292 | | |
293 | | real64 H () const |
294 | 0 | { |
295 | 0 | return Max_real64 (b - t, 0.0); |
296 | 0 | } |
297 | | |
298 | | dng_point_real64 TL () const |
299 | 0 | { |
300 | 0 | return dng_point_real64 (t, l); |
301 | 0 | } |
302 | | |
303 | | dng_point_real64 TR () const |
304 | 0 | { |
305 | 0 | return dng_point_real64 (t, r); |
306 | 0 | } |
307 | | |
308 | | dng_point_real64 BL () const |
309 | 0 | { |
310 | 0 | return dng_point_real64 (b, l); |
311 | 0 | } |
312 | | |
313 | | dng_point_real64 BR () const |
314 | 0 | { |
315 | 0 | return dng_point_real64 (b, r); |
316 | 0 | } |
317 | | |
318 | | dng_point_real64 Size () const |
319 | 0 | { |
320 | 0 | return dng_point_real64 (H (), W ()); |
321 | 0 | } |
322 | | |
323 | | dng_rect Round () const |
324 | 0 | { |
325 | 0 | return dng_rect (Round_int32 (t), |
326 | 0 | Round_int32 (l), |
327 | 0 | Round_int32 (b), |
328 | 0 | Round_int32 (r)); |
329 | 0 | } |
330 | | |
331 | | real64 Diagonal () const |
332 | 0 | { |
333 | 0 | return hypot (W (), H ()); |
334 | 0 | } |
335 | | |
336 | | }; |
337 | | |
338 | | /*****************************************************************************/ |
339 | | |
340 | | dng_rect operator& (const dng_rect &a, |
341 | | const dng_rect &b); |
342 | | |
343 | | dng_rect operator| (const dng_rect &a, |
344 | | const dng_rect &b); |
345 | | |
346 | | /*****************************************************************************/ |
347 | | |
348 | | dng_rect_real64 operator& (const dng_rect_real64 &a, |
349 | | const dng_rect_real64 &b); |
350 | | |
351 | | dng_rect_real64 operator| (const dng_rect_real64 &a, |
352 | | const dng_rect_real64 &b); |
353 | | |
354 | | /*****************************************************************************/ |
355 | | |
356 | | inline dng_rect operator+ (const dng_rect &a, |
357 | | const dng_point &b) |
358 | 923k | { |
359 | | |
360 | 923k | return dng_rect (a.t + b.v, |
361 | 923k | a.l + b.h, |
362 | 923k | a.b + b.v, |
363 | 923k | a.r + b.h); |
364 | | |
365 | 923k | } |
366 | | |
367 | | /*****************************************************************************/ |
368 | | |
369 | | inline dng_rect_real64 operator+ (const dng_rect_real64 &a, |
370 | | const dng_point_real64 &b) |
371 | 0 | { |
372 | 0 | |
373 | 0 | return dng_rect_real64 (a.t + b.v, |
374 | 0 | a.l + b.h, |
375 | 0 | a.b + b.v, |
376 | 0 | a.r + b.h); |
377 | 0 | |
378 | 0 | } |
379 | | |
380 | | /*****************************************************************************/ |
381 | | |
382 | | inline dng_rect operator- (const dng_rect &a, |
383 | | const dng_point &b) |
384 | 123k | { |
385 | | |
386 | 123k | return dng_rect (a.t - b.v, |
387 | 123k | a.l - b.h, |
388 | 123k | a.b - b.v, |
389 | 123k | a.r - b.h); |
390 | | |
391 | 123k | } |
392 | | |
393 | | /*****************************************************************************/ |
394 | | |
395 | | inline dng_rect_real64 operator- (const dng_rect_real64 &a, |
396 | | const dng_point_real64 &b) |
397 | 0 | { |
398 | 0 | |
399 | 0 | return dng_rect_real64 (a.t - b.v, |
400 | 0 | a.l - b.h, |
401 | 0 | a.b - b.v, |
402 | 0 | a.r - b.h); |
403 | 0 | |
404 | 0 | } |
405 | | |
406 | | /*****************************************************************************/ |
407 | | |
408 | | inline dng_rect Transpose (const dng_rect &a) |
409 | 0 | { |
410 | | |
411 | 0 | return dng_rect (a.l, a.t, a.r, a.b); |
412 | | |
413 | 0 | } |
414 | | |
415 | | /*****************************************************************************/ |
416 | | |
417 | | inline dng_rect_real64 Transpose (const dng_rect_real64 &a) |
418 | 0 | { |
419 | 0 | |
420 | 0 | return dng_rect_real64 (a.l, a.t, a.r, a.b); |
421 | 0 | |
422 | 0 | } |
423 | | |
424 | | /*****************************************************************************/ |
425 | | |
426 | | inline void HalfRect (dng_rect &rect) |
427 | 0 | { |
428 | 0 |
|
429 | 0 | rect.r = rect.l + (int32) (rect.W () >> 1); |
430 | 0 | rect.b = rect.t + (int32) (rect.H () >> 1); |
431 | 0 |
|
432 | 0 | } |
433 | | |
434 | | /*****************************************************************************/ |
435 | | |
436 | | inline void DoubleRect (dng_rect &rect) |
437 | 0 | { |
438 | 0 |
|
439 | 0 | rect.r = rect.l + (int32) (rect.W () << 1); |
440 | 0 | rect.b = rect.t + (int32) (rect.H () << 1); |
441 | 0 |
|
442 | 0 | } |
443 | | |
444 | | /*****************************************************************************/ |
445 | | |
446 | | inline void InnerPadRect (dng_rect &rect, |
447 | | int32 pad) |
448 | 0 | { |
449 | 0 |
|
450 | 0 | rect.l += pad; |
451 | 0 | rect.r -= pad; |
452 | 0 | rect.t += pad; |
453 | 0 | rect.b -= pad; |
454 | 0 |
|
455 | 0 | } |
456 | | |
457 | | /*****************************************************************************/ |
458 | | |
459 | | inline void OuterPadRect (dng_rect &rect, |
460 | | int32 pad) |
461 | 0 | { |
462 | 0 |
|
463 | 0 | InnerPadRect (rect, -pad); |
464 | 0 |
|
465 | 0 | } |
466 | | |
467 | | /*****************************************************************************/ |
468 | | |
469 | | inline void InnerPadRectH (dng_rect &rect, |
470 | | int32 pad) |
471 | 0 | { |
472 | 0 |
|
473 | 0 | rect.l += pad; |
474 | 0 | rect.r -= pad; |
475 | 0 |
|
476 | 0 | } |
477 | | |
478 | | /*****************************************************************************/ |
479 | | |
480 | | inline void InnerPadRectV (dng_rect &rect, |
481 | | int32 pad) |
482 | 0 | { |
483 | 0 |
|
484 | 0 | rect.t += pad; |
485 | 0 | rect.b -= pad; |
486 | 0 |
|
487 | 0 | } |
488 | | |
489 | | /*****************************************************************************/ |
490 | | |
491 | | inline dng_rect MakeHalfRect (const dng_rect &rect) |
492 | 0 | { |
493 | 0 | |
494 | 0 | dng_rect out = rect; |
495 | 0 |
|
496 | 0 | HalfRect (out); |
497 | 0 |
|
498 | 0 | return out; |
499 | 0 | |
500 | 0 | } |
501 | | |
502 | | /*****************************************************************************/ |
503 | | |
504 | | inline dng_rect MakeDoubleRect (const dng_rect &rect) |
505 | 0 | { |
506 | 0 | |
507 | 0 | dng_rect out = rect; |
508 | 0 |
|
509 | 0 | DoubleRect (out); |
510 | 0 |
|
511 | 0 | return out; |
512 | 0 | |
513 | 0 | } |
514 | | |
515 | | /*****************************************************************************/ |
516 | | |
517 | | inline dng_rect MakeInnerPadRect (const dng_rect &rect, |
518 | | int32 pad) |
519 | 0 | { |
520 | 0 | |
521 | 0 | dng_rect out = rect; |
522 | 0 |
|
523 | 0 | InnerPadRect (out, pad); |
524 | 0 |
|
525 | 0 | return out; |
526 | 0 | |
527 | 0 | } |
528 | | |
529 | | /*****************************************************************************/ |
530 | | |
531 | | inline dng_rect MakeOuterPadRect (const dng_rect &rect, |
532 | | int32 pad) |
533 | 0 | { |
534 | 0 | |
535 | 0 | dng_rect out = rect; |
536 | 0 |
|
537 | 0 | OuterPadRect (out, pad); |
538 | 0 |
|
539 | 0 | return out; |
540 | 0 | |
541 | 0 | } |
542 | | |
543 | | /*****************************************************************************/ |
544 | | |
545 | | #endif |
546 | | |
547 | | /*****************************************************************************/ |