#include "gdcmVR.h"
#include <algorithm>
#include <cassert>
#include <cstring>
namespace gdcm
{
static const char *VRStrings[] = {
"??", "AE", "AS", "AT", "CS", "DA", "DS", "DT", "FD", "FL", "IS", "LO", "LT", "OB", "OF", "OW", "PN", "SH", "SL", "SQ", "SS", "ST", "TM", "UI", "UL", "UN", "US", "UT", "OD", "OL", "UC", "UR", "OV", "SV", "UV", "OB or OW", "US or SS", "US or SS or OW", "US or OW", nullptr
};
static VR::VRType VRValue[] = {
VR::INVALID ,
VR::AE ,
VR::AS ,
VR::AT ,
VR::CS ,
VR::DA ,
VR::DS ,
VR::DT ,
VR::FD ,
VR::FL ,
VR::IS ,
VR::LO ,
VR::LT ,
VR::OB ,
VR::OF ,
VR::OW ,
VR::PN ,
VR::SH ,
VR::SL ,
VR::SQ ,
VR::SS ,
VR::ST ,
VR::TM ,
VR::UI ,
VR::UL ,
VR::UN ,
VR::US ,
VR::UT ,
VR::OD ,
VR::OL ,
VR::UC ,
VR::UR ,
VR::OV ,
VR::SV ,
VR::UV ,
};
bool VR::IsVRFile() const
{
switch(VRField)
{
case VR::INVALID:
case VR::AE:
case VR::AS:
case VR::AT:
case VR::CS:
case VR::DA:
case VR::DS:
case VR::DT:
case VR::FD:
case VR::FL:
case VR::IS:
case VR::LO:
case VR::LT:
case VR::OB:
case VR::OD:
case VR::OF:
case VR::OL:
case VR::OV:
case VR::OW:
case VR::PN:
case VR::SH:
case VR::SL:
case VR::SQ:
case VR::SS:
case VR::ST:
case VR::SV:
case VR::TM:
case VR::UC:
case VR::UI:
case VR::UL:
case VR::UN:
case VR::UR:
case VR::US:
case VR::UT:
case VR::UV:
return true;
default:
return false;
}
}
unsigned int VR::GetSizeof() const
{
unsigned int size;
switch(VRField)
{
case VR::AE:
size = sizeof(VRToType<VR::AE>::Type);
break;
case VR::AS:
size = sizeof(VRToType<VR::AS>::Type);
break;
case VR::AT:
size = sizeof(VRToType<VR::AT>::Type);
break;
case VR::CS:
size = sizeof(VRToType<VR::CS>::Type);
break;
case VR::DA:
size = sizeof(VRToType<VR::DA>::Type);
break;
case VR::DS:
size = sizeof(VRToType<VR::DS>::Type);
break;
case VR::DT:
size = sizeof(VRToType<VR::DT>::Type);
break;
case VR::FD:
size = sizeof(VRToType<VR::FD>::Type);
break;
case VR::FL:
size = sizeof(VRToType<VR::FL>::Type);
break;
case VR::IS:
size = sizeof(VRToType<VR::IS>::Type);
break;
case VR::LO:
size = sizeof(VRToType<VR::LO>::Type);
break;
case VR::LT:
size = sizeof(VRToType<VR::LT>::Type);
break;
case VR::OB:
size = sizeof(VRToType<VR::OB>::Type);
break;
case VR::OD:
size = sizeof(VRToType<VR::OD>::Type);
break;
case VR::OF:
size = sizeof(VRToType<VR::OF>::Type);
break;
case VR::OL:
size = sizeof(VRToType<VR::OL>::Type);
break;
case VR::OV:
size = sizeof(VRToType<VR::OV>::Type);
break;
case VR::OW:
size = sizeof(VRToType<VR::OW>::Type);
break;
case VR::PN:
size = sizeof(VRToType<VR::PN>::Type);
break;
case VR::SH:
size = sizeof(VRToType<VR::SH>::Type);
break;
case VR::SL:
size = sizeof(VRToType<VR::SL>::Type);
break;
case VR::SQ:
size = sizeof(VRToType<VR::SQ>::Type);
break;
case VR::SS:
size = sizeof(VRToType<VR::SS>::Type);
break;
case VR::ST:
size = sizeof(VRToType<VR::ST>::Type);
break;
case VR::SV:
size = sizeof(VRToType<VR::SV>::Type);
break;
case VR::TM:
size = sizeof(VRToType<VR::TM>::Type);
break;
case VR::UC:
size = sizeof(VRToType<VR::UC>::Type);
break;
case VR::UI:
size = sizeof(VRToType<VR::UI>::Type);
break;
case VR::UL:
size = sizeof(VRToType<VR::UL>::Type);
break;
case VR::UN:
size = sizeof(VRToType<VR::UN>::Type);
break;
case VR::UR:
size = sizeof(VRToType<VR::UR>::Type);
break;
case VR::US:
size = sizeof(VRToType<VR::US>::Type);
break;
case VR::UT:
size = sizeof(VRToType<VR::UT>::Type);
break;
case VR::UV:
size = sizeof(VRToType<VR::UV>::Type);
break;
case VR::US_SS:
size = sizeof(VRToType<VR::US>::Type); break;
default:
size = 0;
}
gdcm_assert( size );
return size;
}
unsigned int VR::GetIndex(VRType vr)
{
if( vr == VR::VL32 ) return 0;
unsigned int l = 0;
gdcm_assert( vr <= VR_END );
switch(vr)
{
case INVALID:
break;
case OB_OW:
l = 35;
break;
case US_SS:
l = 36;
break;
case US_SS_OW:
l = 37;
break;
case US_OW:
l = 38;
break;
case VR_END:
l = 39;
break;
default:
{
long long a = (long long)vr;
for (; a > 1; ++l)
a >>= 1LL;
l++;
}
break;
}
return l;
}
const char *VR::GetVRString(VRType vr)
{
const unsigned int idx = GetIndex(vr);
return VRStrings[idx];
}
const char *VR::GetVRStringFromFile(VRType vr)
{
#if 1
static const int N = sizeof(VRValue) / sizeof(VRType);
gdcm_assert( N == 35 );
static VRType *start = VRValue;
static VRType *end = VRValue+N;
const VRType *p =
std::lower_bound(start, end, vr);
gdcm_assert( *p == vr );
gdcm_assert( (p - start) == (long long)GetIndex(vr) );
return VRStrings[p-start];
#else#endif
}
class MySort
{
public:
bool operator() (const char *a, const char *b)
{
if( a[0] == b[0] )
return a[1] < b[1];
return a[0] < b[0];
}
};
VR::VRType VR::GetVRTypeFromFile(const char *vr)
{
#if 0#else VRType r = VR::VR_END;
for (int i = 1; VRStrings[i] != nullptr; i++)
{
const char *ref = VRStrings[i];
if (ref[0] == vr[0] && ref[1] == vr[1] )
{
r = (VR::VRType)(1LL << (i-1));
break;
}
}
if( r == VR::VR_END )
{
if( vr[0] >= ' ' && vr[0] <= '~'
&& vr[1] >= ' ' && vr[1] <= '~' ) {
return VR::UN;
}
return VR::INVALID;
}
#endif
gdcm_assert( r != VR::INVALID
&& r != VR::OB_OW
&& r != VR::US_SS
&& r != VR::US_SS_OW
&& r != VR::US_OW
&& r != VR::VR_END );
return r;
}
VR::VRType VR::GetVRType(const char *vr)
{
VRType r = VR::VR_END;
if(!vr) return r;
for (int i = 0; VRStrings[i] != nullptr; i++)
if (strcmp(VRStrings[i],vr) == 0)
{
switch(i)
{
case 0:
r = INVALID;
break;
case 35:
r = OB_OW;
break;
case 36:
r = US_SS;
break;
case 37:
r = US_SS_OW;
break;
case 38:
r = US_OW;
break;
case 39:
r = VR_END; gdcm_assert(0);
break;
default:
gdcm_assert( vr[2] == 0 );
r = (VR::VRType)(1LL << (i-1));
}
break; }
return r;
}
bool VR::IsValid(const char *vr)
{
for (int i = 1; VRStrings[i] != nullptr; i++)
{
const char *ref = VRStrings[i];
if (ref[0] == vr[0] && ref[1] == vr[1] )
{
gdcm_assert( i < 35 ); return true;
}
}
return false;
}
bool VR::IsValid(const char *vr1, VRType vr2)
{
gdcm_assert( strlen(vr1) == 2 );
VR::VRType vr = GetVRType(vr1);
return ((vr & vr2) != 0 ? true : false);
}
bool VR::IsSwap(const char *vr)
{
gdcm_assert( vr[2] == '\0' );
char vr_swap[3];
vr_swap[0] = vr[1];
vr_swap[1] = vr[0];
vr_swap[2] = '\0';
gdcm_assert( GetVRType(vr_swap) != SS );
return GetVRType(vr_swap) != VR_END;
}
#define VRTemplateCase(type, rep) \
case VR::type: \
return (VR::VRType)VRToEncoding<VR::type>::Mode \
== VR::rep;
#define VRTemplate(rep) \
VRTemplateCase(AE,rep) \
VRTemplateCase(AS,rep) \
VRTemplateCase(AT,rep) \
VRTemplateCase(CS,rep) \
VRTemplateCase(DA,rep) \
VRTemplateCase(DS,rep) \
VRTemplateCase(DT,rep) \
VRTemplateCase(FD,rep) \
VRTemplateCase(FL,rep) \
VRTemplateCase(IS,rep) \
VRTemplateCase(LO,rep) \
VRTemplateCase(LT,rep) \
VRTemplateCase(OB,rep) \
VRTemplateCase(OD,rep) \
VRTemplateCase(OF,rep) \
VRTemplateCase(OL,rep) \
VRTemplateCase(OV,rep) \
VRTemplateCase(OW,rep) \
VRTemplateCase(PN,rep) \
VRTemplateCase(SH,rep) \
VRTemplateCase(SL,rep) \
VRTemplateCase(SQ,rep) \
VRTemplateCase(SS,rep) \
VRTemplateCase(ST,rep) \
VRTemplateCase(SV,rep) \
VRTemplateCase(TM,rep) \
VRTemplateCase(UC,rep) \
VRTemplateCase(UI,rep) \
VRTemplateCase(UL,rep) \
VRTemplateCase(UN,rep) \
VRTemplateCase(UR,rep) \
VRTemplateCase(US,rep) \
VRTemplateCase(UT,rep) \
VRTemplateCase(UV,rep)
bool VR::IsASCII(VRType vr)
{
switch(vr)
{
VRTemplate(VRASCII)
default:
return false;
}
}
bool VR::IsASCII2(VRType vr)
{
gdcm_assert( vr != VR::INVALID );
return
vr == AE ||
vr == AS ||
vr == CS ||
vr == DA ||
vr == DS ||
vr == DT ||
vr == IS ||
vr == LO ||
vr == LT ||
vr == PN ||
vr == SH ||
vr == ST ||
vr == TM ||
vr == UI;
}
bool VR::IsBinary(VRType vr)
{
switch(vr)
{
VRTemplate(VRBINARY)
case US_SS_OW:
return true;
case US_SS:
return true;
case OB_OW:
return true;
default:
return false;
}
}
bool VR::IsBinary2(VRType vr)
{
return
vr == OB ||
vr == OW ||
vr == OB_OW ||
vr == UN ||
vr == SQ ;
}
bool VR::CanDisplay(VRType vr)
{
return
vr == AE ||
vr == AS ||
vr == AT ||
vr == CS ||
vr == DA ||
vr == DS ||
vr == FL ||
vr == FD ||
vr == IS ||
vr == LO ||
vr == LT ||
vr == PN ||
vr == SH ||
vr == SL ||
vr == SS ||
vr == ST ||
vr == TM ||
vr == UI ||
vr == UL ||
vr == US ||
vr == UT;
}
bool VR::Compatible(VR const &vr) const
{
if( vr.VRField == VR::INVALID ) return true;
else if( vr.VRField == VR::UN ) return true;
else return ((VRField & vr.VRField) > 0 ? true : false);
}
bool VR::IsDual() const
{
switch(VRField)
{
case OB_OW :
case US_SS :
case US_SS_OW :
case US_OW :
return true;
default:
return false;
}
}
}