/* * * Copyright (C) 2007-2011, 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: dcmjpls * * Author: Martin Willkomm, Marco Eichelberg * * Purpose: codec classes for JPEG-LS decoders. * */ #ifndef DCMJPLS_DJCODECD_H #define DCMJPLS_DJCODECD_H #include "dcmtk/config/osconfig.h" #include "dcmtk/dcmdata/dccodec.h" /* for class DcmCodec */ #include "dcmtk/ofstd/ofstring.h" #include "dcmtk/dcmjpls/dldefine.h" /* forward declaration */ class DJLSCodecParameter; /** abstract codec class for JPEG-LS decoders. * This abstract class contains most of the application logic * needed for a dcmdata codec object that implements a JPEG-LS decoder. * This class only supports decompression, it neither implements * encoding nor transcoding. */ class DCMTK_DCMJPLS_EXPORT DJLSDecoderBase: public DcmCodec { public: /// default constructor DJLSDecoderBase(); /// destructor virtual ~DJLSDecoderBase(); /** decompresses the given pixel sequence and * stores the result in the given uncompressedPixelData element. * @param fromRepParam current representation parameter of compressed data, may be NULL * @param pixSeq compressed pixel sequence * @param uncompressedPixelData uncompressed pixel data stored in this element * @param cp codec parameters for this codec * @param objStack stack pointing to the location of the pixel data * element in the current dataset. * @return EC_Normal if successful, an error code otherwise. */ virtual OFCondition decode( const DcmRepresentationParameter * fromRepParam, DcmPixelSequence * pixSeq, DcmPolymorphOBOW& uncompressedPixelData, const DcmCodecParameter * cp, const DcmStack& objStack) const; /** decompresses a single frame from the given pixel sequence and * stores the result in the given buffer. * @param fromParam representation parameter of current compressed * representation, may be NULL. * @param fromPixSeq compressed pixel sequence * @param cp codec parameters for this codec * @param dataset pointer to dataset in which pixel data element is contained * @param frameNo number of frame, starting with 0 for the first frame * @param startFragment index of the compressed fragment that contains * all or the first part of the compressed bitstream for the given frameNo. * Upon successful return this parameter is updated to contain the index * of the first compressed fragment of the next frame. * When unknown, zero should be passed. In this case the decompression * algorithm will try to determine the index by itself, which will always * work if frames are decompressed in increasing order from first to last, * but may fail if frames are decompressed in random order, multiple fragments * per frame and multiple frames are present in the dataset, and the offset * table is empty. * @param buffer pointer to buffer where frame is to be stored * @param bufSize size of buffer in bytes * @param decompressedColorModel upon successful return, the color model * of the decompressed image (which may be different from the one used * in the compressed images) is returned in this parameter. * @return EC_Normal if successful, an error code otherwise. */ virtual OFCondition decodeFrame( const DcmRepresentationParameter * fromParam, DcmPixelSequence * fromPixSeq, const DcmCodecParameter * cp, DcmItem *dataset, Uint32 frameNo, Uint32& startFragment, void *buffer, Uint32 bufSize, OFString& decompressedColorModel) const; /** compresses the given uncompressed DICOM image and stores * the result in the given pixSeq element. * @param pixelData pointer to the uncompressed image data in OW format * and local byte order * @param length of the pixel data field in bytes * @param toRepParam representation parameter describing the desired * compressed representation (e.g. JPEG quality) * @param pixSeq compressed pixel sequence (pointer to new DcmPixelSequence object * allocated on heap) returned in this parameter upon success. * @param cp codec parameters for this codec * @param objStack stack pointing to the location of the pixel data * element in the current dataset. * @return EC_Normal if successful, an error code otherwise. */ virtual OFCondition encode( const Uint16 * pixelData, const Uint32 length, const DcmRepresentationParameter * toRepParam, DcmPixelSequence * & pixSeq, const DcmCodecParameter *cp, DcmStack & objStack) const; /** transcodes (re-compresses) the given compressed DICOM image and stores * the result in the given toPixSeq element. * @param fromRepType current transfer syntax of the compressed image * @param fromRepParam current representation parameter of compressed data, may be NULL * @param fromPixSeq compressed pixel sequence * @param toRepParam representation parameter describing the desired * new compressed representation (e.g. JPEG quality) * @param toPixSeq compressed pixel sequence (pointer to new DcmPixelSequence object * allocated on heap) returned in this parameter upon success. * @param cp codec parameters for this codec * @param objStack stack pointing to the location of the pixel data * element in the current dataset. * @return EC_Normal if successful, an error code otherwise. */ virtual OFCondition encode( const E_TransferSyntax fromRepType, const DcmRepresentationParameter * fromRepParam, DcmPixelSequence * fromPixSeq, const DcmRepresentationParameter * toRepParam, DcmPixelSequence * & toPixSeq, const DcmCodecParameter * cp, DcmStack & objStack) const; /** checks if this codec is able to convert from the * given current transfer syntax to the given new * transfer syntax * @param oldRepType current transfer syntax * @param newRepType desired new transfer syntax * @return true if transformation is supported by this codec, false otherwise. */ virtual OFBool canChangeCoding( const E_TransferSyntax oldRepType, const E_TransferSyntax newRepType) const; /** determine color model of the decompressed image * @param fromParam representation parameter of current compressed * representation, may be NULL * @param fromPixSeq compressed pixel sequence * @param cp codec parameters for this codec * @param dataset pointer to dataset in which pixel data element is contained * @param dataset pointer to DICOM dataset in which this pixel data object * is located. Used to access photometric interpretation. * @param decompressedColorModel upon successful return, the color model * of the decompressed image (which may be different from the one used * in the compressed images) is returned in this parameter * @return EC_Normal if successful, an error code otherwise */ virtual OFCondition determineDecompressedColorModel( const DcmRepresentationParameter *fromParam, DcmPixelSequence *fromPixSeq, const DcmCodecParameter *cp, DcmItem *dataset, OFString &decompressedColorModel) const; private: // static private helper methods /** decompresses a single frame from the given pixel sequence and * stores the result in the given buffer. * @param fromPixSeq compressed pixel sequence * @param cp codec parameters for this codec * @param dataset pointer to dataset in which pixel data element is contained * @param frameNo number of frame, starting with 0 for the first frame * @param startFragment index of the compressed fragment that contains * all or the first part of the compressed bitstream for the given frameNo. * Upon successful return this parameter is updated to contain the index * of the first compressed fragment of the next frame. * When unknown, zero should be passed. In this case the decompression * algorithm will try to determine the index by itself, which will always * work if frames are decompressed in increasing order from first to last, * but may fail if frames are decompressed in random order, multiple fragments * per frame and multiple frames are present in the dataset, and the offset * table is empty. * @param buffer pointer to buffer where frame is to be stored * @param bufSize size of buffer in bytes * @param imageFrames number of frames in this image * @param imageColumns number of columns for each frame * @param imageRows number of rows for each frame * @param imageSamplesPerPixel number of samples per pixel * @param bytesPerSample number of bytes per sample * @return EC_Normal if successful, an error code otherwise. */ static OFCondition decodeFrame( DcmPixelSequence * fromPixSeq, const DJLSCodecParameter *cp, DcmItem *dataset, Uint32 frameNo, Uint32& startFragment, void *buffer, Uint32 bufSize, Sint32 imageFrames, Uint16 imageColumns, Uint16 imageRows, Uint16 imageSamplesPerPixel, Uint16 bytesPerSample); /** determines if a given image requires color-by-plane planar configuration * depending on SOP Class UID (DICOM IOD) and photometric interpretation. * All SOP classes defined in the 2003 edition of the DICOM standard or earlier * are handled correctly. * @param sopClassUID SOP Class UID * @param photometricInterpretation decompressed photometric interpretation * @return legal value for planar configuration */ static Uint16 determinePlanarConfiguration( const OFString& sopClassUID, const OFString& photometricInterpretation); /** computes the number of fragments (pixel items) that comprise the current * frame in the compressed pixel sequence. This method uses various approaches * to compute the number of fragments for a frame, including a check of the * offset table and checking the start of each fragment for JPEG SOI markers. * @param numberOfFrames total number of frames of the DICOM object * @param currentFrame index of current frame (0..numberOfFrames-1) * @param startItem index of fragment (pixel item) the frame starts with * @param ignoreOffsetTable flag instructing the method to ignore the offset table * even if present and presumably useful * @param pixSeq the compressed JPEG-LS pixel sequence * @return number of fragments for the current frame, zero upon error */ static Uint32 computeNumberOfFragments( Sint32 numberOfFrames, Uint32 currentFrame, Uint32 startItem, OFBool ignoreOffsetTable, DcmPixelSequence *pixSeq); /** check whether the given buffer contains a JPEG-LS start-of-image code * @param fragmentData pointer to 4 or more bytes of JPEG-LS data * @returns true if the first four bytes of the code stream indicate that * this fragment is the start of a new JPEG-LS image, i.e. starts with * an SOI marker followed by SOF, COM or APPn. */ static OFBool isJPEGLSStartOfImage(Uint8 *fragmentData); /** converts an RGB or YBR frame with 8 bits/sample from * color-by-pixel to color-by-plane planar configuration. * @param imageFrame pointer to image frame, must contain * at least 3*columns*rows bytes of pixel data. * @param columns columns * @param rows rows * @return EC_Normal if successful, an error code otherwise */ static OFCondition createPlanarConfiguration1Byte( Uint8 *imageFrame, Uint16 columns, Uint16 rows); /** converts an RGB or YBR frame with 16 bits/sample from * color-by-pixel to color-by-plane planar configuration. * @param imageFrame pointer to image frame, must contain * at least 3*columns*rows words of pixel data. * @param columns columns * @param rows rows * @return EC_Normal if successful, an error code otherwise */ static OFCondition createPlanarConfiguration1Word( Uint16 *imageFrame, Uint16 columns, Uint16 rows); /** converts an RGB or YBR frame with 8 bits/sample from * color-by-plane to color-by-pixel planar configuration. * @param imageFrame pointer to image frame, must contain * at least 3*columns*rows bytes of pixel data. * @param columns columns * @param rows rows * @return EC_Normal if successful, an error code otherwise */ static OFCondition createPlanarConfiguration0Byte( Uint8 *imageFrame, Uint16 columns, Uint16 rows); /** converts an RGB or YBR frame with 16 bits/sample from * color-by-plane to color-by-pixel planar configuration. * @param imageFrame pointer to image frame, must contain * at least 3*columns*rows words of pixel data. * @param columns columns * @param rows rows * @return EC_Normal if successful, an error code otherwise */ static OFCondition createPlanarConfiguration0Word( Uint16 *imageFrame, Uint16 columns, Uint16 rows); }; /** codec class for JPEG-LS lossless only TS decoding */ class DCMTK_DCMJPLS_EXPORT DJLSLosslessDecoder : public DJLSDecoderBase { /** returns the transfer syntax that this particular codec * is able to Decode * @return supported transfer syntax */ virtual E_TransferSyntax supportedTransferSyntax() const; }; /** codec class for JPEG-LS lossy and lossless TS decoding */ class DCMTK_DCMJPLS_EXPORT DJLSNearLosslessDecoder : public DJLSDecoderBase { /** returns the transfer syntax that this particular codec * is able to encode * @return supported transfer syntax */ virtual E_TransferSyntax supportedTransferSyntax() const; }; #endif