445 lines
12 KiB
C
445 lines
12 KiB
C
|
/*
|
||
|
*
|
||
|
* Copyright (C) 1996-2016, OFFIS e.V.
|
||
|
* All rights reserved. See COPYRIGHT file for details.
|
||
|
*
|
||
|
* This software and supporting documentation were developed by
|
||
|
*
|
||
|
* OFFIS e.V.
|
||
|
* R&D Division Health
|
||
|
* Escherweg 2
|
||
|
* D-26121 Oldenburg, Germany
|
||
|
*
|
||
|
*
|
||
|
* Module: dcmimgle
|
||
|
*
|
||
|
* Author: Joerg Riesmeier
|
||
|
*
|
||
|
* Purpose: Utilities (Header)
|
||
|
*
|
||
|
*/
|
||
|
|
||
|
|
||
|
#ifndef DIUTILS_H
|
||
|
#define DIUTILS_H
|
||
|
|
||
|
#include "dcmtk/config/osconfig.h"
|
||
|
|
||
|
#include "dcmtk/ofstd/oftypes.h"
|
||
|
#include "dcmtk/ofstd/ofcast.h"
|
||
|
|
||
|
#include "dcmtk/oflog/oflog.h"
|
||
|
|
||
|
#include "dcmtk/dcmimgle/didefine.h"
|
||
|
|
||
|
extern DCMTK_DCMIMGLE_EXPORT OFLogger DCM_dcmimgleLogger;
|
||
|
|
||
|
#define DCMIMGLE_TRACE(msg) OFLOG_TRACE(DCM_dcmimgleLogger, msg)
|
||
|
#define DCMIMGLE_DEBUG(msg) OFLOG_DEBUG(DCM_dcmimgleLogger, msg)
|
||
|
#define DCMIMGLE_INFO(msg) OFLOG_INFO(DCM_dcmimgleLogger, msg)
|
||
|
#define DCMIMGLE_WARN(msg) OFLOG_WARN(DCM_dcmimgleLogger, msg)
|
||
|
#define DCMIMGLE_ERROR(msg) OFLOG_ERROR(DCM_dcmimgleLogger, msg)
|
||
|
#define DCMIMGLE_FATAL(msg) OFLOG_FATAL(DCM_dcmimgleLogger, msg)
|
||
|
|
||
|
|
||
|
// include this file in doxygen documentation
|
||
|
|
||
|
/** @file diutils.h
|
||
|
* @brief utilities for the dcmimgle/dcmimage module
|
||
|
*/
|
||
|
|
||
|
|
||
|
/*---------------------*
|
||
|
* const definitions *
|
||
|
*---------------------*/
|
||
|
|
||
|
/** @name configuration flags
|
||
|
*/
|
||
|
|
||
|
//@{
|
||
|
|
||
|
/// compatibility with old ACR-NEMA images
|
||
|
const unsigned long CIF_AcrNemaCompatibility = 0x0000001;
|
||
|
|
||
|
/// accept wrong palette attribute tags
|
||
|
const unsigned long CIF_WrongPaletteAttributeTags = 0x0000002;
|
||
|
|
||
|
/// element pixel data may be detached if it is no longer needed by DicomImage
|
||
|
const unsigned long CIF_MayDetachPixelData = 0x0000004;
|
||
|
|
||
|
/// use presentation state instead of 'built-in' LUTs & overlays
|
||
|
const unsigned long CIF_UsePresentationState = 0x0000008;
|
||
|
|
||
|
/// don't convert YCbCr (Full and Full 4:2:2) color images to RGB
|
||
|
const unsigned long CIF_KeepYCbCrColorModel = 0x0000010;
|
||
|
|
||
|
/// take responsibility for the given external DICOM dataset, i.e. delete it on destruction
|
||
|
const unsigned long CIF_TakeOverExternalDataset = 0x0000020;
|
||
|
|
||
|
/// ignore modality transformation (rescale slope/intercept or LUT) stored in the dataset
|
||
|
const unsigned long CIF_IgnoreModalityTransformation = 0x0000040;
|
||
|
|
||
|
/// ignore third value of the modality LUT descriptor, determine bit depth automatically
|
||
|
const unsigned long CIF_IgnoreModalityLutBitDepth = 0x0000080;
|
||
|
|
||
|
/// check third value of the LUT descriptor, compare with with expected bit depth based on LUT data
|
||
|
const unsigned long CIF_CheckLutBitDepth = 0x0000100;
|
||
|
|
||
|
/// use absolute (possible) pixel range for determining the internal representation (monochrome only)
|
||
|
const unsigned long CIF_UseAbsolutePixelRange = 0x0000200;
|
||
|
|
||
|
/// use partial access to pixel data, i.e. without decompressing or loading a complete multi-frame image.
|
||
|
/// Please note that the use of this flag can cause another copy of the pixel data to be created in memory,
|
||
|
/// e.g. in case the pixel data element value has already been loaded or decompressed completely in memory.
|
||
|
const unsigned long CIF_UsePartialAccessToPixelData = 0x0000400;
|
||
|
|
||
|
/// always decompress complete pixel data when processing an image, i.e. even if partial access is used
|
||
|
const unsigned long CIF_DecompressCompletePixelData = 0x0000800;
|
||
|
|
||
|
/// never access embedded overlays since this requires to load and uncompress the complete pixel data
|
||
|
const unsigned long CIF_NeverAccessEmbeddedOverlays = 0x0001000;
|
||
|
//@}
|
||
|
|
||
|
|
||
|
// / true color color mode (for monochrome images only)
|
||
|
const int MI_PastelColor = -1;
|
||
|
|
||
|
|
||
|
/*--------------------*
|
||
|
* type definitions *
|
||
|
*--------------------*/
|
||
|
|
||
|
/** constants for photometric interpretation
|
||
|
*/
|
||
|
enum EP_Interpretation
|
||
|
{
|
||
|
/// unknown, undefined, invalid
|
||
|
EPI_Unknown,
|
||
|
/// no element value available
|
||
|
EPI_Missing,
|
||
|
/// monochrome 1
|
||
|
EPI_Monochrome1,
|
||
|
/// monochrome 2
|
||
|
EPI_Monochrome2,
|
||
|
/// palette color
|
||
|
EPI_PaletteColor,
|
||
|
/// RGB color
|
||
|
EPI_RGB,
|
||
|
/// HSV color (retired)
|
||
|
EPI_HSV,
|
||
|
/// ARGB color (retired)
|
||
|
EPI_ARGB,
|
||
|
/// CMYK color (retired)
|
||
|
EPI_CMYK,
|
||
|
/// YCbCr full
|
||
|
EPI_YBR_Full,
|
||
|
/// YCbCr full 4:2:2
|
||
|
EPI_YBR_Full_422,
|
||
|
/// YCbCr partial 4:2:2
|
||
|
EPI_YBR_Partial_422
|
||
|
};
|
||
|
|
||
|
|
||
|
/** structure for photometric string and related constant
|
||
|
*/
|
||
|
struct DCMTK_DCMIMGLE_EXPORT SP_Interpretation
|
||
|
{
|
||
|
/// string (name of the color model without spaces and underscores)
|
||
|
const char *Name;
|
||
|
/// defined term according to the DICOM standard
|
||
|
const char *DefinedTerm;
|
||
|
/// integer constant
|
||
|
EP_Interpretation Type;
|
||
|
};
|
||
|
|
||
|
|
||
|
/** structure for BMP bitmap file header
|
||
|
*/
|
||
|
struct DCMTK_DCMIMGLE_EXPORT SB_BitmapFileHeader
|
||
|
{
|
||
|
/// signature, must always be 'BM'
|
||
|
char bfType[2];
|
||
|
/// file size in bytes
|
||
|
Uint32 bfSize;
|
||
|
/// reserved, should be '0'
|
||
|
Uint16 bfReserved1;
|
||
|
/// reserved, should be '0'
|
||
|
Uint16 bfReserved2;
|
||
|
/// offset from the beginning of the file to the bitmap data (in bytes)
|
||
|
Uint32 bfOffBits;
|
||
|
};
|
||
|
|
||
|
|
||
|
/** structure for BMP bitmap info header
|
||
|
*/
|
||
|
struct DCMTK_DCMIMGLE_EXPORT SB_BitmapInfoHeader
|
||
|
{
|
||
|
/// size of the BitmapInfoHeader, usually '40'
|
||
|
Uint32 biSize;
|
||
|
/// width of the image (in pixels)
|
||
|
Sint32 biWidth;
|
||
|
/// height of the image (in pixels)
|
||
|
Sint32 biHeight;
|
||
|
/// number of planes, usually '1'
|
||
|
Uint16 biPlanes;
|
||
|
/// bits per pixel, supported values: 8 = color palette with 256 entries, 24 = true color
|
||
|
Uint16 biBitCount;
|
||
|
/// type of compression, support value: 0 = BI_RGB, no compression
|
||
|
Uint32 biCompression;
|
||
|
/// size of the image data (in bytes), might be set to '0' if image is uncompressed
|
||
|
Uint32 biSizeImage;
|
||
|
/// horizontal resolution: pixels/meter, usually set to '0'
|
||
|
Sint32 biXPelsPerMeter;
|
||
|
/// vertical resolution: pixels/meter, usually set to '0'
|
||
|
Sint32 biYPelsPerMeter;
|
||
|
/// number of actually used colors, if '0' the number of colors is calculated using 'biBitCount'
|
||
|
Uint32 biClrUsed;
|
||
|
/// number of important colors, '0' means all
|
||
|
Uint32 biClrImportant;
|
||
|
};
|
||
|
|
||
|
|
||
|
/** internal representation of pixel data
|
||
|
*/
|
||
|
enum EP_Representation
|
||
|
{
|
||
|
/// unsigned 8 bit integer
|
||
|
EPR_Uint8, EPR_MinUnsigned = EPR_Uint8,
|
||
|
/// signed 8 bit integer
|
||
|
EPR_Sint8, EPR_MinSigned = EPR_Sint8,
|
||
|
/// unsigned 16 bit integer
|
||
|
EPR_Uint16,
|
||
|
/// signed 16 bit integer
|
||
|
EPR_Sint16,
|
||
|
/// unsigned 32 bit integer
|
||
|
EPR_Uint32, EPR_MaxUnsigned = EPR_Uint32,
|
||
|
/// signed 32 bit integer
|
||
|
EPR_Sint32, EPR_MaxSigned = EPR_Sint32
|
||
|
};
|
||
|
|
||
|
|
||
|
/** image status code
|
||
|
*/
|
||
|
enum EI_Status
|
||
|
{
|
||
|
/// normal, no error
|
||
|
EIS_Normal,
|
||
|
/// data dictionary not found
|
||
|
EIS_NoDataDictionary,
|
||
|
/// invalid dataset/file
|
||
|
EIS_InvalidDocument,
|
||
|
/// mandatory attribute missing
|
||
|
EIS_MissingAttribute,
|
||
|
/// invalid value for an important attribute
|
||
|
EIS_InvalidValue,
|
||
|
/// specified value for an attribute not supported
|
||
|
EIS_NotSupportedValue,
|
||
|
/// memory exhausted etc.
|
||
|
EIS_MemoryFailure,
|
||
|
/// invalid image, internal error
|
||
|
EIS_InvalidImage,
|
||
|
/// other error
|
||
|
EIS_OtherError
|
||
|
};
|
||
|
|
||
|
|
||
|
/** overlay modes.
|
||
|
* This mode is used to define how to display an overlay plane.
|
||
|
*/
|
||
|
enum EM_Overlay
|
||
|
{
|
||
|
/// default mode, as stored in the dataset
|
||
|
EMO_Default,
|
||
|
/// replace mode
|
||
|
EMO_Replace,
|
||
|
/// graphics overlay
|
||
|
EMO_Graphic = EMO_Replace,
|
||
|
/// threshold replace
|
||
|
EMO_ThresholdReplace,
|
||
|
/// complement
|
||
|
EMO_Complement,
|
||
|
/// invert the overlay bitmap
|
||
|
EMO_InvertBitmap,
|
||
|
/// region of interest (ROI)
|
||
|
EMO_RegionOfInterest,
|
||
|
/// bitmap shutter, used for GSPS objects
|
||
|
EMO_BitmapShutter
|
||
|
};
|
||
|
|
||
|
|
||
|
/** VOI LUT functions
|
||
|
*/
|
||
|
enum EF_VoiLutFunction
|
||
|
{
|
||
|
/// default function (not explicitly set)
|
||
|
EFV_Default,
|
||
|
/// function LINEAR
|
||
|
EFV_Linear,
|
||
|
/// function SIGMOID
|
||
|
EFV_Sigmoid
|
||
|
};
|
||
|
|
||
|
|
||
|
/** presentation LUT shapes
|
||
|
*/
|
||
|
enum ES_PresentationLut
|
||
|
{
|
||
|
/// default shape (not explicitly set)
|
||
|
ESP_Default,
|
||
|
/// shape IDENTITY
|
||
|
ESP_Identity,
|
||
|
/// shape INVERSE
|
||
|
ESP_Inverse,
|
||
|
/// shape LIN OD
|
||
|
ESP_LinOD
|
||
|
};
|
||
|
|
||
|
|
||
|
/** polarity
|
||
|
*/
|
||
|
enum EP_Polarity
|
||
|
{
|
||
|
/// NORMAL
|
||
|
EPP_Normal,
|
||
|
/// REVERSE (opposite polarity)
|
||
|
EPP_Reverse
|
||
|
};
|
||
|
|
||
|
|
||
|
/** bits per table entry modes.
|
||
|
* Specifies whether the given value in the LUT descriptor is used.
|
||
|
*/
|
||
|
enum EL_BitsPerTableEntry
|
||
|
{
|
||
|
/// use given value
|
||
|
ELM_UseValue,
|
||
|
/// ignore given value, use auto detection
|
||
|
ELM_IgnoreValue,
|
||
|
/// check whether given value is consistent with LUT data
|
||
|
ELM_CheckValue
|
||
|
};
|
||
|
|
||
|
|
||
|
/*----------------------------*
|
||
|
* constant initializations *
|
||
|
*----------------------------*/
|
||
|
|
||
|
const SP_Interpretation PhotometricInterpretationNames[] =
|
||
|
{
|
||
|
{"MONOCHROME1", "MONOCHROME1", EPI_Monochrome1},
|
||
|
{"MONOCHROME2", "MONOCHROME2", EPI_Monochrome2},
|
||
|
{"PALETTECOLOR", "PALETTE COLOR", EPI_PaletteColor}, // space deleted to simplify detection
|
||
|
{"RGB", "RGB", EPI_RGB},
|
||
|
{"HSV", "HSV", EPI_HSV},
|
||
|
{"ARGB", "ARGB", EPI_ARGB},
|
||
|
{"CMYK", "CMYK", EPI_CMYK},
|
||
|
{"YBRFULL", "YBR_FULL", EPI_YBR_Full}, // underscore deleted to simplify detection
|
||
|
{"YBRFULL422", "YBR_FULL_422", EPI_YBR_Full_422}, // underscores deleted to simplify detection
|
||
|
{"YBRPARTIAL422", "YBR_PARTIAL_422", EPI_YBR_Partial_422}, // underscores deleted to simplify detection
|
||
|
{NULL, NULL, EPI_Unknown}
|
||
|
};
|
||
|
|
||
|
|
||
|
/*---------------------*
|
||
|
* macro definitions *
|
||
|
*---------------------*/
|
||
|
|
||
|
#define MAX_UINT Uint32
|
||
|
#define MAX_SINT Sint32
|
||
|
|
||
|
#define MAX_BITS 32
|
||
|
#define MAX_BITS_TYPE Uint32
|
||
|
#define MAX_RAWPPM_BITS 8
|
||
|
#define MAX_INTERPOLATION_BITS 16
|
||
|
|
||
|
#define bitsof(expr) (sizeof(expr) << 3)
|
||
|
|
||
|
|
||
|
/*----------------------*
|
||
|
* class declarations *
|
||
|
*----------------------*/
|
||
|
|
||
|
/** Class comprising several global functions and constants.
|
||
|
* introduced to avoid problems with naming convention
|
||
|
*/
|
||
|
class DCMTK_DCMIMGLE_EXPORT DicomImageClass
|
||
|
{
|
||
|
|
||
|
public:
|
||
|
|
||
|
/** calculate maximum value which could be stored in the specified number of bits
|
||
|
*
|
||
|
** @param mv_bits number of bits
|
||
|
* @param mv_pos value subtracted from the maximum value (0 or 1)
|
||
|
*
|
||
|
** @return maximum value
|
||
|
*/
|
||
|
static inline unsigned long maxval(const int mv_bits,
|
||
|
const unsigned long mv_pos = 1)
|
||
|
{
|
||
|
return (mv_bits < MAX_BITS) ?
|
||
|
(OFstatic_cast(unsigned long, 1) << mv_bits) - mv_pos : OFstatic_cast(MAX_BITS_TYPE, -1);
|
||
|
}
|
||
|
|
||
|
/** calculate number of bits which are necessary to store the specified value
|
||
|
*
|
||
|
** @param tb_value value to be stored
|
||
|
* @param tb_pos value subtracted from the value (0 or 1) before converting
|
||
|
*
|
||
|
** @return number of bits
|
||
|
*/
|
||
|
static inline unsigned int tobits(unsigned long tb_value,
|
||
|
const unsigned long tb_pos = 1)
|
||
|
{
|
||
|
if (tb_value > 0)
|
||
|
tb_value -= tb_pos;
|
||
|
unsigned int tb_bits = 0;
|
||
|
while (tb_value > 0)
|
||
|
{
|
||
|
++tb_bits;
|
||
|
tb_value >>= 1;
|
||
|
}
|
||
|
return tb_bits;
|
||
|
}
|
||
|
|
||
|
/** calculate number of bits which are necessary to store the specified value range
|
||
|
*
|
||
|
** @param minvalue minimum value to be stored
|
||
|
* @param maxvalue maximum value to be stored
|
||
|
*
|
||
|
** @return number of bits
|
||
|
*/
|
||
|
static unsigned int rangeToBits(double minvalue,
|
||
|
double maxvalue);
|
||
|
|
||
|
/** determine whether integer representation is signed or unsigned
|
||
|
*
|
||
|
** @param repres integer representation (enum) to be checked
|
||
|
*
|
||
|
** @return true if representation is signed, false if unsigned
|
||
|
*/
|
||
|
static int isRepresentationSigned(EP_Representation repres);
|
||
|
|
||
|
/** determine number of bits used for a particular integer representation
|
||
|
*
|
||
|
** @param repres integer representation (enum) to be checked
|
||
|
*
|
||
|
** @return number of bits
|
||
|
*/
|
||
|
static unsigned int getRepresentationBits(EP_Representation repres);
|
||
|
|
||
|
/** determine integer representation which is necessary to store values in the specified range
|
||
|
*
|
||
|
** @param minvalue minimum value to be stored
|
||
|
* @param maxvalue maximum value to be stored
|
||
|
*
|
||
|
** @return integer representation (enum)
|
||
|
*/
|
||
|
static EP_Representation determineRepresentation(double minvalue,
|
||
|
double maxvalue);
|
||
|
|
||
|
};
|
||
|
|
||
|
|
||
|
#endif
|