# GenAllVR.cxx

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

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

      Copyright (c) 2006-2010 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 "gdcmReader.h"
    #include "gdcmGlobal.h"
    #include "gdcmDummyValueGenerator.h"
    #include "gdcmMediaStorage.h"
    #include "gdcmWriter.h"
    #include "gdcmItem.h"
    #include "gdcmImageReader.h"
    #include "gdcmSequenceOfItems.h"
    #include "gdcmFile.h"
    #include "gdcmTag.h"
    #include "gdcmDict.h"
    #include "gdcmDictEntry.h"
    #include "gdcmDicts.h"
    #include "gdcmTransferSyntax.h"
    #include "gdcmUIDGenerator.h"
    #include "gdcmFileExplicitFilter.h"

    #include <cstdlib>
    #include <cstring>

    gdcm::Tag FindTagFromVR(gdcm::Dict const &dict, gdcm::VR const &vr)
    {
      using gdcm::Dict;
      Dict::ConstIterator beg = dict.Begin();
      Dict::ConstIterator end = dict.End();
      Dict::ConstIterator it;
      for( it = beg; it != end; ++it)
        {
        const gdcm::Tag &t = it->first;
        const gdcm::DictEntry &de = it->second;
        const gdcm::VR &vr_de = de.GetVR();
        if( vr == vr_de && !de.GetRetired() && t.GetGroup() >= 0x8 )
          {
          return t;
          }
        }
      return gdcm::Tag(0xffff,0xffff);
    }

    struct rnd_gen {
      rnd_gen(char const* range = "abcdefghijklmnopqrstuvwxyz0123456789")
        : range(range), len(std::strlen(range)) { }

      char operator ()() const {
        return range[static_cast<std::size_t>(std::rand() * (1.0 / (RAND_MAX + 1.0 )) * len)];
      }
    private:
      char const* range;
      std::size_t len;
    };

    /*
     */
    int main(int argc, char *argv[])
    {
      if( argc < 2 )
        {
        std::cerr << argv[0] << " output.dcm" << std::endl;
        return 1;
        }
      const char *outfilename = argv[1];
      static const gdcm::Global &g = gdcm::Global::GetInstance();
      static const gdcm::Dicts &dicts = g.GetDicts();
      static const gdcm::Dict &pubdict = dicts.GetPublicDict();
      using gdcm::VR;
      using gdcm::Tag;

      gdcm::Writer w;

      gdcm::File &f = w.GetFile();
      gdcm::DataSet &ds = f.GetDataSet();

      gdcm::FileExplicitFilter fef;
      //fef.SetChangePrivateTags( true );
      fef.SetFile( w.GetFile() );
      if( !fef.Change() )
        {
        std::cerr << "Failed to change" << std::endl;
        return 1;
        }

      gdcm::SmartPointer<gdcm::SequenceOfItems> sq = new gdcm::SequenceOfItems();
      sq->SetLengthToUndefined();

      gdcm::DummyValueGenerator dvg;

      const std::size_t len = 10;
      char ss[len];
      ss[len] = '\0';

      const char owner_str[] = "GDCM CONFORMANCE TESTS";
      gdcm::DataElement owner( gdcm::Tag(0x4d4d, 0x10) );
      owner.SetByteValue(owner_str, strlen(owner_str));
      owner.SetVR( gdcm::VR::LO );

      // Create an item
      gdcm::Item it;
      it.SetVLToUndefined();
      gdcm::DataSet &nds = it.GetNestedDataSet();
      //    nds.Insert(owner);
      //    nds.Insert(de);

      // Insert sequence into data set
      gdcm::DataElement des( gdcm::Tag(0x4d4d,0x1001) );
      des.SetVR(gdcm::VR::SQ);
      des.SetValue(*sq);
      des.SetVLToUndefined();

      ds.Insert(owner);
      ds.Insert(des);

      // avoid INVALID = 0
      for(int i = 1; i < 27; ++i)
        {
        VR vr = (VR::VRType)(1 << i);
        Tag t = FindTagFromVR( pubdict, vr );
        if( vr != VR::UN && vr != VR::SQ )
          {
          assert( t != Tag(0xffff,0xffff) );
          gdcm::DataElement de( t );
          std::generate_n(ss, len, rnd_gen());
          de.SetVR( vr );
          de.SetByteValue( ss, std::strlen( ss ) );
          nds.Insert( de );
          }
        }
      sq->AddItem(it);

      // Make sure to override any UID stuff
      gdcm::UIDGenerator uid;
      gdcm::DataElement de( Tag(0x8,0x18) ); // SOP Instance UID
      de.SetVR( VR::UI );
      const char *u = uid.Generate();
      de.SetByteValue( u, strlen(u) );
      ds.Insert( de );

      de.SetTag( Tag(0x8,0x16) ); // SOP Class UID
      de.SetVR( VR::UI );
      gdcm::MediaStorage ms( gdcm::MediaStorage::RawDataStorage );
      de.SetByteValue( ms.GetString(),strlen(ms.GetString()));
      ds.Insert( de );

      gdcm::FileMetaInformation &fmi = f.GetHeader();
      //fmi.SetDataSetTransferSyntax( gdcm::TransferSyntax::ImplicitVRLittleEndian );
      fmi.SetDataSetTransferSyntax( gdcm::TransferSyntax::ExplicitVRLittleEndian );

      w.SetCheckFileMetaInformation( true );
      w.SetFileName( outfilename );
      if (!w.Write() )
        {
        return 1;
        }

      return 0;
    }