+ * \warning if a DICOM_V3 header is supplied,
+ * groups < 0x0008 and shadow groups are ignored
+ * \warning NO TEST is performed on processor "Endiannity".
+ * @param fileName name of the file to be created
+ * (any already existing file is overwritten)
+ * @return false if write fails
+ */
+
+bool gdcmFile::WriteAcr (std::string const & fileName)
+{
+ return WriteBase(fileName, gdcmACR);
+}
+
+//-----------------------------------------------------------------------------
+// Protected
+/**
+ * \ingroup gdcmFile
+ * \brief NOT a end user inteded function
+ * (used by WriteDcmExplVR, WriteDcmImplVR, WriteAcr, etc)
+ * @param fileName name of the file to be created
+ * (any already existing file is overwritten)
+ * @param type file type (ExplicitVR, ImplicitVR, ...)
+ * @return false if write fails
+ */
+bool gdcmFile::WriteBase (std::string const & fileName, FileType type)
+{
+ if ( PixelRead == -1 && type != gdcmExplicitVR)
+ {
+ return false;
+ }
+
+ FILE *fp1 = fopen(fileName.c_str(), "wb");
+ if (fp1 == NULL)
+ {
+ printf("Failed to open (write) File [%s] \n", fileName.c_str());
+ return false;
+ }
+
+ if ( type == gdcmImplicitVR || type == gdcmExplicitVR )
+ {
+ // writing Dicom File Preamble
+ uint8_t* filePreamble = new uint8_t[128];
+ memset(filePreamble, 0, 128);
+ fwrite(filePreamble, 128, 1, fp1);
+ fwrite("DICM", 4, 1, fp1);
+
+ delete[] filePreamble;
+ }
+
+ // --------------------------------------------------------------
+ // Special Patch to allow gdcm to re-write ACR-LibIDO formated images
+ //
+ // if recognition code tells us we dealt with a LibIDO image
+ // we reproduce on disk the switch between lineNumber and columnNumber
+ // just before writting ...
+
+ /// \todo the best trick would be *change* the recognition code
+ /// but pb expected if user deals with, e.g. COMPLEX images
+
+ std::string rows, columns;
+ if ( Header->GetFileType() == gdcmACR_LIBIDO)
+ {
+ rows = Header->GetEntryByNumber(0x0028, 0x0010);
+ columns = Header->GetEntryByNumber(0x0028, 0x0011);
+
+ Header->SetEntryByNumber(columns, 0x0028, 0x0010);
+ Header->SetEntryByNumber(rows , 0x0028, 0x0011);
+ }
+ // ----------------- End of Special Patch ----------------
+
+ uint16_t grPixel = Header->GetGrPixel();
+ uint16_t numPixel = Header->GetNumPixel();;
+
+ gdcmDocEntry* PixelElement =
+ GetHeader()->GetDocEntryByNumber(grPixel, numPixel);
+
+ if ( PixelRead == 1 )
+ {
+ // we read pixel 'as is' (no tranformation LUT -> RGB)
+ PixelElement->SetLength( ImageDataSizeRaw );
+ }
+ else if ( PixelRead == 0 )
+ {
+ // we tranformed GrayLevel pixels + LUT into RGB Pixel
+ PixelElement->SetLength( ImageDataSize );
+ }
+
+ Header->Write(fp1, type);
+
+ // --------------------------------------------------------------
+ // Special Patch to allow gdcm to re-write ACR-LibIDO formated images
+ //
+ // ...and we restore the Header to be Dicom Compliant again
+ // just after writting
+
+ if ( Header->GetFileType() == gdcmACR_LIBIDO )
+ {
+ Header->SetEntryByNumber(rows , 0x0028, 0x0010);
+ Header->SetEntryByNumber(columns, 0x0028, 0x0011);
+ }
+ // ----------------- End of Special Patch ----------------
+
+ // fwrite(PixelData, ImageDataSize, 1, fp1); // should be useless, now
+ fclose (fp1);
+
+ return true;
+}
+
+//-----------------------------------------------------------------------------
+// Private
+/**
+ * \ingroup gdcmFile
+ * \brief Swap the bytes, according to swap code.
+ * \warning not end user intended
+ * @param im area to deal with
+ * @param swap swap code
+ * @param lgr Area Length
+ * @param nb Pixels Bit number
+ */
+void gdcmFile::SwapZone(void *im, int swap, int lgr, int nb)
+{
+ int i;
+
+ if( nb == 16 )
+ {
+ uint16_t* im16 = (uint16_t*)im;
+ switch( swap )
+ {
+ case 0:
+ case 12:
+ case 1234:
+ break;
+ case 21:
+ case 3412:
+ case 2143:
+ case 4321:
+ for(i=0; i < lgr/2; i++)
+ {
+ im16[i]= (im16[i] >> 8) | (im16[i] << 8 );
+ }
+ break;
+ default:
+ std::cout << "SWAP value (16 bits) not allowed :i" << swap <<
+ std::endl;
+ }
+ }
+ else if( nb == 32 )
+ {
+ uint32_t s32;
+ uint16_t fort, faible;
+ uint32_t* im32 = (uint32_t*)im;
+ switch ( swap )
+ {
+ case 0:
+ case 1234:
+ break;
+ case 4321:
+ for(i = 0; i < lgr/4; i++)
+ {
+ faible = im32[i] & 0x0000ffff; // 4321
+ fort = im32[i] >> 16;
+ fort = ( fort >> 8 ) | ( fort << 8 );
+ faible = ( faible >> 8 ) | ( faible << 8);
+ s32 = faible;
+ im32[i] = ( s32 << 16 ) | fort;
+ }
+ break;
+ case 2143:
+ for(i = 0; i < lgr/4; i++)
+ {
+ faible = im32[i] & 0x0000ffff; // 2143
+ fort = im32[i] >> 16;
+ fort = ( fort >> 8 ) | ( fort << 8 );
+ faible = ( faible >> 8) | ( faible << 8);
+ s32 = fort;
+ im32[i] = ( s32 << 16 ) | faible;
+ }
+ break;
+ case 3412:
+ for(i = 0; i < lgr/4; i++)
+ {
+ faible = im32[i] & 0x0000ffff; // 3412
+ fort = im32[i] >> 16;
+ s32 = faible;
+ im32[i] = ( s32 << 16 ) | fort;
+ }
+ break;
+ default:
+ std::cout << "SWAP value (32 bits) not allowed : " << swap <<
+ std::endl;
+ }
+ }
+}
+
+/**
+ * \ingroup gdcmFile
+ * \brief Read pixel data from disk (optionaly decompressing) into the
+ * caller specified memory location.
+ * @param destination where the pixel data should be stored.