Home | History | Annotate | Download | only in source
      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 			:	t (0)
     43 			,	l (0)
     44 			,	b (0)
     45 			,	r (0)
     46 			{
     47 			}
     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 			:	t (tt)
     56 			,	l (ll)
     57 			,	b (bb)
     58 			,	r (rr)
     59 			{
     60 			int32 dummy;
     61 			if (!SafeInt32Sub(r, l, &dummy) ||
     62 				!SafeInt32Sub(b, t, &dummy))
     63 				{
     64 				ThrowProgramError ("Overflow in dng_rect constructor");
     65 				}
     66 			}
     67 
     68 		dng_rect (uint32 h, uint32 w)
     69 			:	t (0)
     70 			,	l (0)
     71 			{
     72 				if (!ConvertUint32ToInt32(h, &b) ||
     73 					!ConvertUint32ToInt32(w, &r))
     74 					{
     75 					ThrowProgramError ("Overflow in dng_rect constructor");
     76 					}
     77 			}
     78 
     79 		dng_rect (const dng_point &size)
     80 			:	t (0)
     81 			,	l (0)
     82 			,	b (size.v)
     83 			,	r (size.h)
     84 			{
     85 			}
     86 
     87 		void Clear ()
     88 			{
     89 			*this = dng_rect ();
     90 			}
     91 
     92 		bool operator== (const dng_rect &rect) const;
     93 
     94 		bool operator!= (const dng_rect &rect) const
     95 			{
     96 			return !(*this == rect);
     97 			}
     98 
     99 		bool IsZero () const;
    100 
    101 		bool NotZero () const
    102 			{
    103 			return !IsZero ();
    104 			}
    105 
    106 		bool IsEmpty () const
    107 			{
    108 			return (t >= b) || (l >= r);
    109 			}
    110 
    111 		bool NotEmpty () const
    112 			{
    113 			return !IsEmpty ();
    114 			}
    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 			{
    128 			if (r >= l)
    129 				{
    130 				int32 width;
    131 				if (!SafeInt32Sub(r, l, &width))
    132 					{
    133 					ThrowProgramError ("Overflow computing rectangle width");
    134 					}
    135 				return static_cast<uint32>(width);
    136 				}
    137 			else
    138 				{
    139 				return 0;
    140 				}
    141 			}
    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 			{
    148 			if (b >= t)
    149 				{
    150 				int32 height;
    151 				if (!SafeInt32Sub(b, t, &height))
    152 					{
    153 					ThrowProgramError ("Overflow computing rectangle height");
    154 					}
    155 				return static_cast<uint32>(height);
    156 				}
    157 			else
    158 				{
    159 				return 0;
    160 				}
    161 			}
    162 
    163 		dng_point TL () const
    164 			{
    165 			return dng_point (t, l);
    166 			}
    167 
    168 		dng_point TR () const
    169 			{
    170 			return dng_point (t, r);
    171 			}
    172 
    173 		dng_point BL () const
    174 			{
    175 			return dng_point (b, l);
    176 			}
    177 
    178 		dng_point BR () const
    179 			{
    180 			return dng_point (b, r);
    181 			}
    182 
    183 		dng_point Size () const
    184 			{
    185 			return dng_point ((int32) H (), (int32) W ());
    186 			}
    187 
    188 		real64 Diagonal () const
    189 			{
    190 			return hypot ((real64) W (),
    191 						  (real64) H ());
    192 			}
    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 			:	t (0.0)
    212 			,	l (0.0)
    213 			,	b (0.0)
    214 			,	r (0.0)
    215 			{
    216 			}
    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 			{
    224 			}
    225 
    226 		dng_rect_real64 (real64 h, real64 w)
    227 			:	t (0)
    228 			,	l (0)
    229 			,	b (h)
    230 			,	r (w)
    231 			{
    232 			}
    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 			{
    240 			}
    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 			{
    249 			}
    250 
    251 		dng_rect_real64 (const dng_rect &rect)
    252 			:	t ((real64) rect.t)
    253 			,	l ((real64) rect.l)
    254 			,	b ((real64) rect.b)
    255 			,	r ((real64) rect.r)
    256 			{
    257 			}
    258 
    259 		void Clear ()
    260 			{
    261 			*this = dng_point_real64 ();
    262 			}
    263 
    264 		bool operator== (const dng_rect_real64 &rect) const;
    265 
    266 		bool operator!= (const dng_rect_real64 &rect) const
    267 			{
    268 			return !(*this == rect);
    269 			}
    270 
    271 		bool IsZero () const;
    272 
    273 		bool NotZero () const
    274 			{
    275 			return !IsZero ();
    276 			}
    277 
    278 		bool IsEmpty () const
    279 			{
    280 			return (t >= b) || (l >= r);
    281 			}
    282 
    283 		bool NotEmpty () const
    284 			{
    285 			return !IsEmpty ();
    286 			}
    287 
    288 		real64 W () const
    289 			{
    290 			return Max_real64 (r - l, 0.0);
    291 			}
    292 
    293 		real64 H () const
    294 			{
    295 			return Max_real64 (b - t, 0.0);
    296 			}
    297 
    298 		dng_point_real64 TL () const
    299 			{
    300 			return dng_point_real64 (t, l);
    301 			}
    302 
    303 		dng_point_real64 TR () const
    304 			{
    305 			return dng_point_real64 (t, r);
    306 			}
    307 
    308 		dng_point_real64 BL () const
    309 			{
    310 			return dng_point_real64 (b, l);
    311 			}
    312 
    313 		dng_point_real64 BR () const
    314 			{
    315 			return dng_point_real64 (b, r);
    316 			}
    317 
    318 		dng_point_real64 Size () const
    319 			{
    320 			return dng_point_real64 (H (), W ());
    321 			}
    322 
    323 		dng_rect Round () const
    324 			{
    325 			return dng_rect (Round_int32 (t),
    326 							 Round_int32 (l),
    327 							 Round_int32 (b),
    328 							 Round_int32 (r));
    329 			}
    330 
    331 		real64 Diagonal () const
    332 			{
    333 			return hypot (W (), H ());
    334 			}
    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 	{
    359 
    360 	return dng_rect (a.t + b.v,
    361 					 a.l + b.h,
    362 					 a.b + b.v,
    363 					 a.r + b.h);
    364 
    365 	}
    366 
    367 /*****************************************************************************/
    368 
    369 inline dng_rect_real64 operator+ (const dng_rect_real64 &a,
    370 					       		  const dng_point_real64 &b)
    371 	{
    372 
    373 	return dng_rect_real64 (a.t + b.v,
    374 					 		a.l + b.h,
    375 					 		a.b + b.v,
    376 					 		a.r + b.h);
    377 
    378 	}
    379 
    380 /*****************************************************************************/
    381 
    382 inline dng_rect operator- (const dng_rect &a,
    383 					       const dng_point &b)
    384 	{
    385 
    386 	return dng_rect (a.t - b.v,
    387 					 a.l - b.h,
    388 					 a.b - b.v,
    389 					 a.r - b.h);
    390 
    391 	}
    392 
    393 /*****************************************************************************/
    394 
    395 inline dng_rect_real64 operator- (const dng_rect_real64 &a,
    396 					       		  const dng_point_real64 &b)
    397 	{
    398 
    399 	return dng_rect_real64 (a.t - b.v,
    400 					 		a.l - b.h,
    401 					 		a.b - b.v,
    402 					 		a.r - b.h);
    403 
    404 	}
    405 
    406 /*****************************************************************************/
    407 
    408 inline dng_rect Transpose (const dng_rect &a)
    409 	{
    410 
    411 	return dng_rect (a.l, a.t, a.r, a.b);
    412 
    413 	}
    414 
    415 /*****************************************************************************/
    416 
    417 inline dng_rect_real64 Transpose (const dng_rect_real64 &a)
    418 	{
    419 
    420 	return dng_rect_real64 (a.l, a.t, a.r, a.b);
    421 
    422 	}
    423 
    424 /*****************************************************************************/
    425 
    426 inline void HalfRect (dng_rect &rect)
    427 	{
    428 
    429 	rect.r = rect.l + (int32) (rect.W () >> 1);
    430 	rect.b = rect.t + (int32) (rect.H () >> 1);
    431 
    432 	}
    433 
    434 /*****************************************************************************/
    435 
    436 inline void DoubleRect (dng_rect &rect)
    437 	{
    438 
    439 	rect.r = rect.l + (int32) (rect.W () << 1);
    440 	rect.b = rect.t + (int32) (rect.H () << 1);
    441 
    442 	}
    443 
    444 /*****************************************************************************/
    445 
    446 inline void InnerPadRect (dng_rect &rect,
    447 						  int32 pad)
    448 	{
    449 
    450 	rect.l += pad;
    451 	rect.r -= pad;
    452 	rect.t += pad;
    453 	rect.b -= pad;
    454 
    455 	}
    456 
    457 /*****************************************************************************/
    458 
    459 inline void OuterPadRect (dng_rect &rect,
    460 						  int32 pad)
    461 	{
    462 
    463 	InnerPadRect (rect, -pad);
    464 
    465 	}
    466 
    467 /*****************************************************************************/
    468 
    469 inline void InnerPadRectH (dng_rect &rect,
    470 						   int32 pad)
    471 	{
    472 
    473 	rect.l += pad;
    474 	rect.r -= pad;
    475 
    476 	}
    477 
    478 /*****************************************************************************/
    479 
    480 inline void InnerPadRectV (dng_rect &rect,
    481 						   int32 pad)
    482 	{
    483 
    484 	rect.t += pad;
    485 	rect.b -= pad;
    486 
    487 	}
    488 
    489 /*****************************************************************************/
    490 
    491 inline dng_rect MakeHalfRect (const dng_rect &rect)
    492 	{
    493 
    494 	dng_rect out = rect;
    495 
    496 	HalfRect (out);
    497 
    498 	return out;
    499 
    500 	}
    501 
    502 /*****************************************************************************/
    503 
    504 inline dng_rect MakeDoubleRect (const dng_rect &rect)
    505 	{
    506 
    507 	dng_rect out = rect;
    508 
    509 	DoubleRect (out);
    510 
    511 	return out;
    512 
    513 	}
    514 
    515 /*****************************************************************************/
    516 
    517 inline dng_rect MakeInnerPadRect (const dng_rect &rect,
    518 								  int32 pad)
    519 	{
    520 
    521 	dng_rect out = rect;
    522 
    523 	InnerPadRect (out, pad);
    524 
    525 	return out;
    526 
    527 	}
    528 
    529 /*****************************************************************************/
    530 
    531 inline dng_rect MakeOuterPadRect (const dng_rect &rect,
    532 								  int32 pad)
    533 	{
    534 
    535 	dng_rect out = rect;
    536 
    537 	OuterPadRect (out, pad);
    538 
    539 	return out;
    540 
    541 	}
    542 
    543 /*****************************************************************************/
    544 
    545 #endif
    546 
    547 /*****************************************************************************/
    548