Mercurial > hg > orthanc
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, |