mirror of https://gitee.com/openkylin/gdcm.git
173 lines
4.0 KiB
C++
173 lines
4.0 KiB
C++
/*=========================================================================
|
|
|
|
Program: GDCM (Grassroots DICOM). A DICOM library
|
|
|
|
Copyright (c) 2006-2011 Mathieu Malaterre
|
|
All rights reserved.
|
|
See Copyright.txt or http://gdcm.sourceforge.net/Copyright.html for details.
|
|
|
|
This software is distributed WITHOUT ANY WARRANTY; without even
|
|
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
|
PURPOSE. See the above copyright notice for more information.
|
|
|
|
=========================================================================*/
|
|
#include "gdcmBoxRegion.h"
|
|
|
|
#include <limits>
|
|
#include <algorithm> // req C++11
|
|
|
|
namespace gdcm
|
|
{
|
|
class BoxRegionInternals
|
|
{
|
|
public:
|
|
BoxRegionInternals()
|
|
{
|
|
XMin = YMin = ZMin = std::numeric_limits<unsigned int>::max();
|
|
XMax = YMax = ZMax = std::numeric_limits<unsigned int>::min();
|
|
}
|
|
unsigned int XMin, XMax;
|
|
unsigned int YMin, YMax;
|
|
unsigned int ZMin, ZMax;
|
|
void Print(std::ostream &os) const
|
|
{
|
|
os << "Min:" << XMin << "," << YMin << "," << ZMin << "\n";
|
|
os << "Max:" << XMax << "," << YMax << "," << ZMax;
|
|
}
|
|
|
|
};
|
|
|
|
BoxRegion::BoxRegion()
|
|
{
|
|
Internals = new BoxRegionInternals;
|
|
}
|
|
|
|
BoxRegion::~BoxRegion()
|
|
{
|
|
delete Internals;
|
|
}
|
|
|
|
void BoxRegion::SetDomain(unsigned int xmin, unsigned int xmax,
|
|
unsigned int ymin, unsigned int ymax,
|
|
unsigned int zmin, unsigned int zmax)
|
|
{
|
|
Internals->XMin = xmin;
|
|
Internals->YMin = ymin;
|
|
Internals->ZMin = zmin;
|
|
Internals->XMax = xmax;
|
|
Internals->YMax = ymax;
|
|
Internals->ZMax = zmax;
|
|
}
|
|
|
|
Region *BoxRegion::Clone() const
|
|
{
|
|
BoxRegion *br = new BoxRegion( *this );
|
|
return br;
|
|
}
|
|
|
|
bool BoxRegion::Empty() const
|
|
{
|
|
assert( 0 );
|
|
return false;
|
|
}
|
|
|
|
bool BoxRegion::IsValid() const
|
|
{
|
|
if (Internals->XMax < Internals->XMin ||
|
|
Internals->YMax < Internals->YMin ||
|
|
Internals->ZMax < Internals->ZMin )
|
|
{
|
|
return false;
|
|
}
|
|
// Some properly crafted DICOM could have bigger values, reject them:
|
|
// technically there is no such restrictions for Z direction
|
|
if (Internals->XMax >= std::numeric_limits<uint16_t>::max() ||
|
|
Internals->YMax >= std::numeric_limits<uint16_t>::max() ||
|
|
Internals->ZMax == std::numeric_limits<uint32_t>::max() )
|
|
{
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
size_t BoxRegion::Area() const
|
|
{
|
|
// on some system size_t is too small:
|
|
const uint64_t A = Internals->XMax - Internals->XMin + 1;
|
|
const uint64_t B = Internals->YMax - Internals->YMin + 1;
|
|
const uint64_t C = Internals->ZMax - Internals->ZMin + 1;
|
|
const uint64_t tmp = A * B;
|
|
if (tmp != 0 && (std::numeric_limits<size_t>::max() / tmp) < C)
|
|
{
|
|
// multiplication exceed range of unsigned
|
|
return 0;
|
|
}
|
|
return (size_t)(tmp * C);
|
|
}
|
|
|
|
unsigned int BoxRegion::GetXMin() const
|
|
{
|
|
return Internals->XMin;
|
|
}
|
|
unsigned int BoxRegion::GetXMax() const
|
|
{
|
|
return Internals->XMax;
|
|
}
|
|
unsigned int BoxRegion::GetYMin() const
|
|
{
|
|
return Internals->YMin;
|
|
}
|
|
unsigned int BoxRegion::GetYMax() const
|
|
{
|
|
return Internals->YMax;
|
|
}
|
|
unsigned int BoxRegion::GetZMin() const
|
|
{
|
|
return Internals->ZMin;
|
|
}
|
|
unsigned int BoxRegion::GetZMax() const
|
|
{
|
|
return Internals->ZMax;
|
|
}
|
|
|
|
BoxRegion BoxRegion::BoundingBox(BoxRegion const & b1, BoxRegion const & b2 )
|
|
{
|
|
BoxRegion r;
|
|
unsigned int xmin = std::min( b1.GetXMin(), b2.GetXMin() );
|
|
unsigned int xmax = std::min( b1.GetXMax(), b2.GetXMax() );
|
|
unsigned int ymin = std::min( b1.GetYMin(), b2.GetYMin() );
|
|
unsigned int ymax = std::min( b1.GetYMax(), b2.GetYMax() );
|
|
unsigned int zmin = std::min( b1.GetZMin(), b2.GetZMin() );
|
|
unsigned int zmax = std::min( b1.GetZMax(), b2.GetZMax() );
|
|
|
|
r.SetDomain(xmin, xmax, ymin, ymax, zmin, zmax);
|
|
return r;
|
|
}
|
|
|
|
BoxRegion::BoxRegion(const BoxRegion& b)
|
|
{
|
|
assert( b.Internals );
|
|
Internals = new BoxRegionInternals;
|
|
*Internals = *b.Internals;
|
|
}
|
|
|
|
void BoxRegion::operator=(const BoxRegion& b)
|
|
{
|
|
assert( b.Internals );
|
|
*Internals = *b.Internals;
|
|
}
|
|
|
|
BoxRegion BoxRegion::ComputeBoundingBox()
|
|
{
|
|
return *this;
|
|
}
|
|
|
|
void BoxRegion::Print(std::ostream &os) const
|
|
{
|
|
Region::Print( os );
|
|
os << "Domain:\n";
|
|
this->Internals->Print( os );
|
|
}
|
|
|
|
} // end namespace gdcm
|