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,