# GenFakeImage.cxx

    /*=========================================================================

      Program: GDCM (Grassroots DICOM). A DICOM library
      Module:  $URL$

      Copyright (c) 2006-2009 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 "gdcmImage.h"
    #include "gdcmImageWriter.h"
    #include "gdcmFileDerivation.h"
    #include "gdcmUIDGenerator.h"
    //#include "gdcmImageChangePhotometricInterpretation.h"

    /*
     * This example shows two things:
     * 1. How to create an image ex-nihilo
     * 2. How to use the gdcm.FileDerivation filter. This filter is meant to create "DERIVED" image
     * object. FileDerivation has a simple API where you can reference *all* the input image that have been
     * used to generate the image. The API also allows user to specify the purpose of reference (see CID 7202,
     * PS 3.16 - 2008), and the image derivation type (CID 7203, PS 3.16 - 2008).
     */
    int main(int, char *[])
    {
      // Step 1: Fake Image
      gdcm::SmartPointer<gdcm::Image> im = new gdcm::Image;

      char * buffer = new char[ 256 * 256 * 3];
      char * p = buffer;
      int b = 128;
      int ybr[3];
      int ybr2[3];
      int rgb[3];

      for(int r = 0; r < 256; ++r)
        for(int g = 0; g < 256; ++g)
          //for(int b = 0; b < 256; ++b)
          {
          rgb[0] = r;
          rgb[1] = g;
          rgb[1] = 128;
          rgb[2] = b;
          ybr[0] = r;
          ybr[1] = g;
          ybr[1] = 128;
          ybr[2] = b;

          ybr2[0] = r;
          ybr2[1] = g;
          ybr2[1] = 128;
          ybr2[2] = b;
          //gdcm::ImageChangePhotometricInterpretation::YBR2RGB(rgb, ybr);
          //gdcm::ImageChangePhotometricInterpretation::RGB2YBR(ybr2, rgb);
          *p++ = ybr2[0];
          *p++ = ybr2[1];
          *p++ = ybr2[2];
          }

      im->SetNumberOfDimensions( 2 );
      im->SetDimension(0, 256 );
      im->SetDimension(1, 256 );

      im->GetPixelFormat().SetSamplesPerPixel(3);
      //im->SetPhotometricInterpretation( gdcm::PhotometricInterpretation::RGB );
      im->SetPhotometricInterpretation( gdcm::PhotometricInterpretation::YBR_FULL );

      unsigned long l = im->GetBufferLength();
      if( l != 256 * 256 * 3 )
        {
        return 1;
        }
      gdcm::DataElement pixeldata( gdcm::Tag(0x7fe0,0x0010) );
      pixeldata.SetByteValue( buffer, l );
      delete[] buffer;
      im->SetDataElement( pixeldata );

      gdcm::UIDGenerator uid; // helper for uid generation

      gdcm::SmartPointer<gdcm::File> file = new gdcm::File; // empty file

      // Step 2: DERIVED object
      gdcm::FileDerivation fd;
      // For the pupose of this execise we will pretend that this image is referencing
      // two source image (we need to generate fake UID for that).
      const char ReferencedSOPClassUID[] = "1.2.840.10008.5.1.4.1.1.7"; // Secondary Capture
      fd.AddReference( ReferencedSOPClassUID, uid.Generate() );
      fd.AddReference( ReferencedSOPClassUID, uid.Generate() );

      // Again for the purpose of the exercise we will pretend that the image is a
      // multiplanar reformat (MPR):
      // CID 7202 Source Image Purposes of Reference
      // {"DCM",121322,"Source image for image processing operation"},
      fd.SetPurposeOfReferenceCodeSequenceCodeValue( 121322 );
      // CID 7203 Image Derivation
      // { "DCM",113072,"Multiplanar reformatting" },
      fd.SetDerivationCodeSequenceCodeValue( 113072 );
      fd.SetFile( *file );
      // If all Code Value are ok the filter will execute properly
      if( !fd.Derive() )
        {
        std::cerr << "Sorry could not derive using input info" << std::endl;
        return 1;
        }

      // We pass both :
      // 1. the fake generated image
      // 2. the 'DERIVED' dataset object
      // to the writer.
      gdcm::ImageWriter w;
      w.SetImage( *im );
      w.SetFile( fd.GetFile() );

      // Set the filename:
      w.SetFileName( "ybr2.dcm" );
      if( !w.Write() )
        {
        return 1;
        }

      return 0;
    }