1 /* 2 * 3 * Copyright (C) 1996-2018, OFFIS e.V. 4 * All rights reserved. See COPYRIGHT file for details. 5 * 6 * This software and supporting documentation were developed by 7 * 8 * OFFIS e.V. 9 * R&D Division Health 10 * Escherweg 2 11 * D-26121 Oldenburg, Germany 12 * 13 * 14 * Module: dcmimgle 15 * 16 * Author: Joerg Riesmeier 17 * 18 * Purpose: Utilities (Header) 19 * 20 */ 21 22 23 #ifndef DIUTILS_H 24 #define DIUTILS_H 25 26 #include "dcmtk/config/osconfig.h" 27 28 #include "dcmtk/ofstd/oftypes.h" 29 #include "dcmtk/ofstd/ofcast.h" 30 31 #include "dcmtk/oflog/oflog.h" 32 33 #include "dcmtk/dcmimgle/didefine.h" 34 35 extern DCMTK_DCMIMGLE_EXPORT OFLogger DCM_dcmimgleLogger; 36 37 #define DCMIMGLE_TRACE(msg) OFLOG_TRACE(DCM_dcmimgleLogger, msg) 38 #define DCMIMGLE_DEBUG(msg) OFLOG_DEBUG(DCM_dcmimgleLogger, msg) 39 #define DCMIMGLE_INFO(msg) OFLOG_INFO(DCM_dcmimgleLogger, msg) 40 #define DCMIMGLE_WARN(msg) OFLOG_WARN(DCM_dcmimgleLogger, msg) 41 #define DCMIMGLE_ERROR(msg) OFLOG_ERROR(DCM_dcmimgleLogger, msg) 42 #define DCMIMGLE_FATAL(msg) OFLOG_FATAL(DCM_dcmimgleLogger, msg) 43 44 45 // include this file in doxygen documentation 46 47 /** @file diutils.h 48 * @brief type definitions, constants and helper functions for the dcmimgle/dcmimage module 49 */ 50 51 52 /*---------------------* 53 * const definitions * 54 *---------------------*/ 55 56 /** @name configuration flags 57 */ 58 59 //@{ 60 61 /// compatibility with old ACR-NEMA images 62 const unsigned long CIF_AcrNemaCompatibility = 0x0000001; 63 64 /// accept wrong palette attribute tags 65 const unsigned long CIF_WrongPaletteAttributeTags = 0x0000002; 66 67 /// element pixel data may be detached if it is no longer needed by DicomImage 68 const unsigned long CIF_MayDetachPixelData = 0x0000004; 69 70 /// use presentation state instead of 'built-in' LUTs & overlays 71 const unsigned long CIF_UsePresentationState = 0x0000008; 72 73 /// don't convert YCbCr (Full and Full 4:2:2) color images to RGB 74 const unsigned long CIF_KeepYCbCrColorModel = 0x0000010; 75 76 /// take responsibility for the given external DICOM dataset, i.e. delete it on destruction 77 const unsigned long CIF_TakeOverExternalDataset = 0x0000020; 78 79 /// ignore modality transformation (rescale slope/intercept or LUT) stored in the dataset 80 const unsigned long CIF_IgnoreModalityTransformation = 0x0000040; 81 82 /// ignore third value of the modality LUT descriptor, determine bit depth automatically 83 const unsigned long CIF_IgnoreModalityLutBitDepth = 0x0000080; 84 85 /// check third value of the LUT descriptor, compare with with expected bit depth based on LUT data 86 const unsigned long CIF_CheckLutBitDepth = 0x0000100; 87 88 /// use absolute (possible) pixel range for determining the internal representation (monochrome only) 89 const unsigned long CIF_UseAbsolutePixelRange = 0x0000200; 90 91 /// use partial access to pixel data, i.e. without decompressing or loading a complete multi-frame image. 92 /// Please note that the use of this flag can cause another copy of the pixel data to be created in memory, 93 /// e.g. in case the pixel data element value has already been loaded or decompressed completely in memory. 94 const unsigned long CIF_UsePartialAccessToPixelData = 0x0000400; 95 96 /// always decompress complete pixel data when processing an image, i.e. even if partial access is used 97 const unsigned long CIF_DecompressCompletePixelData = 0x0000800; 98 99 /// never access embedded overlays since this requires to load and uncompress the complete pixel data 100 const unsigned long CIF_NeverAccessEmbeddedOverlays = 0x0001000; 101 //@} 102 103 104 // / true color color mode (for monochrome images only) 105 const int MI_PastelColor = -1; 106 107 108 /*--------------------* 109 * type definitions * 110 *--------------------*/ 111 112 /** constants for photometric interpretation 113 */ 114 enum EP_Interpretation 115 { 116 /// unknown, undefined, invalid 117 EPI_Unknown, 118 /// no element value available 119 EPI_Missing, 120 /// monochrome 1 121 EPI_Monochrome1, 122 /// monochrome 2 123 EPI_Monochrome2, 124 /// palette color 125 EPI_PaletteColor, 126 /// RGB color 127 EPI_RGB, 128 /// HSV color (retired) 129 EPI_HSV, 130 /// ARGB color (retired) 131 EPI_ARGB, 132 /// CMYK color (retired) 133 EPI_CMYK, 134 /// YCbCr full 135 EPI_YBR_Full, 136 /// YCbCr full 4:2:2 137 EPI_YBR_Full_422, 138 /// YCbCr partial 4:2:2 139 EPI_YBR_Partial_422 140 }; 141 142 143 /** structure for photometric string and related constant 144 */ 145 struct DCMTK_DCMIMGLE_EXPORT SP_Interpretation 146 { 147 /// string (name of the color model without spaces and underscores) 148 const char *Name; 149 /// defined term according to the DICOM standard 150 const char *DefinedTerm; 151 /// integer constant 152 EP_Interpretation Type; 153 }; 154 155 156 /** structure for BMP bitmap file header 157 */ 158 struct DCMTK_DCMIMGLE_EXPORT SB_BitmapFileHeader 159 { 160 /// signature, must always be 'BM' 161 char bfType[2]; 162 /// file size in bytes 163 Uint32 bfSize; 164 /// reserved, should be '0' 165 Uint16 bfReserved1; 166 /// reserved, should be '0' 167 Uint16 bfReserved2; 168 /// offset from the beginning of the file to the bitmap data (in bytes) 169 Uint32 bfOffBits; 170 }; 171 172 173 /** structure for BMP bitmap info header 174 */ 175 struct DCMTK_DCMIMGLE_EXPORT SB_BitmapInfoHeader 176 { 177 /// size of the BitmapInfoHeader, usually '40' 178 Uint32 biSize; 179 /// width of the image (in pixels) 180 Sint32 biWidth; 181 /// height of the image (in pixels) 182 Sint32 biHeight; 183 /// number of planes, usually '1' 184 Uint16 biPlanes; 185 /// bits per pixel, supported values: 8 = color palette with 256 entries, 24 = true color 186 Uint16 biBitCount; 187 /// type of compression, support value: 0 = BI_RGB, no compression 188 Uint32 biCompression; 189 /// size of the image data (in bytes), might be set to '0' if image is uncompressed 190 Uint32 biSizeImage; 191 /// horizontal resolution: pixels/meter, usually set to '0' 192 Sint32 biXPelsPerMeter; 193 /// vertical resolution: pixels/meter, usually set to '0' 194 Sint32 biYPelsPerMeter; 195 /// number of actually used colors, if '0' the number of colors is calculated using 'biBitCount' 196 Uint32 biClrUsed; 197 /// number of important colors, '0' means all 198 Uint32 biClrImportant; 199 }; 200 201 202 /** internal representation of pixel data 203 */ 204 enum EP_Representation 205 { 206 /// unsigned 8 bit integer 207 EPR_Uint8, EPR_MinUnsigned = EPR_Uint8, 208 /// signed 8 bit integer 209 EPR_Sint8, EPR_MinSigned = EPR_Sint8, 210 /// unsigned 16 bit integer 211 EPR_Uint16, 212 /// signed 16 bit integer 213 EPR_Sint16, 214 /// unsigned 32 bit integer 215 EPR_Uint32, EPR_MaxUnsigned = EPR_Uint32, 216 /// signed 32 bit integer 217 EPR_Sint32, EPR_MaxSigned = EPR_Sint32 218 }; 219 220 221 /** image status code 222 */ 223 enum EI_Status 224 { 225 /// normal, no error 226 EIS_Normal, 227 /// data dictionary not found 228 EIS_NoDataDictionary, 229 /// invalid dataset/file 230 EIS_InvalidDocument, 231 /// mandatory attribute missing 232 EIS_MissingAttribute, 233 /// invalid value for an important attribute 234 EIS_InvalidValue, 235 /// specified value for an attribute not supported 236 EIS_NotSupportedValue, 237 /// memory exhausted etc. 238 EIS_MemoryFailure, 239 /// invalid image, internal error 240 EIS_InvalidImage, 241 /// other error 242 EIS_OtherError 243 }; 244 245 246 /** overlay modes. 247 * This mode is used to define how to display an overlay plane. 248 */ 249 enum EM_Overlay 250 { 251 /// default mode, as stored in the dataset 252 EMO_Default, 253 /// replace mode 254 EMO_Replace, 255 /// graphics overlay 256 EMO_Graphic = EMO_Replace, 257 /// threshold replace 258 EMO_ThresholdReplace, 259 /// complement 260 EMO_Complement, 261 /// invert the overlay bitmap 262 EMO_InvertBitmap, 263 /// region of interest (ROI) 264 EMO_RegionOfInterest, 265 /// bitmap shutter, used for GSPS objects 266 EMO_BitmapShutter 267 }; 268 269 270 /** VOI LUT functions 271 */ 272 enum EF_VoiLutFunction 273 { 274 /// default function (not explicitly set) 275 EFV_Default, 276 /// function LINEAR 277 EFV_Linear, 278 /// function SIGMOID 279 EFV_Sigmoid 280 }; 281 282 283 /** presentation LUT shapes 284 */ 285 enum ES_PresentationLut 286 { 287 /// default shape (not explicitly set) 288 ESP_Default, 289 /// shape IDENTITY 290 ESP_Identity, 291 /// shape INVERSE 292 ESP_Inverse, 293 /// shape LIN OD 294 ESP_LinOD 295 }; 296 297 298 /** polarity 299 */ 300 enum EP_Polarity 301 { 302 /// NORMAL 303 EPP_Normal, 304 /// REVERSE (opposite polarity) 305 EPP_Reverse 306 }; 307 308 309 /** bits per table entry modes. 310 * Specifies whether the given value in the LUT descriptor is used. 311 */ 312 enum EL_BitsPerTableEntry 313 { 314 /// use given value 315 ELM_UseValue, 316 /// ignore given value, use auto detection 317 ELM_IgnoreValue, 318 /// check whether given value is consistent with LUT data 319 ELM_CheckValue 320 }; 321 322 /** type of VOI LUT transformation to apply. 323 * Specifies which VOI LUT transformation should be applied to an image. 324 */ 325 enum EW_WindowType 326 { 327 /// use given value 328 EWT_none, 329 /// use the n-th VOI window from the image file 330 EWT_window_from_file, 331 /// use the n-th VOI look up table from the image file 332 EWT_voi_lut_from_file, 333 /// compute VOI window using min-max algorithm 334 EWT_window_minmax, 335 /// compute VOI window using min-max algorithm ignoring extremes 336 EWT_window_minmax_n, 337 /// compute VOI window using min-max algorithm applied to region of interest 338 EWT_window_minmax_roi, 339 /// compute VOI window using Histogram algorithm, ignoring n percent 340 EWT_window_histogram, 341 /// compute VOI window using center and width 342 EWT_window_center_width 343 }; 344 345 /*----------------------------* 346 * constant initializations * 347 *----------------------------*/ 348 349 const SP_Interpretation PhotometricInterpretationNames[] = 350 { 351 {"MONOCHROME1", "MONOCHROME1", EPI_Monochrome1}, 352 {"MONOCHROME2", "MONOCHROME2", EPI_Monochrome2}, 353 {"PALETTECOLOR", "PALETTE COLOR", EPI_PaletteColor}, // space deleted to simplify detection 354 {"RGB", "RGB", EPI_RGB}, 355 {"HSV", "HSV", EPI_HSV}, 356 {"ARGB", "ARGB", EPI_ARGB}, 357 {"CMYK", "CMYK", EPI_CMYK}, 358 {"YBRFULL", "YBR_FULL", EPI_YBR_Full}, // underscore deleted to simplify detection 359 {"YBRFULL422", "YBR_FULL_422", EPI_YBR_Full_422}, // underscores deleted to simplify detection 360 {"YBRPARTIAL422", "YBR_PARTIAL_422", EPI_YBR_Partial_422}, // underscores deleted to simplify detection 361 {NULL, NULL, EPI_Unknown} 362 }; 363 364 365 /*---------------------* 366 * macro definitions * 367 *---------------------*/ 368 369 #define MAX_UINT Uint32 370 #define MAX_SINT Sint32 371 372 #define MAX_BITS 32 373 #define MAX_BITS_TYPE Uint32 374 #define MAX_RAWPPM_BITS 8 375 #define MAX_INTERPOLATION_BITS 16 376 377 #define bitsof(expr) (sizeof(expr) << 3) 378 379 380 /*----------------------* 381 * class declarations * 382 *----------------------*/ 383 384 /** Class comprising several global functions and constants. 385 * introduced to avoid problems with naming convention 386 */ 387 class DCMTK_DCMIMGLE_EXPORT DicomImageClass 388 { 389 390 public: 391 392 /** calculate maximum value which could be stored in the specified number of bits 393 * 394 ** @param mv_bits number of bits 395 * @param mv_pos value subtracted from the maximum value (0 or 1) 396 * 397 ** @return maximum value 398 */ 399 static inline unsigned long maxval(const int mv_bits, 400 const unsigned long mv_pos = 1) 401 { 402 return (mv_bits < MAX_BITS) ? 403 (OFstatic_cast(unsigned long, 1) << mv_bits) - mv_pos : OFstatic_cast(MAX_BITS_TYPE, -1); 404 } 405 406 /** calculate number of bits which are necessary to store the specified value 407 * 408 ** @param tb_value value to be stored 409 * @param tb_pos value subtracted from the value (0 or 1) before converting 410 * 411 ** @return number of bits 412 */ 413 static inline unsigned int tobits(unsigned long tb_value, 414 const unsigned long tb_pos = 1) 415 { 416 if (tb_value > 0) 417 tb_value -= tb_pos; 418 unsigned int tb_bits = 0; 419 while (tb_value > 0) 420 { 421 ++tb_bits; 422 tb_value >>= 1; 423 } 424 return tb_bits; 425 } 426 427 /** calculate number of bits which are necessary to store the specified value range 428 * 429 ** @param minvalue minimum value to be stored 430 * @param maxvalue maximum value to be stored 431 * 432 ** @return number of bits 433 */ 434 static unsigned int rangeToBits(double minvalue, 435 double maxvalue); 436 437 /** determine whether integer representation is signed or unsigned 438 * 439 ** @param repres integer representation (enum) to be checked 440 * 441 ** @return true if representation is signed, false if unsigned 442 */ 443 static int isRepresentationSigned(EP_Representation repres); 444 445 /** determine number of bits used for a particular integer representation 446 * 447 ** @param repres integer representation (enum) to be checked 448 * 449 ** @return number of bits 450 */ 451 static unsigned int getRepresentationBits(EP_Representation repres); 452 453 /** determine integer representation which is necessary to store values in the specified range 454 * 455 ** @param minvalue minimum value to be stored 456 * @param maxvalue maximum value to be stored 457 * 458 ** @return integer representation (enum) 459 */ 460 static EP_Representation determineRepresentation(double minvalue, 461 double maxvalue); 462 463 }; 464 465 466 #endif 467