+/**
+ * \brief Performs some consistency checking on various 'File related'
+ * (as opposed to 'DicomDir related') entries
+ * then writes in a file all the (Dicom Elements) included the Pixels
+ * @param fileName file name to write to
+ * @param filetype Type of the File to be written
+ * (ACR, ExplicitVR, ImplicitVR)
+ */
+bool File::Write(std::string fileName, FileType filetype)
+{
+ std::ofstream *fp = new std::ofstream(fileName.c_str(),
+ std::ios::out | std::ios::binary);
+ if (*fp == NULL)
+ {
+ gdcmWarningMacro("Failed to open (write) File: " << fileName.c_str());
+ return false;
+ }
+
+ // Entry : 0002|0000 = group length -> recalculated
+ ValEntry *e0002 = GetValEntry(0x0002,0x0000);
+ if( e0002 )
+ {
+ std::ostringstream sLen;
+ sLen << ComputeGroup0002Length(filetype);
+ e0002->SetValue(sLen.str());
+ }
+
+ // Bits Allocated
+ if ( GetEntryValue(0x0028,0x0100) == "12")
+ {
+ SetValEntry("16", 0x0028,0x0100);
+ }
+
+ int i_lgPix = GetEntryLength(GrPixel, NumPixel);
+ if (i_lgPix != -2)
+ {
+ // no (GrPixel, NumPixel) element
+ std::string s_lgPix = Util::Format("%d", i_lgPix+12);
+ s_lgPix = Util::DicomString( s_lgPix.c_str() );
+ InsertValEntry(s_lgPix,GrPixel, 0x0000);
+ }
+
+ // FIXME : should be nice if we could move it to File
+ // (or in future gdcmPixelData class)
+
+ // Drop Palette Color, if necessary
+ if ( GetEntryValue(0x0028,0x0002).c_str()[0] == '3' )
+ {
+ // if SamplesPerPixel = 3, sure we don't need any LUT !
+ // Drop 0028|1101, 0028|1102, 0028|1103
+ // Drop 0028|1201, 0028|1202, 0028|1203
+
+ DocEntry *e = GetDocEntry(0x0028,0x01101);
+ if (e)
+ {
+ RemoveEntryNoDestroy(e);
+ }
+ e = GetDocEntry(0x0028,0x1102);
+ if (e)
+ {
+ RemoveEntryNoDestroy(e);
+ }
+ e = GetDocEntry(0x0028,0x1103);
+ if (e)
+ {
+ RemoveEntryNoDestroy(e);
+ }
+ e = GetDocEntry(0x0028,0x01201);
+ if (e)
+ {
+ RemoveEntryNoDestroy(e);
+ }
+ e = GetDocEntry(0x0028,0x1202);
+ if (e)
+ {
+ RemoveEntryNoDestroy(e);
+ }
+ e = GetDocEntry(0x0028,0x1203);
+ if (e)
+ {
+ RemoveEntryNoDestroy(e);
+ }
+ }
+
+ Document::WriteContent(fp, filetype);
+
+ fp->close();
+ delete fp;
+
+ return true;
+}
+
+//-----------------------------------------------------------------------------
+// Protected
+/**
+ * \brief Initialize a default DICOM File that should contain all the
+ * field require by other reader. DICOM standard does not
+ * explicitely defines those fields, heuristic has been choosen.
+ * This is not perfect as we are writting a CT image...
+ */
+void File::InitializeDefaultFile()
+{
+ std::string date = Util::GetCurrentDate();
+ std::string time = Util::GetCurrentTime();
+ std::string uid = Util::CreateUniqueUID();
+ std::string uidMedia = uid;
+ std::string uidInst = uid;
+ std::string uidClass = Util::CreateUniqueUID();
+ std::string uidStudy = Util::CreateUniqueUID();
+ std::string uidSerie = Util::CreateUniqueUID();
+
+ // Meta Element Group Length
+ InsertValEntry("146 ", 0x0002, 0x0000);
+ // Media Storage SOP Class UID (CT Image Storage)
+ InsertValEntry("1.2.840.10008.5.1.4.1.1.2", 0x0002, 0x0002);
+ // Media Storage SOP Instance UID
+ InsertValEntry(uidMedia.c_str(), 0x0002, 0x0003);
+ // Transfer Syntax UID (Explicit VR Little Endian)
+ InsertValEntry("1.2.840.10008.1.2.1 ", 0x0002, 0x0010);
+ // META Implementation Class UID
+ InsertValEntry(uidClass.c_str(), 0x0002, 0x0012);
+ // Source Application Entity Title
+ InsertValEntry("GDCM", 0x0002, 0x0016);
+
+ // Instance Creation Date
+ InsertValEntry(date.c_str(), 0x0008, 0x0012);
+ // Instance Creation Time
+ InsertValEntry(time.c_str(), 0x0008, 0x0013);
+ // SOP Class UID
+ InsertValEntry("1.2.840.10008.5.1.4.1.1.2", 0x0008, 0x0016);
+ // SOP Instance UID
+ InsertValEntry(uidInst.c_str(), 0x0008, 0x0018);
+ // Modality
+ InsertValEntry("CT", 0x0008, 0x0060);
+ // Manufacturer
+ InsertValEntry("GDCM", 0x0008, 0x0070);
+ // Institution Name
+ InsertValEntry("GDCM", 0x0008, 0x0080);
+ // Institution Address
+ InsertValEntry("http://www-creatis.insa-lyon.fr/Public/Gdcm", 0x0008, 0x0081);
+
+ // Patient's Name
+ InsertValEntry("GDCM", 0x0010, 0x0010);
+ // Patient ID
+ InsertValEntry("GDCMID", 0x0010, 0x0020);
+
+ // Study Instance UID
+ InsertValEntry(uidStudy.c_str(), 0x0020, 0x000d);
+ // Series Instance UID
+ InsertValEntry(uidSerie.c_str(), 0x0020, 0x000e);
+ // StudyID
+ InsertValEntry("1", 0x0020, 0x0010);
+ // SeriesNumber
+ InsertValEntry("1", 0x0020, 0x0011);
+
+ // Samples per pixel 1 or 3
+ InsertValEntry("1", 0x0028, 0x0002);
+ // photochromatic interpretation
+ InsertValEntry("MONOCHROME1", 0x0028, 0x0004);
+ // nbRows
+ InsertValEntry("0", 0x0028, 0x0010);
+ // nbCols
+ InsertValEntry("0", 0x0028, 0x0011);
+ // BitsAllocated 8 or 12 or 16
+ InsertValEntry("8", 0x0028, 0x0100);
+ // BitsStored <= BitsAllocated
+ InsertValEntry("8", 0x0028, 0x0101);
+ // HighBit <= BitsAllocated - 1
+ InsertValEntry("7", 0x0028, 0x0102);
+ // Pixel Representation 0(unsigned) or 1(signed)
+ InsertValEntry("0", 0x0028, 0x0103);
+
+ // default value
+ // Special case this is the image (not a string)
+ GrPixel = 0x7fe0;
+ NumPixel = 0x0010;
+ InsertBinEntry(0, 0, GrPixel, NumPixel);
+}
+