44
55#include < gtest/gtest.h>
66
7+ #include < fstream>
78#include < vector>
89
910#include " dcmtk/dcmdata/dcdeftag.h"
@@ -23,6 +24,83 @@ struct TestLogConfig {
2324
2425static TestLogConfig g_testLogConfig;
2526
27+ void PopulateDatasetWithRequiredAttributes (
28+ DcmDataset *dataset, Uint16 rows, Uint16 cols, Uint16 bitsAllocated,
29+ Uint16 samplesPerPixel, OFString const &photometricInterpretation,
30+ Uint16 pixelRepresentation) {
31+ // Required image attributes
32+ ASSERT_TRUE (dataset->putAndInsertUint16 (DCM_Rows, rows).good ());
33+ ASSERT_TRUE (dataset->putAndInsertUint16 (DCM_Columns, cols).good ());
34+ ASSERT_TRUE (
35+ dataset->putAndInsertUint16 (DCM_SamplesPerPixel, samplesPerPixel).good ());
36+ ASSERT_TRUE (dataset
37+ ->putAndInsertString (DCM_PhotometricInterpretation,
38+ photometricInterpretation.c_str ())
39+ .good ());
40+ ASSERT_TRUE (
41+ dataset->putAndInsertUint16 (DCM_BitsAllocated, bitsAllocated).good ());
42+ ASSERT_TRUE (
43+ dataset->putAndInsertUint16 (DCM_BitsStored, bitsAllocated).good ());
44+ ASSERT_TRUE (
45+ dataset->putAndInsertUint16 (DCM_HighBit, bitsAllocated - 1 ).good ());
46+ ASSERT_TRUE (
47+ dataset->putAndInsertUint16 (DCM_PixelRepresentation, pixelRepresentation)
48+ .good ());
49+
50+ // Minimal required UIDs
51+ char studyUid[100 ];
52+ char seriesUid[100 ];
53+ char instanceUid[100 ];
54+ dcmGenerateUniqueIdentifier (studyUid, SITE_STUDY_UID_ROOT);
55+ dcmGenerateUniqueIdentifier (seriesUid, SITE_SERIES_UID_ROOT);
56+ dcmGenerateUniqueIdentifier (instanceUid, SITE_INSTANCE_UID_ROOT);
57+
58+ ASSERT_TRUE (dataset
59+ ->putAndInsertString (DCM_SOPClassUID,
60+ UID_SecondaryCaptureImageStorage)
61+ .good ());
62+ ASSERT_TRUE (
63+ dataset->putAndInsertString (DCM_StudyInstanceUID, studyUid).good ());
64+ ASSERT_TRUE (
65+ dataset->putAndInsertString (DCM_SeriesInstanceUID, seriesUid).good ());
66+ ASSERT_TRUE (
67+ dataset->putAndInsertString (DCM_SOPInstanceUID, instanceUid).good ());
68+ }
69+
70+ void VerifyProgressionOrder (OFTempFile const &tmpFile,
71+ unsigned char const expectedProgressionOrder) {
72+ // Open temp file in a buffer
73+ std::ifstream input (tmpFile.getFilename (), std::ios::binary);
74+ // Scan for JPEG 2000 COD marker (0xFF52)
75+ bool foundCodMarker = false ;
76+ char byte1, byte2;
77+ if (input.get (byte1)) {
78+ while (input.get (byte2)) {
79+ if (static_cast <unsigned char >(byte1) == 0xFF &&
80+ static_cast <unsigned char >(byte2) == 0x52 ) {
81+ foundCodMarker = true ;
82+ break ;
83+ }
84+ byte1 = byte2;
85+ }
86+ }
87+ ASSERT_TRUE (foundCodMarker);
88+ // Get COD marker length (2 bytes after COD marker)
89+ char codLength[2 ];
90+ // COD segment length
91+ ASSERT_TRUE (input.read (codLength, 2 ));
92+ // COD coding style default (1 byte after COD marker)
93+ char codingStyleDefault;
94+ ASSERT_TRUE (input.read (&codingStyleDefault, 1 ));
95+ // COD progression order (1 byte after coding style default)
96+ char progressionOrder;
97+ ASSERT_TRUE (input.read (&progressionOrder, 1 ));
98+ // Verify progression order
99+ ASSERT_TRUE (progressionOrder == expectedProgressionOrder);
100+
101+ input.close ();
102+ }
103+
26104TEST (BasicTest, FrameworkWorks) {
27105 EXPECT_EQ (1 + 1 , 2 );
28106 EXPECT_TRUE (true );
@@ -59,36 +137,9 @@ TEST(CodecTest, BasicMonochrome8BitUnsignedCompressDecompressLossless) {
59137 DcmFileFormat fileformat;
60138 DcmDataset *dataset = fileformat.getDataset ();
61139
62- // Required image attributes
63- ASSERT_TRUE (dataset->putAndInsertUint16 (DCM_Rows, rows).good ());
64- ASSERT_TRUE (dataset->putAndInsertUint16 (DCM_Columns, cols).good ());
65- ASSERT_TRUE (dataset->putAndInsertUint16 (DCM_SamplesPerPixel, 1 ).good ());
66- ASSERT_TRUE (
67- dataset->putAndInsertString (DCM_PhotometricInterpretation, " MONOCHROME2" )
68- .good ());
69- ASSERT_TRUE (dataset->putAndInsertUint16 (DCM_BitsAllocated, 8 ).good ());
70- ASSERT_TRUE (dataset->putAndInsertUint16 (DCM_BitsStored, 8 ).good ());
71- ASSERT_TRUE (dataset->putAndInsertUint16 (DCM_HighBit, 7 ).good ());
72- ASSERT_TRUE (dataset->putAndInsertUint16 (DCM_PixelRepresentation, 0 ).good ());
73-
74- // Minimal required UIDs
75- char studyUid[100 ];
76- char seriesUid[100 ];
77- char instanceUid[100 ];
78- dcmGenerateUniqueIdentifier (studyUid, SITE_STUDY_UID_ROOT);
79- dcmGenerateUniqueIdentifier (seriesUid, SITE_SERIES_UID_ROOT);
80- dcmGenerateUniqueIdentifier (instanceUid, SITE_INSTANCE_UID_ROOT);
81-
82- ASSERT_TRUE (dataset
83- ->putAndInsertString (DCM_SOPClassUID,
84- UID_SecondaryCaptureImageStorage)
85- .good ());
86- ASSERT_TRUE (
87- dataset->putAndInsertString (DCM_StudyInstanceUID, studyUid).good ());
88- ASSERT_TRUE (
89- dataset->putAndInsertString (DCM_SeriesInstanceUID, seriesUid).good ());
90- ASSERT_TRUE (
91- dataset->putAndInsertString (DCM_SOPInstanceUID, instanceUid).good ());
140+ // Populate dataset for an 8-bit monochrome image
141+ PopulateDatasetWithRequiredAttributes (dataset, rows, cols, 8 , 1 ,
142+ " MONOCHROME2" , 0 );
92143
93144 // Pixel data
94145 ASSERT_TRUE (
@@ -101,7 +152,8 @@ TEST(CodecTest, BasicMonochrome8BitUnsignedCompressDecompressLossless) {
101152 HtJ2kEncoderRegistration::registerCodecs ();
102153 HtJ2kDecoderRegistration::registerCodecs ();
103154
104- const E_TransferSyntax htj2kLossless = EXS_HighThroughputJPEG2000LosslessOnly;
155+ const E_TransferSyntax htj2kLossless =
156+ EXS_HighThroughputJPEG2000withRPCLOptionsLosslessOnly;
105157 ASSERT_TRUE (dataset->chooseRepresentation (htj2kLossless, nullptr ).good ());
106158 ASSERT_TRUE (dataset->canWriteXfer (htj2kLossless));
107159
@@ -111,6 +163,9 @@ TEST(CodecTest, BasicMonochrome8BitUnsignedCompressDecompressLossless) {
111163 ASSERT_TRUE (
112164 fileformat.saveFile (tempFile.getFilename (), htj2kLossless).good ());
113165
166+ // RPCL progression order [0x02]
167+ VerifyProgressionOrder (tempFile, 0x02 );
168+
114169 // Read back
115170 DcmFileFormat readFile;
116171 ASSERT_TRUE (readFile.loadFile (tempFile.getFilename ()).good ());
@@ -156,36 +211,9 @@ TEST(CodecTest, BasicMonochrome16BitUnsignedCompressDecompressLossless) {
156211 DcmFileFormat fileformat;
157212 DcmDataset *dataset = fileformat.getDataset ();
158213
159- // Required image attributes
160- ASSERT_TRUE (dataset->putAndInsertUint16 (DCM_Rows, rows).good ());
161- ASSERT_TRUE (dataset->putAndInsertUint16 (DCM_Columns, cols).good ());
162- ASSERT_TRUE (dataset->putAndInsertUint16 (DCM_SamplesPerPixel, 1 ).good ());
163- ASSERT_TRUE (
164- dataset->putAndInsertString (DCM_PhotometricInterpretation, " MONOCHROME2" )
165- .good ());
166- ASSERT_TRUE (dataset->putAndInsertUint16 (DCM_BitsAllocated, 16 ).good ());
167- ASSERT_TRUE (dataset->putAndInsertUint16 (DCM_BitsStored, 16 ).good ());
168- ASSERT_TRUE (dataset->putAndInsertUint16 (DCM_HighBit, 15 ).good ());
169- ASSERT_TRUE (dataset->putAndInsertUint16 (DCM_PixelRepresentation, 0 ).good ());
170-
171- // Minimal required UIDs
172- char studyUid[100 ];
173- char seriesUid[100 ];
174- char instanceUid[100 ];
175- dcmGenerateUniqueIdentifier (studyUid, SITE_STUDY_UID_ROOT);
176- dcmGenerateUniqueIdentifier (seriesUid, SITE_SERIES_UID_ROOT);
177- dcmGenerateUniqueIdentifier (instanceUid, SITE_INSTANCE_UID_ROOT);
178-
179- ASSERT_TRUE (dataset
180- ->putAndInsertString (DCM_SOPClassUID,
181- UID_SecondaryCaptureImageStorage)
182- .good ());
183- ASSERT_TRUE (
184- dataset->putAndInsertString (DCM_StudyInstanceUID, studyUid).good ());
185- ASSERT_TRUE (
186- dataset->putAndInsertString (DCM_SeriesInstanceUID, seriesUid).good ());
187- ASSERT_TRUE (
188- dataset->putAndInsertString (DCM_SOPInstanceUID, instanceUid).good ());
214+ // Populate dataset for an 16-bit unsigned monochrome image
215+ PopulateDatasetWithRequiredAttributes (dataset, rows, cols, 16 , 1 ,
216+ " MONOCHROME2" , 0 );
189217
190218 // Pixel data
191219 ASSERT_TRUE (
@@ -208,6 +236,9 @@ TEST(CodecTest, BasicMonochrome16BitUnsignedCompressDecompressLossless) {
208236 ASSERT_TRUE (
209237 fileformat.saveFile (tempFile.getFilename (), htj2kLossless).good ());
210238
239+ // Default LRCP progression order [0x00]
240+ VerifyProgressionOrder (tempFile, 0x00 );
241+
211242 // Read back
212243 DcmFileFormat readFile;
213244 ASSERT_TRUE (readFile.loadFile (tempFile.getFilename ()).good ());
@@ -257,36 +288,9 @@ TEST(CodecTest, BasicMonochrome16BitSignedCompressDecompressLossless) {
257288 DcmFileFormat fileformat;
258289 DcmDataset *dataset = fileformat.getDataset ();
259290
260- // Required image attributes
261- ASSERT_TRUE (dataset->putAndInsertUint16 (DCM_Rows, rows).good ());
262- ASSERT_TRUE (dataset->putAndInsertUint16 (DCM_Columns, cols).good ());
263- ASSERT_TRUE (dataset->putAndInsertUint16 (DCM_SamplesPerPixel, 1 ).good ());
264- ASSERT_TRUE (
265- dataset->putAndInsertString (DCM_PhotometricInterpretation, " MONOCHROME2" )
266- .good ());
267- ASSERT_TRUE (dataset->putAndInsertUint16 (DCM_BitsAllocated, 16 ).good ());
268- ASSERT_TRUE (dataset->putAndInsertUint16 (DCM_BitsStored, 16 ).good ());
269- ASSERT_TRUE (dataset->putAndInsertUint16 (DCM_HighBit, 15 ).good ());
270- ASSERT_TRUE (dataset->putAndInsertUint16 (DCM_PixelRepresentation, 1 ).good ());
271-
272- // Minimal required UIDs
273- char studyUid[100 ];
274- char seriesUid[100 ];
275- char instanceUid[100 ];
276- dcmGenerateUniqueIdentifier (studyUid, SITE_STUDY_UID_ROOT);
277- dcmGenerateUniqueIdentifier (seriesUid, SITE_SERIES_UID_ROOT);
278- dcmGenerateUniqueIdentifier (instanceUid, SITE_INSTANCE_UID_ROOT);
279-
280- ASSERT_TRUE (dataset
281- ->putAndInsertString (DCM_SOPClassUID,
282- UID_SecondaryCaptureImageStorage)
283- .good ());
284- ASSERT_TRUE (
285- dataset->putAndInsertString (DCM_StudyInstanceUID, studyUid).good ());
286- ASSERT_TRUE (
287- dataset->putAndInsertString (DCM_SeriesInstanceUID, seriesUid).good ());
288- ASSERT_TRUE (
289- dataset->putAndInsertString (DCM_SOPInstanceUID, instanceUid).good ());
291+ // Populate dataset for an 16-bit signed monochrome image
292+ PopulateDatasetWithRequiredAttributes (dataset, rows, cols, 16 , 1 ,
293+ " MONOCHROME2" , 1 );
290294
291295 // Pixel data
292296 ASSERT_TRUE (
@@ -358,37 +362,9 @@ TEST(CodecTest, BasicColorCompressDecompressLossless) {
358362 DcmFileFormat fileformat;
359363 DcmDataset *dataset = fileformat.getDataset ();
360364
361- // Required image attributes
362- ASSERT_TRUE (dataset->putAndInsertUint16 (DCM_Rows, rows).good ());
363- ASSERT_TRUE (dataset->putAndInsertUint16 (DCM_Columns, cols).good ());
364- ASSERT_TRUE (
365- dataset->putAndInsertUint16 (DCM_SamplesPerPixel, samplesPerPixel).good ());
366- ASSERT_TRUE (
367- dataset->putAndInsertString (DCM_PhotometricInterpretation, " RGB" ).good ());
365+ // Populate dataset for an 8-bit color image
366+ PopulateDatasetWithRequiredAttributes (dataset, rows, cols, 8 , 3 , " RGB" , 0 );
368367 ASSERT_TRUE (dataset->putAndInsertUint16 (DCM_PlanarConfiguration, 0 ).good ());
369- ASSERT_TRUE (dataset->putAndInsertUint16 (DCM_BitsAllocated, 8 ).good ());
370- ASSERT_TRUE (dataset->putAndInsertUint16 (DCM_BitsStored, 8 ).good ());
371- ASSERT_TRUE (dataset->putAndInsertUint16 (DCM_HighBit, 7 ).good ());
372- ASSERT_TRUE (dataset->putAndInsertUint16 (DCM_PixelRepresentation, 0 ).good ());
373-
374- // Minimal required UIDs
375- char studyUid[100 ];
376- char seriesUid[100 ];
377- char instanceUid[100 ];
378- dcmGenerateUniqueIdentifier (studyUid, SITE_STUDY_UID_ROOT);
379- dcmGenerateUniqueIdentifier (seriesUid, SITE_SERIES_UID_ROOT);
380- dcmGenerateUniqueIdentifier (instanceUid, SITE_INSTANCE_UID_ROOT);
381-
382- ASSERT_TRUE (dataset
383- ->putAndInsertString (DCM_SOPClassUID,
384- UID_SecondaryCaptureImageStorage)
385- .good ());
386- ASSERT_TRUE (
387- dataset->putAndInsertString (DCM_StudyInstanceUID, studyUid).good ());
388- ASSERT_TRUE (
389- dataset->putAndInsertString (DCM_SeriesInstanceUID, seriesUid).good ());
390- ASSERT_TRUE (
391- dataset->putAndInsertString (DCM_SOPInstanceUID, instanceUid).good ());
392368
393369 // Pixel data
394370 ASSERT_TRUE (
0 commit comments