comparison OrthancServer/Sources/ServerContext.cpp @ 5747:796cb17db15c find-refactoring

merged default -> find-refactoring
author Alain Mazy <am@orthanc.team>
date Mon, 02 Sep 2024 17:17:22 +0200
parents 2b05428843d2 8bb3f2fca242
children f75596b224e0 23b5a090a64b
comparison
equal deleted inserted replaced
5725:95a3802ad133 5747:796cb17db15c
1345 accessor_.reset(NULL); 1345 accessor_.reset(NULL);
1346 1346
1347 // Throttle to avoid loading several large DICOM files simultaneously 1347 // Throttle to avoid loading several large DICOM files simultaneously
1348 largeDicomLocker_.reset(new Semaphore::Locker(context.largeDicomThrottler_)); 1348 largeDicomLocker_.reset(new Semaphore::Locker(context.largeDicomThrottler_));
1349 1349
1350 std::string content; 1350 context_.ReadDicom(buffer_, instancePublicId_);
1351 context_.ReadDicom(content, instancePublicId);
1352 1351
1353 // Release the throttle if loading "small" DICOM files (under 1352 // Release the throttle if loading "small" DICOM files (under
1354 // 50MB, which is an arbitrary value) 1353 // 50MB, which is an arbitrary value)
1355 if (content.size() < 50 * 1024 * 1024) 1354 if (buffer_.size() < 50 * 1024 * 1024)
1356 { 1355 {
1357 largeDicomLocker_.reset(NULL); 1356 largeDicomLocker_.reset(NULL);
1358 } 1357 }
1359 1358
1360 dicom_.reset(new ParsedDicomFile(content)); 1359 dicom_.reset(new ParsedDicomFile(buffer_));
1361 dicomSize_ = content.size(); 1360 dicomSize_ = buffer_.size();
1362 } 1361 }
1363 1362
1364 assert(accessor_.get() != NULL || 1363 assert(accessor_.get() != NULL ||
1365 dicom_.get() != NULL); 1364 dicom_.get() != NULL);
1366 } 1365 }
1392 assert(accessor_.get() != NULL); 1391 assert(accessor_.get() != NULL);
1393 return accessor_->GetDicom(); 1392 return accessor_->GetDicom();
1394 } 1393 }
1395 } 1394 }
1396 1395
1396 const std::string& ServerContext::DicomCacheLocker::GetBuffer()
1397 {
1398 if (buffer_.size() > 0)
1399 {
1400 return buffer_;
1401 }
1402 else
1403 {
1404 context_.ReadDicom(buffer_, instancePublicId_);
1405 return buffer_;
1406 }
1407 }
1397 1408
1398 void ServerContext::SetStoreMD5ForAttachments(bool storeMD5) 1409 void ServerContext::SetStoreMD5ForAttachments(bool storeMD5)
1399 { 1410 {
1400 LOG(INFO) << "Storing MD5 for attachments: " << (storeMD5 ? "yes" : "no"); 1411 LOG(INFO) << "Storing MD5 for attachments: " << (storeMD5 ? "yes" : "no");
1401 storeMD5_ = storeMD5; 1412 storeMD5_ = storeMD5;
1843 1854
1844 return NULL; 1855 return NULL;
1845 } 1856 }
1846 1857
1847 1858
1859
1860
1861
1848 ImageAccessor* ServerContext::DecodeDicomFrame(const std::string& publicId, 1862 ImageAccessor* ServerContext::DecodeDicomFrame(const std::string& publicId,
1849 unsigned int frameIndex) 1863 unsigned int frameIndex)
1850 { 1864 {
1865 ServerContext::DicomCacheLocker locker(*this, publicId);
1866 std::unique_ptr<ImageAccessor> decoded(DecodeDicomFrame(locker.GetDicom(), locker.GetBuffer().c_str(), locker.GetBuffer().size(), frameIndex));
1867
1868 if (decoded.get() == NULL)
1869 {
1870 OrthancConfiguration::ReaderLock configLock;
1871 if (configLock.GetConfiguration().IsWarningEnabled(Warnings_003_DecoderFailure))
1872 {
1873 LOG(WARNING) << "W003: Unable to decode frame " << frameIndex << " from instance " << publicId;
1874 }
1875 return NULL;
1876 }
1877
1878 return decoded.release();
1879 }
1880
1881
1882 ImageAccessor* ServerContext::DecodeDicomFrame(const ParsedDicomFile& parsedDicom,
1883 const void* buffer, // actually the buffer that is the source of the ParsedDicomFile
1884 size_t size,
1885 unsigned int frameIndex)
1886 {
1887 std::unique_ptr<ImageAccessor> decoded;
1888
1851 if (builtinDecoderTranscoderOrder_ == BuiltinDecoderTranscoderOrder_Before) 1889 if (builtinDecoderTranscoderOrder_ == BuiltinDecoderTranscoderOrder_Before)
1852 { 1890 {
1853 // Use Orthanc's built-in decoder, using the cache to speed-up 1891 // Use Orthanc's built-in decoder
1854 // things on multi-frame images 1892
1855
1856 std::unique_ptr<ImageAccessor> decoded;
1857 try 1893 try
1858 { 1894 {
1859 ServerContext::DicomCacheLocker locker(*this, publicId); 1895 decoded.reset(parsedDicom.DecodeFrame(frameIndex));
1860 decoded.reset(locker.GetDicom().DecodeFrame(frameIndex)); 1896 if (decoded.get() != NULL)
1897 {
1898 return decoded.release();
1899 }
1861 } 1900 }
1862 catch (OrthancException& e) 1901 catch (OrthancException& e)
1863 { 1902 { // ignore, we'll try other alternatives
1864 }
1865
1866 if (decoded.get() != NULL)
1867 {
1868 return decoded.release();
1869 } 1903 }
1870 } 1904 }
1871 1905
1872 #if ORTHANC_ENABLE_PLUGINS == 1 1906 #if ORTHANC_ENABLE_PLUGINS == 1
1873 if (HasPlugins() && 1907 if (HasPlugins() &&
1874 GetPlugins().HasCustomImageDecoder()) 1908 GetPlugins().HasCustomImageDecoder())
1875 { 1909 {
1876 // TODO: Store the raw buffer in the DicomCacheLocker
1877 std::string dicomContent;
1878 ReadDicom(dicomContent, publicId);
1879
1880 std::unique_ptr<ImageAccessor> decoded;
1881 try 1910 try
1882 { 1911 {
1883 decoded.reset(GetPlugins().Decode(dicomContent.c_str(), dicomContent.size(), frameIndex)); 1912 decoded.reset(GetPlugins().Decode(buffer, size, frameIndex));
1884 } 1913 }
1885 catch (OrthancException& e) 1914 catch (OrthancException& e)
1886 { 1915 {
1887 } 1916 }
1888 1917
1898 } 1927 }
1899 #endif 1928 #endif
1900 1929
1901 if (builtinDecoderTranscoderOrder_ == BuiltinDecoderTranscoderOrder_After) 1930 if (builtinDecoderTranscoderOrder_ == BuiltinDecoderTranscoderOrder_After)
1902 { 1931 {
1903 ServerContext::DicomCacheLocker locker(*this, publicId); 1932 try
1904 return locker.GetDicom().DecodeFrame(frameIndex); 1933 {
1905 } 1934 decoded.reset(parsedDicom.DecodeFrame(frameIndex));
1906 else 1935 if (decoded.get() != NULL)
1907 { 1936 {
1908 return NULL; // Built-in decoder is disabled 1937 return decoded.release();
1909 } 1938 }
1939 }
1940 catch (OrthancException& e)
1941 {
1942 LOG(INFO) << e.GetDetails();
1943 }
1944 }
1945
1946 if (HasPlugins() && GetPlugins().HasCustomTranscoder())
1947 {
1948 LOG(INFO) << "The plugins and built-in image decoders failed to decode a frame, "
1949 << "trying to transcode the file to LittleEndianExplicit using the plugins.";
1950 DicomImage explicitTemporaryImage;
1951 DicomImage source;
1952 std::set<DicomTransferSyntax> allowedSyntaxes;
1953
1954 source.SetExternalBuffer(buffer, size);
1955 allowedSyntaxes.insert(DicomTransferSyntax_LittleEndianExplicit);
1956
1957 if (Transcode(explicitTemporaryImage, source, allowedSyntaxes, true))
1958 {
1959 std::unique_ptr<ParsedDicomFile> file(explicitTemporaryImage.ReleaseAsParsedDicomFile());
1960 return file->DecodeFrame(frameIndex);
1961 }
1962 }
1963
1964 return NULL;
1910 } 1965 }
1911 1966
1912 1967
1913 ImageAccessor* ServerContext::DecodeDicomFrame(const DicomInstanceToStore& dicom, 1968 ImageAccessor* ServerContext::DecodeDicomFrame(const DicomInstanceToStore& dicom,
1914 unsigned int frameIndex) 1969 unsigned int frameIndex)
1915 { 1970 {
1916 if (builtinDecoderTranscoderOrder_ == BuiltinDecoderTranscoderOrder_Before) 1971 return DecodeDicomFrame(dicom.GetParsedDicomFile(),
1917 { 1972 dicom.GetBufferData(),
1918 std::unique_ptr<ImageAccessor> decoded; 1973 dicom.GetBufferSize(),
1919 try 1974 frameIndex);
1920 { 1975
1921 decoded.reset(dicom.DecodeFrame(frameIndex));
1922 }
1923 catch (OrthancException& e)
1924 {
1925 }
1926
1927 if (decoded.get() != NULL)
1928 {
1929 return decoded.release();
1930 }
1931 }
1932
1933 #if ORTHANC_ENABLE_PLUGINS == 1
1934 if (HasPlugins() &&
1935 GetPlugins().HasCustomImageDecoder())
1936 {
1937 std::unique_ptr<ImageAccessor> decoded;
1938 try
1939 {
1940 decoded.reset(GetPlugins().Decode(dicom.GetBufferData(), dicom.GetBufferSize(), frameIndex));
1941 }
1942 catch (OrthancException& e)
1943 {
1944 }
1945
1946 if (decoded.get() != NULL)
1947 {
1948 return decoded.release();
1949 }
1950 else if (builtinDecoderTranscoderOrder_ == BuiltinDecoderTranscoderOrder_After)
1951 {
1952 LOG(INFO) << "The installed image decoding plugins cannot handle an image, "
1953 << "fallback to the built-in DCMTK decoder";
1954 }
1955 }
1956 #endif
1957
1958 if (builtinDecoderTranscoderOrder_ == BuiltinDecoderTranscoderOrder_After)
1959 {
1960 return dicom.DecodeFrame(frameIndex);
1961 }
1962 else
1963 {
1964 return NULL;
1965 }
1966 } 1976 }
1967 1977
1968 1978
1969 ImageAccessor* ServerContext::DecodeDicomFrame(const void* dicom, 1979 ImageAccessor* ServerContext::DecodeDicomFrame(const void* dicom,
1970 size_t size, 1980 size_t size,
1971 unsigned int frameIndex) 1981 unsigned int frameIndex)
1972 { 1982 {
1973 std::unique_ptr<DicomInstanceToStore> instance(DicomInstanceToStore::CreateFromBuffer(dicom, size)); 1983 std::unique_ptr<ParsedDicomFile> instance(new ParsedDicomFile(dicom, size));
1974 return DecodeDicomFrame(*instance, frameIndex); 1984 return DecodeDicomFrame(*instance, dicom, size, frameIndex);
1975 } 1985 }
1976 1986
1977 1987
1978 void ServerContext::StoreWithTranscoding(std::string& sopClassUid, 1988 void ServerContext::StoreWithTranscoding(std::string& sopClassUid,
1979 std::string& sopInstanceUid, 1989 std::string& sopInstanceUid,