You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
548 lines
10 KiB
548 lines
10 KiB
/*****************************************************************************/
|
|
// Copyright 2006-2007 Adobe Systems Incorporated
|
|
// All Rights Reserved.
|
|
//
|
|
// NOTICE: Adobe permits you to use, modify, and distribute this file in
|
|
// accordance with the terms of the Adobe license agreement accompanying it.
|
|
/*****************************************************************************/
|
|
|
|
/* $Id: //mondo/dng_sdk_1_4/dng_sdk/source/dng_rect.h#2 $ */
|
|
/* $DateTime: 2012/06/01 07:28:57 $ */
|
|
/* $Change: 832715 $ */
|
|
/* $Author: tknoll $ */
|
|
|
|
/*****************************************************************************/
|
|
|
|
#ifndef __dng_rect__
|
|
#define __dng_rect__
|
|
|
|
/*****************************************************************************/
|
|
|
|
#include "dng_exceptions.h"
|
|
#include "dng_point.h"
|
|
#include "dng_safe_arithmetic.h"
|
|
#include "dng_types.h"
|
|
#include "dng_utils.h"
|
|
|
|
/*****************************************************************************/
|
|
|
|
class dng_rect
|
|
{
|
|
|
|
public:
|
|
|
|
int32 t;
|
|
int32 l;
|
|
int32 b;
|
|
int32 r;
|
|
|
|
public:
|
|
|
|
dng_rect ()
|
|
: t (0)
|
|
, l (0)
|
|
, b (0)
|
|
, r (0)
|
|
{
|
|
}
|
|
|
|
// Constructs a dng_rect from the top-left and bottom-right corner.
|
|
// Throws an exception if the resulting height or width are too large to
|
|
// be represented as an int32. The intent of this is to protect code
|
|
// that may be computing the height or width directly from the member
|
|
// variables (instead of going through H() or W()).
|
|
dng_rect (int32 tt, int32 ll, int32 bb, int32 rr)
|
|
: t (tt)
|
|
, l (ll)
|
|
, b (bb)
|
|
, r (rr)
|
|
{
|
|
int32 dummy;
|
|
if (!SafeInt32Sub(r, l, &dummy) ||
|
|
!SafeInt32Sub(b, t, &dummy))
|
|
{
|
|
ThrowProgramError ("Overflow in dng_rect constructor");
|
|
}
|
|
}
|
|
|
|
dng_rect (uint32 h, uint32 w)
|
|
: t (0)
|
|
, l (0)
|
|
{
|
|
if (!ConvertUint32ToInt32(h, &b) ||
|
|
!ConvertUint32ToInt32(w, &r))
|
|
{
|
|
ThrowProgramError ("Overflow in dng_rect constructor");
|
|
}
|
|
}
|
|
|
|
dng_rect (const dng_point &size)
|
|
: t (0)
|
|
, l (0)
|
|
, b (size.v)
|
|
, r (size.h)
|
|
{
|
|
}
|
|
|
|
void Clear ()
|
|
{
|
|
*this = dng_rect ();
|
|
}
|
|
|
|
bool operator== (const dng_rect &rect) const;
|
|
|
|
bool operator!= (const dng_rect &rect) const
|
|
{
|
|
return !(*this == rect);
|
|
}
|
|
|
|
bool IsZero () const;
|
|
|
|
bool NotZero () const
|
|
{
|
|
return !IsZero ();
|
|
}
|
|
|
|
bool IsEmpty () const
|
|
{
|
|
return (t >= b) || (l >= r);
|
|
}
|
|
|
|
bool NotEmpty () const
|
|
{
|
|
return !IsEmpty ();
|
|
}
|
|
|
|
// Returns the width of the rectangle, or 0 if r is smaller than l.
|
|
// Throws an exception if the width is too large to be represented as
|
|
// a _signed_ int32 (even if it would fit in a uint32). This is
|
|
// consciously conservative -- there are existing uses of W() where
|
|
// the result is converted to an int32 without an overflow check, and
|
|
// we want to make sure no overflow can occur in such cases. We provide
|
|
// this check in addition to the check performed in the "two-corners"
|
|
// constructor to protect client code that produes a dng_rect with
|
|
// excessive size by initializing or modifying the member variables
|
|
// directly.
|
|
uint32 W () const
|
|
{
|
|
if (r >= l)
|
|
{
|
|
int32 width;
|
|
if (!SafeInt32Sub(r, l, &width))
|
|
{
|
|
ThrowProgramError ("Overflow computing rectangle width");
|
|
}
|
|
return static_cast<uint32>(width);
|
|
}
|
|
else
|
|
{
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
// Returns the height of the rectangle, or 0 if b is smaller than t.
|
|
// Throws an exception if the height is too large to be represented as
|
|
// a _signed_ int32 (see W() for rationale).
|
|
uint32 H () const
|
|
{
|
|
if (b >= t)
|
|
{
|
|
int32 height;
|
|
if (!SafeInt32Sub(b, t, &height))
|
|
{
|
|
ThrowProgramError ("Overflow computing rectangle height");
|
|
}
|
|
return static_cast<uint32>(height);
|
|
}
|
|
else
|
|
{
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
dng_point TL () const
|
|
{
|
|
return dng_point (t, l);
|
|
}
|
|
|
|
dng_point TR () const
|
|
{
|
|
return dng_point (t, r);
|
|
}
|
|
|
|
dng_point BL () const
|
|
{
|
|
return dng_point (b, l);
|
|
}
|
|
|
|
dng_point BR () const
|
|
{
|
|
return dng_point (b, r);
|
|
}
|
|
|
|
dng_point Size () const
|
|
{
|
|
return dng_point ((int32) H (), (int32) W ());
|
|
}
|
|
|
|
real64 Diagonal () const
|
|
{
|
|
return hypot ((real64) W (),
|
|
(real64) H ());
|
|
}
|
|
|
|
};
|
|
|
|
/*****************************************************************************/
|
|
|
|
class dng_rect_real64
|
|
{
|
|
|
|
public:
|
|
|
|
real64 t;
|
|
real64 l;
|
|
real64 b;
|
|
real64 r;
|
|
|
|
public:
|
|
|
|
dng_rect_real64 ()
|
|
: t (0.0)
|
|
, l (0.0)
|
|
, b (0.0)
|
|
, r (0.0)
|
|
{
|
|
}
|
|
|
|
dng_rect_real64 (real64 tt, real64 ll, real64 bb, real64 rr)
|
|
: t (tt)
|
|
, l (ll)
|
|
, b (bb)
|
|
, r (rr)
|
|
{
|
|
}
|
|
|
|
dng_rect_real64 (real64 h, real64 w)
|
|
: t (0)
|
|
, l (0)
|
|
, b (h)
|
|
, r (w)
|
|
{
|
|
}
|
|
|
|
dng_rect_real64 (const dng_point_real64 &size)
|
|
: t (0)
|
|
, l (0)
|
|
, b (size.v)
|
|
, r (size.h)
|
|
{
|
|
}
|
|
|
|
dng_rect_real64 (const dng_point_real64 &pt1,
|
|
const dng_point_real64 &pt2)
|
|
: t (Min_real64 (pt1.v, pt2.v))
|
|
, l (Min_real64 (pt1.h, pt2.h))
|
|
, b (Max_real64 (pt1.v, pt2.v))
|
|
, r (Max_real64 (pt1.h, pt2.h))
|
|
{
|
|
}
|
|
|
|
dng_rect_real64 (const dng_rect &rect)
|
|
: t ((real64) rect.t)
|
|
, l ((real64) rect.l)
|
|
, b ((real64) rect.b)
|
|
, r ((real64) rect.r)
|
|
{
|
|
}
|
|
|
|
void Clear ()
|
|
{
|
|
*this = dng_point_real64 ();
|
|
}
|
|
|
|
bool operator== (const dng_rect_real64 &rect) const;
|
|
|
|
bool operator!= (const dng_rect_real64 &rect) const
|
|
{
|
|
return !(*this == rect);
|
|
}
|
|
|
|
bool IsZero () const;
|
|
|
|
bool NotZero () const
|
|
{
|
|
return !IsZero ();
|
|
}
|
|
|
|
bool IsEmpty () const
|
|
{
|
|
return (t >= b) || (l >= r);
|
|
}
|
|
|
|
bool NotEmpty () const
|
|
{
|
|
return !IsEmpty ();
|
|
}
|
|
|
|
real64 W () const
|
|
{
|
|
return Max_real64 (r - l, 0.0);
|
|
}
|
|
|
|
real64 H () const
|
|
{
|
|
return Max_real64 (b - t, 0.0);
|
|
}
|
|
|
|
dng_point_real64 TL () const
|
|
{
|
|
return dng_point_real64 (t, l);
|
|
}
|
|
|
|
dng_point_real64 TR () const
|
|
{
|
|
return dng_point_real64 (t, r);
|
|
}
|
|
|
|
dng_point_real64 BL () const
|
|
{
|
|
return dng_point_real64 (b, l);
|
|
}
|
|
|
|
dng_point_real64 BR () const
|
|
{
|
|
return dng_point_real64 (b, r);
|
|
}
|
|
|
|
dng_point_real64 Size () const
|
|
{
|
|
return dng_point_real64 (H (), W ());
|
|
}
|
|
|
|
dng_rect Round () const
|
|
{
|
|
return dng_rect (Round_int32 (t),
|
|
Round_int32 (l),
|
|
Round_int32 (b),
|
|
Round_int32 (r));
|
|
}
|
|
|
|
real64 Diagonal () const
|
|
{
|
|
return hypot (W (), H ());
|
|
}
|
|
|
|
};
|
|
|
|
/*****************************************************************************/
|
|
|
|
dng_rect operator& (const dng_rect &a,
|
|
const dng_rect &b);
|
|
|
|
dng_rect operator| (const dng_rect &a,
|
|
const dng_rect &b);
|
|
|
|
/*****************************************************************************/
|
|
|
|
dng_rect_real64 operator& (const dng_rect_real64 &a,
|
|
const dng_rect_real64 &b);
|
|
|
|
dng_rect_real64 operator| (const dng_rect_real64 &a,
|
|
const dng_rect_real64 &b);
|
|
|
|
/*****************************************************************************/
|
|
|
|
inline dng_rect operator+ (const dng_rect &a,
|
|
const dng_point &b)
|
|
{
|
|
|
|
return dng_rect (a.t + b.v,
|
|
a.l + b.h,
|
|
a.b + b.v,
|
|
a.r + b.h);
|
|
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
|
|
inline dng_rect_real64 operator+ (const dng_rect_real64 &a,
|
|
const dng_point_real64 &b)
|
|
{
|
|
|
|
return dng_rect_real64 (a.t + b.v,
|
|
a.l + b.h,
|
|
a.b + b.v,
|
|
a.r + b.h);
|
|
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
|
|
inline dng_rect operator- (const dng_rect &a,
|
|
const dng_point &b)
|
|
{
|
|
|
|
return dng_rect (a.t - b.v,
|
|
a.l - b.h,
|
|
a.b - b.v,
|
|
a.r - b.h);
|
|
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
|
|
inline dng_rect_real64 operator- (const dng_rect_real64 &a,
|
|
const dng_point_real64 &b)
|
|
{
|
|
|
|
return dng_rect_real64 (a.t - b.v,
|
|
a.l - b.h,
|
|
a.b - b.v,
|
|
a.r - b.h);
|
|
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
|
|
inline dng_rect Transpose (const dng_rect &a)
|
|
{
|
|
|
|
return dng_rect (a.l, a.t, a.r, a.b);
|
|
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
|
|
inline dng_rect_real64 Transpose (const dng_rect_real64 &a)
|
|
{
|
|
|
|
return dng_rect_real64 (a.l, a.t, a.r, a.b);
|
|
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
|
|
inline void HalfRect (dng_rect &rect)
|
|
{
|
|
|
|
rect.r = rect.l + (int32) (rect.W () >> 1);
|
|
rect.b = rect.t + (int32) (rect.H () >> 1);
|
|
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
|
|
inline void DoubleRect (dng_rect &rect)
|
|
{
|
|
|
|
rect.r = rect.l + (int32) (rect.W () << 1);
|
|
rect.b = rect.t + (int32) (rect.H () << 1);
|
|
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
|
|
inline void InnerPadRect (dng_rect &rect,
|
|
int32 pad)
|
|
{
|
|
|
|
rect.l += pad;
|
|
rect.r -= pad;
|
|
rect.t += pad;
|
|
rect.b -= pad;
|
|
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
|
|
inline void OuterPadRect (dng_rect &rect,
|
|
int32 pad)
|
|
{
|
|
|
|
InnerPadRect (rect, -pad);
|
|
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
|
|
inline void InnerPadRectH (dng_rect &rect,
|
|
int32 pad)
|
|
{
|
|
|
|
rect.l += pad;
|
|
rect.r -= pad;
|
|
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
|
|
inline void InnerPadRectV (dng_rect &rect,
|
|
int32 pad)
|
|
{
|
|
|
|
rect.t += pad;
|
|
rect.b -= pad;
|
|
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
|
|
inline dng_rect MakeHalfRect (const dng_rect &rect)
|
|
{
|
|
|
|
dng_rect out = rect;
|
|
|
|
HalfRect (out);
|
|
|
|
return out;
|
|
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
|
|
inline dng_rect MakeDoubleRect (const dng_rect &rect)
|
|
{
|
|
|
|
dng_rect out = rect;
|
|
|
|
DoubleRect (out);
|
|
|
|
return out;
|
|
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
|
|
inline dng_rect MakeInnerPadRect (const dng_rect &rect,
|
|
int32 pad)
|
|
{
|
|
|
|
dng_rect out = rect;
|
|
|
|
InnerPadRect (out, pad);
|
|
|
|
return out;
|
|
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
|
|
inline dng_rect MakeOuterPadRect (const dng_rect &rect,
|
|
int32 pad)
|
|
{
|
|
|
|
dng_rect out = rect;
|
|
|
|
OuterPadRect (out, pad);
|
|
|
|
return out;
|
|
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
|
|
#endif
|
|
|
|
/*****************************************************************************/
|