comparison UnitTestsSources/FromDcmtkTests.cpp @ 3765:4a25727401cd transcoding

first transcoding to jpeg 8bpp
author Sebastien Jodogne <s.jodogne@gmail.com>
date Mon, 16 Mar 2020 18:39:23 +0100
parents d55768319f8e
children 711d2ec2db34
comparison
equal deleted inserted replaced
3764:d55768319f8e 3765:4a25727401cd
1920 #include "../Core/DicomParsing/Internals/DicomFrameIndex.h" 1920 #include "../Core/DicomParsing/Internals/DicomFrameIndex.h"
1921 1921
1922 #include <dcmtk/dcmdata/dcostrmb.h> 1922 #include <dcmtk/dcmdata/dcostrmb.h>
1923 #include <dcmtk/dcmdata/dcpixel.h> 1923 #include <dcmtk/dcmdata/dcpixel.h>
1924 #include <dcmtk/dcmdata/dcpxitem.h> 1924 #include <dcmtk/dcmdata/dcpxitem.h>
1925 #include <dcmtk/dcmjpeg/djrploss.h> // for DJ_RPLossy
1926 #include <dcmtk/dcmjpeg/djrplol.h> // for DJ_RPLossless
1925 1927
1926 1928
1927 namespace Orthanc 1929 namespace Orthanc
1928 { 1930 {
1929 class IDicomTranscoder : public boost::noncopyable 1931 class IDicomTranscoder : public boost::noncopyable
1960 std::unique_ptr<DcmFileFormat> dicom_; 1962 std::unique_ptr<DcmFileFormat> dicom_;
1961 std::unique_ptr<DicomFrameIndex> index_; 1963 std::unique_ptr<DicomFrameIndex> index_;
1962 DicomTransferSyntax transferSyntax_; 1964 DicomTransferSyntax transferSyntax_;
1963 std::string sopClassUid_; 1965 std::string sopClassUid_;
1964 std::string sopInstanceUid_; 1966 std::string sopInstanceUid_;
1967 uint16_t bitsStored_;
1968 unsigned int lossyQuality_;
1965 1969
1966 void Setup(DcmFileFormat* dicom) 1970 void Setup(DcmFileFormat* dicom)
1967 { 1971 {
1972 lossyQuality_ = 90;
1973
1968 dicom_.reset(dicom); 1974 dicom_.reset(dicom);
1969 1975
1970 if (dicom == NULL || 1976 if (dicom == NULL ||
1971 dicom_->getDataset() == NULL) 1977 dicom_->getDataset() == NULL)
1972 { 1978 {
1993 throw OrthancException( 1999 throw OrthancException(
1994 ErrorCode_BadFileFormat, 2000 ErrorCode_BadFileFormat,
1995 "Unsupported transfer syntax: " + boost::lexical_cast<std::string>(xfer)); 2001 "Unsupported transfer syntax: " + boost::lexical_cast<std::string>(xfer));
1996 } 2002 }
1997 2003
2004 if (!dataset.findAndGetUint16(DCM_BitsStored, bitsStored_).good())
2005 {
2006 throw OrthancException(ErrorCode_BadFileFormat,
2007 "Missing \"Bits Stored\" tag in DICOM instance");
2008 }
2009
1998 const char* a = NULL; 2010 const char* a = NULL;
1999 const char* b = NULL; 2011 const char* b = NULL;
2000 2012
2001 if (!dataset.findAndGetString(DCM_SOPClassUID, a).good() || 2013 if (!dataset.findAndGetString(DCM_SOPClassUID, a).good() ||
2002 !dataset.findAndGetString(DCM_SOPInstanceUID, b).good() || 2014 !dataset.findAndGetString(DCM_SOPInstanceUID, b).good() ||
2021 size_t size) 2033 size_t size)
2022 { 2034 {
2023 Setup(FromDcmtkBridge::LoadFromMemoryBuffer(dicom, size)); 2035 Setup(FromDcmtkBridge::LoadFromMemoryBuffer(dicom, size));
2024 } 2036 }
2025 2037
2038 void SetLossyQuality(unsigned int quality)
2039 {
2040 if (quality <= 0 ||
2041 quality > 100)
2042 {
2043 throw OrthancException(ErrorCode_ParameterOutOfRange);
2044 }
2045 else
2046 {
2047 lossyQuality_ = quality;
2048 }
2049 }
2050
2051 unsigned int GetLossyQuality() const
2052 {
2053 return lossyQuality_;
2054 }
2055
2056 unsigned int GetBitsStored() const
2057 {
2058 return bitsStored_;
2059 }
2060
2026 virtual DicomTransferSyntax GetTransferSyntax() ORTHANC_OVERRIDE 2061 virtual DicomTransferSyntax GetTransferSyntax() ORTHANC_OVERRIDE
2027 { 2062 {
2028 return transferSyntax_; 2063 return transferSyntax_;
2029 } 2064 }
2030 2065
2066 2101
2067 virtual bool Transcode(std::string& target, 2102 virtual bool Transcode(std::string& target,
2068 std::set<DicomTransferSyntax> syntaxes, 2103 std::set<DicomTransferSyntax> syntaxes,
2069 bool allowNewSopInstanceUid) ORTHANC_OVERRIDE 2104 bool allowNewSopInstanceUid) ORTHANC_OVERRIDE
2070 { 2105 {
2106 if (syntaxes.find(GetTransferSyntax()) != syntaxes.end())
2107 {
2108 printf("NO TRANSCODING\n");
2109
2110 // No change in the transfer syntax => simply serialize the current dataset
2111 WriteToMemoryBuffer(target);
2112 return true;
2113 }
2114
2115 printf(">> %d\n", bitsStored_);
2116
2117 DJ_RPLossy rpLossy(lossyQuality_);
2118
2071 if (syntaxes.find(DicomTransferSyntax_LittleEndianImplicit) != syntaxes.end() && 2119 if (syntaxes.find(DicomTransferSyntax_LittleEndianImplicit) != syntaxes.end() &&
2072 FromDcmtkBridge::Transcode(target, *dicom_, DicomTransferSyntax_LittleEndianImplicit, NULL)) 2120 FromDcmtkBridge::Transcode(target, *dicom_, DicomTransferSyntax_LittleEndianImplicit, NULL))
2073 { 2121 {
2074 return true; 2122 return true;
2075 } 2123 }
2078 { 2126 {
2079 return true; 2127 return true;
2080 } 2128 }
2081 else if (syntaxes.find(DicomTransferSyntax_BigEndianExplicit) != syntaxes.end() && 2129 else if (syntaxes.find(DicomTransferSyntax_BigEndianExplicit) != syntaxes.end() &&
2082 FromDcmtkBridge::Transcode(target, *dicom_, DicomTransferSyntax_BigEndianExplicit, NULL)) 2130 FromDcmtkBridge::Transcode(target, *dicom_, DicomTransferSyntax_BigEndianExplicit, NULL))
2131 {
2132 return true;
2133 }
2134 else if (syntaxes.find(DicomTransferSyntax_JPEGProcess1) != syntaxes.end() &&
2135 FromDcmtkBridge::Transcode(target, *dicom_, DicomTransferSyntax_JPEGProcess1, &rpLossy))
2083 { 2136 {
2084 return true; 2137 return true;
2085 } 2138 }
2086 else 2139 else
2087 { 2140 {
2161 buffer.clear(); 2214 buffer.clear();
2162 return false; 2215 return false;
2163 } 2216 }
2164 } 2217 }
2165 2218
2166 #include "dcmtk/dcmjpeg/djrploss.h" /* for DJ_RPLossy */
2167 #include "dcmtk/dcmjpeg/djrplol.h" /* for DJ_RPLossless */
2168 2219
2169 #include <boost/filesystem.hpp> 2220 #include <boost/filesystem.hpp>
2170 2221
2171 2222
2172 static void TestFile(const std::string& path) 2223 static void TestFile(const std::string& path)
2173 { 2224 {
2225 static unsigned int count = 0;
2226 count++;
2227
2228
2174 printf("** %s\n", path.c_str()); 2229 printf("** %s\n", path.c_str());
2175 2230
2176 std::string s; 2231 std::string s;
2177 SystemToolbox::ReadFile(s, path); 2232 SystemToolbox::ReadFile(s, path);
2178 2233
2179 Orthanc::DcmtkTranscoder transcoder(s.c_str(), s.size()); 2234 Orthanc::DcmtkTranscoder transcoder(s.c_str(), s.size());
2235
2236 if (transcoder.GetBitsStored() != 8) // TODO
2237 return;
2238
2239 {
2240 char buf[1024];
2241 sprintf(buf, "/tmp/source-%06d.dcm", count);
2242 printf(">> %s\n", buf);
2243 Orthanc::SystemToolbox::WriteFile(s, buf);
2244 }
2180 2245
2181 printf("[%s] [%s] [%s] %d %d\n", GetTransferSyntaxUid(transcoder.GetTransferSyntax()), 2246 printf("[%s] [%s] [%s] %d %d\n", GetTransferSyntaxUid(transcoder.GetTransferSyntax()),
2182 transcoder.GetSopClassUid().c_str(), transcoder.GetSopInstanceUid().c_str(), 2247 transcoder.GetSopClassUid().c_str(), transcoder.GetSopInstanceUid().c_str(),
2183 transcoder.GetFramesCount(), transcoder.GetTransferSyntax()); 2248 transcoder.GetFramesCount(), transcoder.GetTransferSyntax());
2184 2249
2187 std::string f; 2252 std::string f;
2188 transcoder.GetCompressedFrame(f, i); 2253 transcoder.GetCompressedFrame(f, i);
2189 2254
2190 if (i == 0) 2255 if (i == 0)
2191 { 2256 {
2192 static unsigned int i = 0;
2193 char buf[1024]; 2257 char buf[1024];
2194 sprintf(buf, "/tmp/frame-%06d.dcm", i++); 2258 sprintf(buf, "/tmp/frame-%06d.raw", count);
2195 printf(">> %s\n", buf); 2259 printf(">> %s\n", buf);
2196 Orthanc::SystemToolbox::WriteFile(f, buf); 2260 Orthanc::SystemToolbox::WriteFile(f, buf);
2197 } 2261 }
2198 } 2262 }
2199 2263
2200 { 2264 {
2201 std::string t; 2265 std::string t;
2202 transcoder.WriteToMemoryBuffer(t); 2266 transcoder.WriteToMemoryBuffer(t);
2203 2267
2204 Orthanc::DcmtkTranscoder transcoder2(t.c_str(), t.size()); 2268 Orthanc::DcmtkTranscoder transcoder2(t.c_str(), t.size());
2205 printf(">> %d %d ; %d bytes\n", transcoder.GetTransferSyntax(), transcoder2.GetTransferSyntax(), t.size()); 2269 printf(">> %d %d ; %lu bytes\n", transcoder.GetTransferSyntax(), transcoder2.GetTransferSyntax(), t.size());
2206 } 2270 }
2207 2271
2208 { 2272 {
2209 std::set<DicomTransferSyntax> syntaxes; 2273 std::set<DicomTransferSyntax> syntaxes;
2210 syntaxes.insert(DicomTransferSyntax_LittleEndianExplicit); 2274 syntaxes.insert(DicomTransferSyntax_JPEGProcess1);
2211 2275
2212 std::string t; 2276 std::string t;
2213 bool ok = transcoder.Transcode(t, syntaxes, false); 2277 bool ok = transcoder.Transcode(t, syntaxes, false);
2214 printf("Transcoding: %d\n", ok); 2278 printf("Transcoding: %d\n", ok);
2215 2279
2216 if (ok) 2280 if (ok)
2217 { 2281 {
2282 {
2283 char buf[1024];
2284 sprintf(buf, "/tmp/transcoded-%06d.dcm", count);
2285 printf(">> %s\n", buf);
2286 Orthanc::SystemToolbox::WriteFile(t, buf);
2287 }
2288
2218 Orthanc::DcmtkTranscoder transcoder2(t.c_str(), t.size()); 2289 Orthanc::DcmtkTranscoder transcoder2(t.c_str(), t.size());
2219 printf(" => transcoded transfer syntax %d ; %d bytes\n", transcoder2.GetTransferSyntax(), t.size()); 2290 printf(" => transcoded transfer syntax %d ; %lu bytes\n", transcoder2.GetTransferSyntax(), t.size());
2220 } 2291 }
2221 } 2292 }
2222 2293
2223 printf("\n"); 2294 printf("\n");
2224 } 2295 }
2225 2296
2226 TEST(Toto, DISABLED_Transcode) 2297 TEST(Toto, DISABLED_Transcode)
2227 { 2298 {
2299 //OFLog::configure(OFLogger::DEBUG_LOG_LEVEL);
2300
2228 if (0) 2301 if (0)
2229 { 2302 {
2230 OFLog::configure(OFLogger::DEBUG_LOG_LEVEL);
2231
2232 std::string s; 2303 std::string s;
2233 //SystemToolbox::ReadFile(s, "/home/jodogne/Subversion/orthanc-tests/Database/TransferSyntaxes/1.2.840.10008.1.2.4.50.dcm"); 2304 //SystemToolbox::ReadFile(s, "/home/jodogne/Subversion/orthanc-tests/Database/TransferSyntaxes/1.2.840.10008.1.2.4.50.dcm");
2234 //SystemToolbox::ReadFile(s, "/home/jodogne/DICOM/Alain.dcm"); 2305 //SystemToolbox::ReadFile(s, "/home/jodogne/DICOM/Alain.dcm");
2235 SystemToolbox::ReadFile(s, "/home/jodogne/Subversion/orthanc-tests/Database/Brainix/Epi/IM-0001-0002.dcm"); 2306 SystemToolbox::ReadFile(s, "/home/jodogne/Subversion/orthanc-tests/Database/Brainix/Epi/IM-0001-0002.dcm");
2236 2307
2274 if (boost::filesystem::is_regular_file(it->status())) 2345 if (boost::filesystem::is_regular_file(it->status()))
2275 { 2346 {
2276 TestFile(it->path().string()); 2347 TestFile(it->path().string());
2277 } 2348 }
2278 } 2349 }
2279 2350 }
2351
2352 if (0)
2353 {
2280 TestFile("/home/jodogne/Subversion/orthanc-tests/Database/Multiframe.dcm"); 2354 TestFile("/home/jodogne/Subversion/orthanc-tests/Database/Multiframe.dcm");
2281 TestFile("/home/jodogne/Subversion/orthanc-tests/Database/Issue44/Monochrome1-Jpeg.dcm"); 2355 TestFile("/home/jodogne/Subversion/orthanc-tests/Database/Issue44/Monochrome1-Jpeg.dcm");
2282 } 2356 }
2357
2358 if (0)
2359 {
2360 TestFile("/home/jodogne/Subversion/orthanc-tests/Database/TransferSyntaxes/1.2.840.10008.1.2.1.dcm");
2361 }
2283 } 2362 }
2284 2363
2285 #endif 2364 #endif