⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dcrledec.h

📁 转化为DIB位图再显示出来的dicom文件C++代码
💻 H
字号:
/* * *  Copyright (C) 1994-2005, OFFIS * *  This software and supporting documentation were developed by * *    Kuratorium OFFIS e.V. *    Healthcare Information and Communication Systems *    Escherweg 2 *    D-26121 Oldenburg, Germany * *  THIS SOFTWARE IS MADE AVAILABLE,  AS IS,  AND OFFIS MAKES NO  WARRANTY *  REGARDING  THE  SOFTWARE,  ITS  PERFORMANCE,  ITS  MERCHANTABILITY  OR *  FITNESS FOR ANY PARTICULAR USE, FREEDOM FROM ANY COMPUTER DISEASES  OR *  ITS CONFORMITY TO ANY SPECIFICATION. THE ENTIRE RISK AS TO QUALITY AND *  PERFORMANCE OF THE SOFTWARE IS WITH THE USER. * *  Module:  dcmdata * *  Author:  Marco Eichelberg * *  Purpose: RLE decompressor * *  Last Update:      $Author: meichel $ *  Update Date:      $Date: 2005/12/08 16:28:36 $ *  Source File:      $Source: /share/dicom/cvs-depot/dcmtk/dcmdata/include/dcmtk/dcmdata/dcrledec.h,v $ *  CVS/RCS Revision: $Revision: 1.4 $ *  Status:           $State: Exp $ * *  CVS/RCS Log at end of file * */#ifndef DCRLEDEC_H#define DCRLEDEC_H#include "dcmtk/config/osconfig.h"#include "dcmtk/dcmdata/dcerror.h"/** this class implements an RLE decompressor conforming to the DICOM standard. *  The class is loosely based on an implementation by Phil Norman <forrey@eh.org> */class DcmRLEDecoder{public:  /** constructor   *  @param outputBufferSize size of the output buffer (in bytes)   *    to which the RLE codec will write decompressed output.   */  DcmRLEDecoder(size_t outputBufferSize)  : fail_(0)  , outputBufferSize_(outputBufferSize)  , outputBuffer_(NULL)  , offset_(0)  , suspendInfo_(128)  {    if (outputBufferSize_ == 0) fail_ = 1;    else    {      outputBuffer_ = new unsigned char[outputBufferSize_];      if (outputBuffer_ == NULL) fail_ = 1;    }  }  /// destructor  ~DcmRLEDecoder()  {    delete[] outputBuffer_;  }  /** resets the decoder object to newly constructed state.   *  The size and location of the output buffer is not changed.   */  inline void clear()  {    offset_ = 0;    suspendInfo_ = 128;    if (outputBuffer_) fail_ = 0;  }  inline OFCondition decompress(void *compressedData, size_t compressedSize)  {    // we allow a call for zero bytes    if (compressedSize == 0) return EC_Normal;    OFCondition result = EC_IllegalCall;    // check parameters passed by caller    if (compressedData == NULL) fail_ = 1;    if (! fail_)  // if fail_ is true, just ignore input    {      result = EC_Normal;      unsigned char ch;      unsigned char nbytes;      unsigned char *cp = OFstatic_cast(unsigned char *, compressedData);      // check if we suspended last time, clean up      if (suspendInfo_ > 128)      {        // DICOM packbit scheme uses 257 - nbytes to represent replicate runs        nbytes = OFstatic_cast(unsigned char, 257 - suspendInfo_);        // suspended replicate run. compressedSize cannot be zero now.        suspendInfo_ = 128;        ch = *cp++;        --compressedSize;        replicate(ch, nbytes);      }      else if (suspendInfo_ < 128)      {        // suspended literal run        nbytes = OFstatic_cast(unsigned char, (suspendInfo_ & 0x7f) + 1);        suspendInfo_ = 128;        if (compressedSize < nbytes)        {          // we're going to suspend again (oops?), prepare everything          suspendInfo_ = OFstatic_cast(unsigned char, nbytes - compressedSize - 1);          nbytes = OFstatic_cast(unsigned char, compressedSize);          result = EC_StreamNotifyClient;        }        literal(cp, nbytes);        compressedSize -= nbytes;        cp += nbytes;      }      // continue with ordinary RLE decompression      while (compressedSize && (! fail_))      {        ch = *cp++;        --compressedSize;        if (ch & 0x80)        {          // replicate run          if (compressedSize)          {            // DICOM packbit scheme uses 257 - nbytes to represent replicate runs            nbytes = OFstatic_cast(unsigned char, 257 - ch);            ch = *cp++;            --compressedSize;            replicate(ch, nbytes);          }          else          {            // suspension: replicate run but second byte is in next block            suspendInfo_ = ch;            result = EC_StreamNotifyClient;          }        }         else        {          // literal run          nbytes = OFstatic_cast(unsigned char, (ch & 0x7f) + 1);          if (compressedSize < nbytes)          {            // we're going to suspend, prepare everything            suspendInfo_ = OFstatic_cast(unsigned char, nbytes - compressedSize - 1);            nbytes = OFstatic_cast(unsigned char, compressedSize);            result = EC_StreamNotifyClient;          }          literal(cp, nbytes);          compressedSize -= nbytes;          cp += nbytes;        }      }      // failure status at this point means output buffer overflow      if (fail_) result = EC_CorruptedData;    }    return result;  }  /** returns the number of bytes written to the output buffer   *  @return size of decompressed stream, in bytes   */  inline size_t size() const  {    return offset_;  }  /** returns pointer to the output buffer   */  inline void *getOutputBuffer() const  {    return outputBuffer_;  }  /** returns true if the RLE compressor has failed (out of memory or output buffer too small).   */  inline OFBool fail() const  {    if (fail_) return OFTrue; else return OFFalse;  }private:  /// private undefined copy constructor  DcmRLEDecoder(const DcmRLEDecoder&);  /// private undefined copy assignment operator  DcmRLEDecoder& operator=(const DcmRLEDecoder&);  /** this method expands a replicate run   *  @param ch value to replicate   *  @param nbytes number of repetitions   */  inline void replicate(unsigned char ch, unsigned char nbytes)  {     if (offset_ + nbytes > outputBufferSize_)     {       // output buffer overflow       fail_ = 1;       nbytes = OFstatic_cast(unsigned char, outputBufferSize_ - offset_);     }     while (nbytes--) outputBuffer_[offset_++] = ch;  }  /** this method expands a literal run   *  @param cp pointer to buffer   *  @param nbytes number of bytes in buffer   */  inline void literal(unsigned char *cp, unsigned char nbytes)  {     if (offset_ + nbytes > outputBufferSize_)     {       // output buffer overflow       fail_ = 1;       nbytes = OFstatic_cast(unsigned char, outputBufferSize_ - offset_);     }     while (nbytes--) outputBuffer_[offset_++] = *cp++;  }  /* member variables */  /** this flag indicates a failure of the RLE codec.  Once a failure is   *  flagged, the codec will consume all input and not produce any more   *  output.   */  int fail_;  /** size of output buffer, in bytes   */  size_t outputBufferSize_;  /** this member points to a block of size outputBufferSize_   *  (unless fail_ is true). This is the block of data to   *  which the decompressed stream is written   */  unsigned char *outputBuffer_;  /** contains the number of bytes already written to outputBuffer_.   *  Value is always less or equal to outputBufferSize_.   */  size_t offset_;  /** contains suspension information.     *  If not suspended, contains 128.   *  If suspended during a replicate run, contains control byte of repeat run (> 128).   *  If suspended during a literal run, contains number of remaining bytes in literal run minus 1 (< 128).   */  unsigned char suspendInfo_;};#endif/* * CVS/RCS Log * $Log: dcrledec.h,v $ * Revision 1.4  2005/12/08 16:28:36  meichel * Changed include path schema for all DCMTK header files * * Revision 1.3  2003/08/14 09:00:56  meichel * Adapted type casts to new-style typecast operators defined in ofcast.h * * Revision 1.2  2003/03/21 13:06:46  meichel * Minor code purifications for warnings reported by MSVC in Level 4 * * Revision 1.1  2002/06/06 14:52:36  meichel * Initial release of the new RLE codec classes *   and the dcmcrle/dcmdrle tools in module dcmdata * * */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -