Mercurial > hg > orthanc
comparison OrthancFramework/Sources/DicomParsing/ParsedDicomFile.cpp @ 4945:6a59dc426f93
added ParsedDicomFile::DecodeOverlay()
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Sun, 20 Mar 2022 11:35:17 +0100 |
parents | 45d6ce72a84e |
children | dfbe764995cf |
comparison
equal
deleted
inserted
replaced
4943:47d734fa30f6 | 4945:6a59dc426f93 |
---|---|
74 #include "FromDcmtkBridge.h" | 74 #include "FromDcmtkBridge.h" |
75 #include "Internals/DicomFrameIndex.h" | 75 #include "Internals/DicomFrameIndex.h" |
76 #include "Internals/DicomImageDecoder.h" | 76 #include "Internals/DicomImageDecoder.h" |
77 #include "ToDcmtkBridge.h" | 77 #include "ToDcmtkBridge.h" |
78 | 78 |
79 #include "../Images/Image.h" | |
80 #include "../Images/ImageProcessing.h" | |
79 #include "../Images/PamReader.h" | 81 #include "../Images/PamReader.h" |
80 #include "../Logging.h" | 82 #include "../Logging.h" |
81 #include "../OrthancException.h" | 83 #include "../OrthancException.h" |
82 #include "../SerializationToolbox.h" | 84 #include "../SerializationToolbox.h" |
83 #include "../Toolbox.h" | 85 #include "../Toolbox.h" |
1916 rescaleSlope = 1; | 1918 rescaleSlope = 1; |
1917 } | 1919 } |
1918 } | 1920 } |
1919 | 1921 |
1920 | 1922 |
1923 void ParsedDicomFile::ListOverlays(std::set<unsigned int>& groups) const | |
1924 { | |
1925 DcmDataset& dataset = *const_cast<ParsedDicomFile&>(*this).GetDcmtkObject().getDataset(); | |
1926 | |
1927 // "Repeating Groups shall only be allowed in the even Groups (6000-601E,eeee)" | |
1928 // https://dicom.nema.org/medical/dicom/2021e/output/chtml/part05/sect_7.6.html | |
1929 | |
1930 for (uint16_t group = 0x6000; group <= 0x601e; group += 2) | |
1931 { | |
1932 if (dataset.tagExists(DcmTagKey(group, 0x0010))) | |
1933 { | |
1934 groups.insert(group); | |
1935 } | |
1936 } | |
1937 } | |
1938 | |
1939 | |
1940 static unsigned int Ceiling(unsigned int a, | |
1941 unsigned int b) | |
1942 { | |
1943 if (a % b == 0) | |
1944 { | |
1945 return a / b; | |
1946 } | |
1947 else | |
1948 { | |
1949 return a / b + 1; | |
1950 } | |
1951 } | |
1952 | |
1953 | |
1954 ImageAccessor* ParsedDicomFile::DecodeOverlay(int& originX, | |
1955 int& originY, | |
1956 unsigned int group) const | |
1957 { | |
1958 // https://dicom.nema.org/medical/dicom/current/output/chtml/part03/sect_C.9.2.html | |
1959 | |
1960 DcmDataset& dataset = *const_cast<ParsedDicomFile&>(*this).GetDcmtkObject().getDataset(); | |
1961 | |
1962 Uint16 rows, columns, bitsAllocated, bitPosition; | |
1963 const Sint16* origin = NULL; | |
1964 unsigned long originSize = 0; | |
1965 const Uint8* overlayData = NULL; | |
1966 unsigned long overlaySize = 0; | |
1967 | |
1968 if (dataset.findAndGetUint16(DcmTagKey(group, 0x0010), rows).good() && | |
1969 dataset.findAndGetUint16(DcmTagKey(group, 0x0011), columns).good() && | |
1970 dataset.findAndGetSint16Array(DcmTagKey(group, 0x0050), origin, &originSize).good() && | |
1971 origin != NULL && | |
1972 originSize == 2 && | |
1973 dataset.findAndGetUint16(DcmTagKey(group, 0x0100), bitsAllocated).good() && | |
1974 bitsAllocated == 1 && | |
1975 dataset.findAndGetUint16(DcmTagKey(group, 0x0102), bitPosition).good() && | |
1976 bitPosition == 0 && | |
1977 dataset.findAndGetUint8Array(DcmTagKey(group, 0x3000), overlayData, &overlaySize).good() && | |
1978 overlayData != NULL) | |
1979 { | |
1980 unsigned int expectedSize = Ceiling(rows * columns, 8); | |
1981 if (overlaySize < expectedSize) | |
1982 { | |
1983 throw OrthancException(ErrorCode_CorruptedFile, "Overlay doesn't have a valid number of bits"); | |
1984 } | |
1985 | |
1986 originX = origin[1]; | |
1987 originY = origin[0]; | |
1988 | |
1989 std::unique_ptr<ImageAccessor> overlay(new Image(Orthanc::PixelFormat_Grayscale8, columns, rows, false)); | |
1990 | |
1991 unsigned int posBit = 0; | |
1992 for (int y = 0; y < rows; y++) | |
1993 { | |
1994 uint8_t* target = reinterpret_cast<uint8_t*>(overlay->GetRow(y)); | |
1995 | |
1996 for (int x = 0; x < columns; x++) | |
1997 { | |
1998 uint8_t source = overlayData[posBit / 8]; | |
1999 uint8_t mask = 1 << (posBit % 8); | |
2000 | |
2001 *target = ((source & mask) ? 255 : 0); | |
2002 | |
2003 target++; | |
2004 posBit++; | |
2005 } | |
2006 } | |
2007 | |
2008 return overlay.release(); | |
2009 } | |
2010 else | |
2011 { | |
2012 throw OrthancException(ErrorCode_CorruptedFile, "Invalid overlay"); | |
2013 } | |
2014 } | |
2015 | |
2016 | |
1921 #if ORTHANC_BUILDING_FRAMEWORK_LIBRARY == 1 | 2017 #if ORTHANC_BUILDING_FRAMEWORK_LIBRARY == 1 |
1922 // Alias for binary compatibility with Orthanc Framework 1.7.2 => don't use it anymore | 2018 // Alias for binary compatibility with Orthanc Framework 1.7.2 => don't use it anymore |
1923 void ParsedDicomFile::DatasetToJson(Json::Value& target, | 2019 void ParsedDicomFile::DatasetToJson(Json::Value& target, |
1924 DicomToJsonFormat format, | 2020 DicomToJsonFormat format, |
1925 DicomToJsonFlags flags, | 2021 DicomToJsonFlags flags, |