/usr/include/gdcm-2.6/gdcmScanner.h is in libgdcm2-dev 2.6.3-3ubuntu3.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 | /*=========================================================================
Program: GDCM (Grassroots DICOM). A DICOM library
Copyright (c) 2006-2011 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.
=========================================================================*/
#ifndef GDCMSCANNER_H
#define GDCMSCANNER_H
#include "gdcmDirectory.h"
#include "gdcmSubject.h"
#include "gdcmTag.h"
#include "gdcmPrivateTag.h"
#include "gdcmSmartPointer.h"
#include <map>
#include <set>
#include <string>
#include <string.h> // strcmp
namespace gdcm
{
class StringFilter;
/**
* \brief Scanner
* This filter is meant for quickly browsing a FileSet (a set of files on
* disk). Special consideration are taken so as to read the mimimum amount of
* information in each file in order to retrieve the user specified set of
* DICOM Attribute.
*
* This filter is dealing with both VRASCII and VRBINARY element, thanks to the
* help of StringFilter
*
* \warning IMPORTANT In case of file where tags are not ordered (illegal as
* per DICOM specification), the output will be missing information
*
* \note implementation details. All values are stored in a std::set of
* std::string. Then the address of the cstring underlying the std::string is
* used in the std::map.
*
* This class implement the Subject/Observer pattern trigger the following events:
* \li ProgressEvent
* \li StartEvent
* \li EndEvent
*/
class GDCM_EXPORT Scanner : public Subject
{
friend std::ostream& operator<<(std::ostream &_os, const Scanner &s);
public:
Scanner():Values(),Filenames(),Mappings() {}
~Scanner();
/// struct to map a filename to a value
/// Implementation note:
/// all std::map in this class will be using const char * and not std::string
/// since we are pointing to existing std::string (hold in a std::vector)
/// this avoid an extra copy of the byte array.
/// Tag are used as Tag class since sizeof(tag) <= sizeof(pointer)
typedef std::map<Tag, const char*> TagToValue;
//typedef std::map<Tag, ConstCharWrapper> TagToValue; //StringMap;
//typedef TagToStringMap TagToValue;
typedef TagToValue::value_type TagToValueValueType;
/// Add a tag that will need to be read. Those are root level tags
void AddTag( Tag const & t );
void ClearTags();
// Work in progress do not use:
void AddPrivateTag( PrivateTag const & t );
/// Add a tag that will need to be skipped. Those are root level skip tags
void AddSkipTag( Tag const & t );
void ClearSkipTags();
/// Start the scan !
bool Scan( Directory::FilenamesType const & filenames );
Directory::FilenamesType const &GetFilenames() const { return Filenames; }
/// Print result
void Print( std::ostream & os ) const;
/// Check if filename is a key in the Mapping table.
/// returns true only of file can be found, which means
/// the file was indeed a DICOM file that could be processed
bool IsKey( const char * filename ) const;
/// Return the list of filename that are key in the internal map,
/// which means those filename were properly parsed
Directory::FilenamesType GetKeys() const;
// struct to store all the values found:
typedef std::set< std::string > ValuesType;
/// Get all the values found (in lexicographic order)
ValuesType const & GetValues() const { return Values; }
/// Get all the values found (in lexicographic order) associated with Tag 't'
ValuesType GetValues(Tag const &t) const;
/// Get all the values found (in a vector) associated with Tag 't'
/// This function is identical to GetValues, but is accessible from the wrapped
/// layer (python, C#, java)
Directory::FilenamesType GetOrderedValues(Tag const &t) const;
/* ltstr is CRITICAL, otherwise pointers value are used to do the key comparison */
struct ltstr
{
bool operator()(const char* s1, const char* s2) const
{
assert( s1 && s2 );
return strcmp(s1, s2) < 0;
}
};
typedef std::map<const char *,TagToValue, ltstr> MappingType;
typedef MappingType::const_iterator ConstIterator;
ConstIterator Begin() const { return Mappings.begin(); }
ConstIterator End() const { return Mappings.end(); }
/// Mappings are the mapping from a particular tag to the map, mapping filename to value:
MappingType const & GetMappings() const { return Mappings; }
/// Get the std::map mapping filenames to value for file 'filename'
TagToValue const & GetMapping(const char *filename) const;
/// Will loop over all files and return the first file where value match the reference value
/// 'valueref'
const char *GetFilenameFromTagToValue(Tag const &t, const char *valueref) const;
/// Will loop over all files and return a vector of std::strings of filenames
/// where value match the reference value 'valueref'
Directory::FilenamesType GetAllFilenamesFromTagToValue(Tag const &t, const char *valueref) const;
/// See GetFilenameFromTagToValue(). This is simply GetFilenameFromTagToValue followed
// by a call to GetMapping()
TagToValue const & GetMappingFromTagToValue(Tag const &t, const char *value) const;
/// Retrieve the value found for tag: t associated with file: filename
/// This is meant for a single short call. If multiple calls (multiple tags)
/// should be done, prefer the GetMapping function, and then reuse the TagToValue
/// hash table.
/// \warning Tag 't' should have been added via AddTag() prior to the Scan() call !
const char* GetValue(const char *filename, Tag const &t) const;
/// for wrapped language: instanciate a reference counted object
static SmartPointer<Scanner> New() { return new Scanner; }
protected:
void ProcessPublicTag(StringFilter &sf, const char *filename);
private:
// struct to store all uniq tags in ascending order:
typedef std::set< Tag > TagsType;
typedef std::set< PrivateTag > PrivateTagsType;
std::set< Tag > Tags;
std::set< PrivateTag > PrivateTags;
std::set< Tag > SkipTags;
ValuesType Values;
Directory::FilenamesType Filenames;
// Main struct that will hold all mapping:
MappingType Mappings;
double Progress;
};
//-----------------------------------------------------------------------------
inline std::ostream& operator<<(std::ostream &os, const Scanner &s)
{
s.Print( os );
return os;
}
#if defined(SWIGPYTHON) || defined(SWIGCSHARP) || defined(SWIGJAVA) || defined(SWIGPHP)
/*
* HACK: I need this temp class to be able to manipulate a std::map from python,
* swig does not support wrapping of simple class like std::map...
*/
class SWIGTagToValue
{
public:
SWIGTagToValue(Scanner::TagToValue const &t2v):Internal(t2v),it(t2v.begin()) {}
const Scanner::TagToValueValueType& GetCurrent() const { return *it; }
const Tag& GetCurrentTag() const { return it->first; }
const char *GetCurrentValue() const { return it->second; }
void Start() { it = Internal.begin(); }
bool IsAtEnd() const { return it == Internal.end(); }
void Next() { ++it; }
private:
const Scanner::TagToValue& Internal;
Scanner::TagToValue::const_iterator it;
};
#endif /* SWIG */
/**
* \example ScanDirectory.cs
* This is a C# example on how to use Scanner
*/
} // end namespace gdcm
#endif //GDCMSCANNER_H
|