-// $Header: /cvs/public/gdcm/src/Attic/gdcmHeader.cxx,v 1.88 2003/09/24 13:45:11 jpr Exp $
+// $Header: /cvs/public/gdcm/src/Attic/gdcmHeader.cxx,v 1.103 2003/10/23 12:08:32 jpr Exp $
-//This is needed when compiling in debug mode
-#ifdef _MSC_VER
-//'identifier' : not all control paths return a value
-//#pragma warning ( disable : 4715 )
-// 'identifier' : class 'type' needs to have dll-interface to be used by
-// clients of class 'type2'
-#pragma warning ( disable : 4251 )
-// 'identifier' : identifier was truncated to 'number' characters in the
-// debug information
-#pragma warning ( disable : 4786 )
-#endif //_MSC_VER
+#include "gdcmHeader.h"
#include <stdio.h>
#include <cerrno>
#include <cctype> // for isalpha
#include <sstream>
#include "gdcmUtil.h"
-#include "gdcmHeader.h"
#include "gdcmTS.h"
// Refer to gdcmHeader::CheckSwap()
void gdcmHeader::Initialise(void) {
dicom_vr = gdcmGlobal::GetVR();
dicom_ts = gdcmGlobal::GetTS();
- Dicts = gdcmGlobal::GetDicts();
+ Dicts = gdcmGlobal::GetDicts();
RefPubDict = Dicts->GetDefaultPubDict();
RefShaDict = (gdcmDict*)0;
}
if(!fp)
throw gdcmFileError("gdcmHeader::gdcmHeader(const char *, bool)");
}
- if ( fp )
- return true;
- dbg.Verbose(0, "gdcmHeader::gdcmHeader cannot open file", filename.c_str());
+
+ if ( fp ) {
+ guint16 zero;
+ fread(&zero, (size_t)2, (size_t)1, fp);
+
+ //ACR -- or DICOM with no Preamble
+ if( zero == 0x0008 || zero == 0x0800 || zero == 0x0002 || zero == 0x0200)
+ return true;
+ //DICOM
+ fseek(fp, 126L, SEEK_CUR);
+ char dicm[4];
+ fread(dicm, (size_t)4, (size_t)1, fp);
+ if( memcmp(dicm, "DICM", 4) == 0 )
+ return true;
+ fclose(fp);
+ dbg.Verbose(0, "gdcmHeader::gdcmHeader not DICOM/ACR", filename.c_str());
+ }
+ else {
+ dbg.Verbose(0, "gdcmHeader::gdcmHeader cannot open file", filename.c_str());
+ }
return false;
}
}
// Fourth semantics:
+//
+// ---> Warning : This fourth field is NOT part
+// of the 'official' Dicom Dictionnary
+// and should NOT be used.
+// (Not defined for all the groups
+// may be removed in a future release)
+//
// CMD Command
// META Meta Information
// DIR Directory
// We thought this was explicit VR, but we end up with an
// implicit VR tag. Let's backtrack.
- sprintf(msg,"Falsely explicit vr file (%04x,%04x)\n", ElVal->GetGroup(),ElVal->GetElement());
+ sprintf(msg,"Falsely explicit vr file (%04x,%04x)\n",
+ ElVal->GetGroup(),ElVal->GetElement());
dbg.Verbose(1, "gdcmHeader::FindVR: ",msg);
fseek(fp, PositionOnEntry, SEEK_SET);
const char * Transfert = Element->GetValue().c_str();
if ( memcmp(Transfert+strlen(Transfert)-2 ,"70",2)==0) return true;
if ( memcmp(Transfert+strlen(Transfert)-2 ,"55",2)==0) return true;
+ if (Element->GetValue() == "1.2.840.10008.1.2.4.57") return true;
+
return false;
}
void gdcmHeader::FixFoundLength(gdcmElValue * ElVal, guint32 FoundLength) {
if ( FoundLength == 0xffffffff)
FoundLength = 0;
+
+ // Sorry for the patch!
+ // XMedCom did the trick to read some nasty GE images ...
+ else if (FoundLength == 13) {
+ // The following 'if' will be removed when there is no more
+ // images on Creatis HDs with a 13 length for Manufacturer...
+ if ( (ElVal->GetGroup() != 0x0008) || (ElVal->GetElement() != 0x0070)) {
+ // end of remove area
+ FoundLength =10;
+ }
+ }
+ // to fix some garbage 'Leonardo' Siemens images
+ // May be commented out to avoid overhead
+ else if ( (ElVal->GetGroup() == 0x0009)
+ &&
+ ( (ElVal->GetElement() == 0x1113) || (ElVal->GetElement() == 0x1114) ) )
+ FoundLength =4;
+
ElVal->SetLength(FoundLength);
}
while ( ! FoundSequenceDelimiter) {
g = ReadInt16();
- n = ReadInt16();
-
- long l = ftell(fp);
-
+ n = ReadInt16();
if (errno == 1)
return 0;
TotalLength += 4; // We even have to decount the group and element
- if ( g != 0xfffe && g!=0xb00c ) /*for bogus header */ {
+ if ( g != 0xfffe && g!=0xb00c ) /*for bogus header */ {
char msg[100]; // for sprintf. Sorry
sprintf(msg,"wrong group (%04x) for an item sequence (%04x,%04x)\n",g, g,n);
dbg.Verbose(1, "gdcmHeader::FindLengthOB: ",msg);
- long l = ftell(fp);
errno = 1;
return 0;
}
- if ( n == 0xe0dd || ( g==0xb00c && n==0x0eb6 ) ) /* for bogus header */
+ if ( n == 0xe0dd || ( g==0xb00c && n==0x0eb6 ) ) /* for bogus header */
FoundSequenceDelimiter = true;
else if ( n != 0xe000 ){
char msg[100]; // for sprintf. Sorry
- sprintf(msg,"wrong element (%04x) for an item sequence (%04x,%04x)\n",n, g,n);
+ sprintf(msg,"wrong element (%04x) for an item sequence (%04x,%04x)\n",
+ n, g,n);
dbg.Verbose(1, "gdcmHeader::FindLengthOB: ",msg);
errno = 1;
return 0;
}
ItemLength = ReadInt32();
TotalLength += ItemLength + 4; // We add 4 bytes since we just read
- // the ItemLength with ReadInt32
-
+ // the ItemLength with ReadInt32
SkipBytes(ItemLength);
}
fseek(fp, PositionOnEntry, SEEK_SET);
void gdcmHeader::FindLength (gdcmElValue * ElVal) {
guint16 element = ElVal->GetElement();
guint16 group = ElVal->GetGroup();
- std::string vr = ElVal->GetVR();
+ std::string vr = ElVal->GetVR();
guint16 length16;
if( (element == 0x0010) && (group == 0x7fe0) ) {
dbg.SetDebug(0);
dbg.Verbose(2, "gdcmHeader::FindLength: ",
- "on est sur 7fe0 0010");
+ "we reached 7fe0 0010");
}
if ( (filetype == ExplicitVR) && ! ElVal->IsImplicitVr() ) {
fseek(fp, 2L, SEEK_CUR);
guint32 length32 = ReadInt32();
+
if ( (vr == "OB") && (length32 == 0xffffffff) ) {
ElVal->SetLength(FindLengthOB());
return;
// Heuristic: well some files are really ill-formed.
if ( length16 == 0xffff) {
length16 = 0;
- dbg.Verbose(0, "gdcmHeader::FindLength",
- "Erroneous element length fixed.");
+ //dbg.Verbose(0, "gdcmHeader::FindLength",
+ // "Erroneous element length fixed.");
+ // Actually, length= 0xffff means that we deal with
+ // Unknown Sequence Length
}
+
FixFoundLength(ElVal, (guint32)length16);
return;
}
void gdcmHeader::LoadElementValue(gdcmElValue * ElVal) {
size_t item_read;
guint16 group = ElVal->GetGroup();
- std::string vr = ElVal->GetVR();
+ std::string vr= ElVal->GetVR();
guint32 length = ElVal->GetLength();
bool SkipLoad = false;
* @param Elem
* \return integer acts as a boolean
*/
-int gdcmHeader::ReplaceOrCreateByNumber(std::string Value, guint16 Group, guint16 Elem ) {
+int gdcmHeader::ReplaceOrCreateByNumber(std::string Value,
+ guint16 Group, guint16 Elem ) {
// TODO : FIXME JPRx
// curieux, non ?
// on l'ajoute au ElValSet
// on affecte une valeur a cette ElValue a l'interieur du ElValSet
// --> devrait pouvoir etre fait + simplement ???
-
- gdcmElValue* nvElValue=NewElValueByNumber(Group, Elem);
- PubElValSet.Add(nvElValue);
+ if (CheckIfExistByNumber(Group, Elem) == 0) {
+ gdcmElValue* a =NewElValueByNumber(Group, Elem);
+ if (a == NULL)
+ return 0;
+ PubElValSet.Add(a);
+ }
PubElValSet.SetElValueByNumber(Value, Group, Elem);
return(1);
}
/**
* \ingroup gdcmHeader
- * \brief Modify or (Creates if not found) an element
+ * \brief Modify (or Creates if not found) an element
* @param Value new value
* @param Group
* @param Elem
/**
* \ingroup gdcmHeader
* \brief Set a new value if the invoked element exists
+ * Seems to be useless !!!
* @param Value
* @param Group
* @param Elem
*/
int gdcmHeader::ReplaceIfExistByNumber(char* Value, guint16 Group, guint16 Elem ) {
- gdcmElValue* elValue = PubElValSet.GetElementByNumber(Group, Elem);
+ //gdcmElValue* elValue = PubElValSet.GetElementByNumber(Group, Elem);
std::string v = Value;
PubElValSet.SetElValueByNumber(v, Group, Elem);
return 1;
g = ReadInt16();
n = ReadInt16();
-
- if ( (g==0x7fe0) && (n==0x0010) )
-
+
if (errno == 1)
// We reached the EOF (or an error occured) and header parsing
// has to be considered as finished.
return (gdcmElValue *)0;
}
NewElVal->SetOffset(ftell(fp));
- if ( (g==0x7fe0) && (n==0x0010) )
+ //if ( (g==0x7fe0) && (n==0x0010) )
return NewElVal;
}
* @return The result of the heuristical predicate.
*/
bool gdcmHeader::IsAnInteger(gdcmElValue * ElVal) {
- guint16 group = ElVal->GetGroup();
guint16 element = ElVal->GetElement();
- std::string vr = ElVal->GetVR();
+ std::string vr = ElVal->GetVR();
guint32 length = ElVal->GetLength();
// When we have some semantics on the element we just read, and if we
int gdcmHeader::SetPubElValByNumber(std::string content, guint16 group,
guint16 element)
-//TODO : homogeneiser les noms : SetPubElValByNumber qui appelle PubElValSet.SetElValueByNumber
+//TODO : homogeneiser les noms : SetPubElValByNumber
+// qui appelle PubElValSet.SetElValueByNumber
// pourquoi pas SetPubElValueByNumber ??
{
* @param VR The Value Representation to be given to this new tag.
* @ return The newly hand crafted Element Value.
*/
-gdcmElValue* gdcmHeader::NewManualElValToPubDict(std::string NewTagName, std::string VR) {
+gdcmElValue* gdcmHeader::NewManualElValToPubDict(std::string NewTagName,
+ std::string VR) {
gdcmElValue* NewElVal = (gdcmElValue*)0;
guint32 StuffGroup = 0xffff; // Group to be stuffed with additional info
guint32 FreeElem = 0;
/**
* \ingroup gdcmHeader
- * \brief
+ * \brief
* @return
*/
void gdcmHeader::PrintPubDict(std::ostream & os) {
/**
* \ingroup gdcmHeader
* \brief
- * @return
+ * @return integer, acts as a Boolean
*/
int gdcmHeader::Write(FILE * fp, FileType type) {
+
+
+ // TODO : move the following lines (and a lot of others)
+ // to a future function CheckAndCorrectHeader
+
+ if (type == ImplicitVR) {
+ std::string implicitVRTransfertSyntax = "1.2.840.10008.1.2";
+ ReplaceOrCreateByNumber(implicitVRTransfertSyntax,0x0002, 0x0010);
+
+ //FIXME Refer to standards on page 21, chapter 6.2 "Value representation":
+ // values with a VR of UI shall be padded with a single trailing null
+ // Dans le cas suivant on doit pader manuellement avec un 0
+
+ PubElValSet.SetElValueLengthByNumber(18, 0x0002, 0x0010);
+ }
+
+ if (type == ExplicitVR) {
+ std::string explicitVRTransfertSyntax = "1.2.840.10008.1.2.1";
+ ReplaceOrCreateByNumber(explicitVRTransfertSyntax,0x0002, 0x0010);
+
+ //FIXME Refer to standards on page 21, chapter 6.2 "Value representation":
+ // values with a VR of UI shall be padded with a single trailing null
+ // Dans le cas suivant on doit pader manuellement avec un 0
+
+ PubElValSet.SetElValueLengthByNumber(20, 0x0002, 0x0010);
+ }
+
return PubElValSet.Write(fp, type);
}
int l=Element->GetLength();
void * a = malloc(l);
if(!a) {
- cout << "Big Broblem (LoadElementVoidArea, malloc) "
- << std::hex << Group << " " << Elem << std::endl;
+ std::cout << "Big Broblem (LoadElementVoidArea, malloc) "
+ << std::hex << Group << " " << Elem << std::endl;
return NULL;
}
- int res = PubElValSet.SetVoidAreaByNumber(a, Group, Elem);
+ /* int res = */ PubElValSet.SetVoidAreaByNumber(a, Group, Elem);
// TODO check the result
size_t l2 = fread(a, 1, l ,fp);
if(l != l2) {
- cout << "Big Broblem (LoadElementVoidArea, fread) "
- << std::hex << Group << " " << Elem << std::endl;
+ std::cout << "Big Broblem (LoadElementVoidArea, fread) "
+ << std::hex << Group << " " << Elem << std::endl;
free(a);
return NULL;
- }
+ }
+ return a;
}
/**
gdcmElValue* elValue = PubElValSet.GetElementByNumber(Group, Elem);
if (!elValue) {
dbg.Verbose(1, "gdcmHeader::GetElValueByNumber",
- "failed to Locate gdcmElValue");
+ "failed to Locate gdcmElValue");
return (size_t)0;
}
return elValue->GetOffset();
return atoi(StrSize.c_str());
}
+/**
+ * \ingroup gdcmHeader
+ * \brief Retrieve the number of Bits Allocated
+ * (8, 12 -compacted ACR-NEMA files, 16, ...)
+ *
+ * @return The encountered number of Bits Allocated, 0 by default.
+ */
+int gdcmHeader::GetBitsAllocated(void) {
+ std::string StrSize = GetPubElValByNumber(0x0028,0x0100);
+ if (StrSize == GDCM_UNFOUND)
+ return 1;
+ return atoi(StrSize.c_str());
+}
/**
* \ingroup gdcmHeader
dbg.Verbose(0, "gdcmHeader::GetLUTLength: The CLUT R,G,B are not equal");
return 0;
}
- cout << "Lut Description " << LutDescriptionR <<std::endl;
+ std::cout << "Lut Description " << LutDescriptionR <<std::endl;
tokens.erase(tokens.begin(),tokens.end()); // clean any previous value
Tokenize (LutDescriptionR, tokens, "\\");
LutLength=atoi(tokens[0].c_str());
//int LutLength;
//int LutDepth;
int LutNbits;
- // Just hope Lookup Table Desc-Red = Lookup Table Desc-Red = Lookup Table Desc-Blue
+ //Just hope Lookup Table Desc-Red = Lookup Table Desc-Red = Lookup Table Desc-Blue
// Consistency already checked in GetLUTLength
std::string LutDescription = GetPubElValByNumber(0x0028,0x1101);
if (LutDescription == GDCM_UNFOUND)
if(l==0)
return (NULL);
int nBits=GetLUTNbits();
+
// a virer quand on aura trouve UNE image
// qui correspond VRAIMENT à la definition !
- cout << "l " << l << " nBits " << nBits;
+ std::cout << "l " << l << " nBits " << nBits;
l= l/(nBits/8);
unsigned char * g = (unsigned char *)LutG;
unsigned char * b = (unsigned char *)LutB;
for(int i=0;i<l;i++) {
- //cout << "lut16 " << i << " : " << *r << " " << *g << " " << *b << std::endl;
+ //std::cout << "lut16 " << i << " : " << *r << " " << *g << " " << *b
+ // << std::endl;
printf("lut 8 %d : %d %d %d \n",i,*r,*g,*b);
*rgb++ = *r++;
*rgb++ = *g++;
free(LutR); free(LutB); free(LutG);
return(LUTRGB);
}
+
+/* Sorry for the comments. The code will be moved in a fonction
+
+ std::string x=GetPubElValByNumber(0x0028,0x1201);
+ unsigned short int * lutR = (unsigned short int *)malloc((size_t)200*sizeof(short int));
+ unsigned short int * lutG = (unsigned short int *)malloc((size_t)200*sizeof(short int));
+ unsigned short int * lutB = (unsigned short int *)malloc((size_t)200*sizeof(short int));
+
+ std::vector<std::string> tokens;
+ tokens.erase(tokens.begin(),tokens.end()); // clean any previous value
+ Tokenize ((const std::string)x, tokens, "\\");
+ for (unsigned int i=0; i<tokens.size();i++) {
+ lutR[i] = atoi(tokens[i].c_str());
+ printf("%d (%x)\n",lutR[i],lutR[i]);
+ }
+
+ std::string y=GetPubElValByNumber(0x0028,0x1202);
+ tokens.erase(tokens.begin(),tokens.end()); // clean any previous value
+ Tokenize ((const std::string)y, tokens, "\\");
+ for (unsigned int i=0; i<tokens.size();i++) {
+ lutG[i] = atoi(tokens[i].c_str());
+ }
+
+ std::string z=GetPubElValByNumber(0x0028,0x1203);
+ tokens.erase(tokens.begin(),tokens.end()); // clean any previous value
+ Tokenize ((const std::string)z, tokens, "\\");
+ for (unsigned int i=0; i<tokens.size();i++) {
+ lutB[i] = atoi(tokens[i].c_str());
+ }
+ tokens.erase(tokens.begin(),tokens.end()); // clean any previous value
+ Tokenize ((const std::string)x, tokens, "\\");
+ for (unsigned int i=0; i<tokens.size();i++) {
+ lutB[i] = atoi(tokens[i].c_str());
+ }
+
+ */
+
+//int lgth=GetLUTLength();
+//cout << "lgth " << lgth << std::endl;;
+//for (int j=0;j<lgth;j++){
+//printf ("%d : %d (%x) %d (%x) %d (%x)\n",j,lutR[j],lutR[j],lutG[j],lutG[j],lutB[j],lutB[j]);
+//}
+
+
}