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

📄 discalet.h

📁 转化为DIB位图再显示出来的dicom文件C++代码
💻 H
📖 第 1 页 / 共 3 页
字号:
/* * *  Copyright (C) 1996-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:  dcmimgle * *  Author:  Joerg Riesmeier * *  Purpose: DicomScaleTemplates (Header) * *  Last Update:      $Author: meichel $ *  Update Date:      $Date: 2005/12/08 16:48:09 $ *  CVS/RCS Revision: $Revision: 1.25 $ *  Status:           $State: Exp $ * *  CVS/RCS Log at end of file * */#ifndef DISCALET_H#define DISCALET_H#include "dcmtk/config/osconfig.h"#include "dcmtk/dcmdata/dctypes.h"#include "dcmtk/ofstd/ofconsol.h"#include "dcmtk/ofstd/ofcast.h"#include "dcmtk/ofstd/ofstream.h"#include "dcmtk/dcmimgle/ditranst.h"#include "dcmtk/dcmimgle/dipxrept.h"#include "dcmtk/dcmimgle/diutils.h"/*---------------------* *  macro definitions  * *---------------------*/#define SCALE_FACTOR 4096#define HALFSCALE_FACTOR 2048/*--------------------* *  helper functions  * *--------------------*/// help function to set scaling valuesstatic inline void setScaleValues(Uint16 data[],                                  const Uint16 min,                                  const Uint16 max){    register Uint16 remainder = max % min;    Uint16 step0 = max / min;    Uint16 step1 = max / min;    if (remainder > OFstatic_cast(Uint16, min / 2))    {        remainder = min - remainder;        ++step0;    } else        ++step1;    const double count = OFstatic_cast(double, min) / (OFstatic_cast(double, remainder) + 1);    register Uint16 i;    register double c = count;    for (i = 0; i < min; ++i)    {        if ((i >= OFstatic_cast(Uint16, c)) && (remainder > 0))        {            --remainder;            c += count;            data[i] = step1;        }        else            data[i] = step0;    }}/*---------------------* *  class declaration  * *---------------------*//** Template class to scale images (on pixel data level). *  with and without interpolation */template<class T>class DiScaleTemplate  : public DiTransTemplate<T>{ public:    /** constructor, scale clipping area.     *     ** @param  planes     number of planes (1 or 3)     *  @param  columns    width of source image     *  @param  rows       height of source image     *  @param  left_pos   left coordinate of clipping area     *  @param  top_pos    top coordinate of clipping area     *  @param  src_cols   width of clipping area     *  @param  src_rows   height of clipping area     *  @param  dest_cols  width of destination image (scaled image)     *  @param  dest_rows  height of destination image     *  @param  frames     number of frames     *  @param  bits       number of bits per plane/pixel     */    DiScaleTemplate(const int planes,                    const Uint16 columns,           /* resolution of source image */                    const Uint16 rows,                    const signed long left_pos,     /* origin of clipping area */                    const signed long top_pos,                    const Uint16 src_cols,          /* extension of clipping area */                    const Uint16 src_rows,                    const Uint16 dest_cols,         /* extension of destination image */                    const Uint16 dest_rows,                    const Uint32 frames,            /* number of frames */                    const int bits = 0)      : DiTransTemplate<T>(planes, src_cols, src_rows, dest_cols, dest_rows, frames, bits),        Left(left_pos),        Top(top_pos),        Columns(columns),        Rows(rows)    {    }    /** constructor, scale whole image.     *     ** @param  planes     number of planes (1 or 3)     *  @param  src_cols   width of source image     *  @param  src_rows   height of source image     *  @param  dest_cols  width of destination image (scaled image)     *  @param  dest_rows  height of destination image     *  @param  frames     number of frames     *  @param  bits       number of bits per plane/pixel     */    DiScaleTemplate(const int planes,                    const Uint16 src_cols,          /* resolution of source image */                    const Uint16 src_rows,                    const Uint16 dest_cols,         /* resolution of destination image */                    const Uint16 dest_rows,                    const Uint32 frames,            /* number of frames */                    const int bits = 0)      : DiTransTemplate<T>(planes, src_cols, src_rows, dest_cols, dest_rows, frames, bits),        Left(0),        Top(0),        Columns(src_cols),        Rows(src_rows)    {    }    /** destructor     */    virtual ~DiScaleTemplate()    {    }    /** choose scaling/clipping algorithm depending on specified parameters.     *     ** @param  src          array of pointers to source image pixels     *  @param  dest         array of pointers to destination image pixels     *  @param  interpolate  interpolation algorithm (0 = no interpolation, 1 = pbmplus algorithm, 2 = c't algorithm)     *  @param  value        value to be set outside the image boundaries (used for clipping, default: 0)     */    void scaleData(const T *src[],               // combined clipping and scaling UNTESTED for multi-frame images !!                   T *dest[],                   const int interpolate,                   const T value = 0)    {        if ((src != NULL) && (dest != NULL))        {#ifdef DEBUG            if (DicomImageClass::checkDebugLevel(DicomImageClass::DL_DebugMessages))            {                ofConsole.lockCout() << "C/R: " << Columns << " " << Rows << endl                                     << "L/T: " << Left << " " << Top << endl                                     << "SX/Y: " << this->Src_X << " " << this->Src_Y << endl                                     << "DX/Y: " << this->Dest_X << " " << this->Dest_Y << endl;                ofConsole.unlockCout();            }#endif            if ((Left + OFstatic_cast(signed long, this->Src_X) <= 0) || (Top + OFstatic_cast(signed long, this->Src_Y) <= 0) ||                (Left >= OFstatic_cast(signed long, Columns)) || (Top >= OFstatic_cast(signed long, Rows)))            {                                                                   // no image to be displayed#ifdef DEBUG                if (DicomImageClass::checkDebugLevel(DicomImageClass::DL_Informationals))                {                    ofConsole.lockCerr() << "INFO: clipping area is fully outside the image boundaries !" << endl;                    ofConsole.unlockCerr();                }#endif                fillPixel(dest, value);                                         // ... fill bitmap            }            else if ((this->Src_X == this->Dest_X) && (this->Src_Y == this->Dest_Y))                    // no scaling            {                if ((Left == 0) && (Top == 0) && (Columns == this->Src_X) && (Rows == this->Src_Y))                    copyPixel(src, dest);                                       // copying                else if ((Left >= 0) && (OFstatic_cast(Uint16, Left + this->Src_X) <= Columns) &&                         (Top >= 0) && (OFstatic_cast(Uint16, Top + this->Src_Y) <= Rows))                    clipPixel(src, dest);                                       // clipping                else                    clipBorderPixel(src, dest, value);                          // clipping (with border)            }            else if ((interpolate == 1) && (this->Bits <= MAX_INTERPOLATION_BITS))    // interpolation (pbmplus)                interpolatePixel(src, dest);            else if ((interpolate == 2) && (this->Dest_X >= this->Src_X) && (this->Dest_Y >= this->Src_Y))    // interpolated expansion (c't)                expandPixel(src, dest);            else if ((interpolate == 2) && (this->Src_X >= this->Dest_X) && (this->Src_Y >= this->Dest_Y))    // interpolated reduction (c't)                reducePixel(src, dest);            else if ((this->Dest_X % this->Src_X == 0) && (this->Dest_Y % this->Src_Y == 0))            // replication                replicatePixel(src, dest);            else if ((this->Src_X % this->Dest_X == 0) && (this->Src_Y % this->Dest_Y == 0))            // supression                suppressPixel(src, dest);            else                                                                // general scaling                scalePixel(src, dest);        }    } protected:    /// left coordinate of clipping area    const signed long Left;    /// top coordinate of clipping area    const signed long Top;    /// width of source image    const Uint16 Columns;    /// height of source image    const Uint16 Rows; private:    /** clip image to specified area (only inside image boundaries).     *  This is an optimization of the more general method clipBorderPixel().     *     ** @param  src   array of pointers to source image pixels     *  @param  dest  array of pointers to destination image pixels     */    void clipPixel(const T *src[],                   T *dest[])    {        const unsigned long x_feed = Columns - this->Src_X;        const unsigned long y_feed = OFstatic_cast(unsigned long, Rows - this->Src_Y) * OFstatic_cast(unsigned long, Columns);        register Uint16 x;        register Uint16 y;        register const T *p;        register T *q;        for (int j = 0; j < this->Planes; ++j)        {            p = src[j] + OFstatic_cast(unsigned long, Top) * OFstatic_cast(unsigned long, Columns) + Left;            q = dest[j];            for (unsigned long f = this->Frames; f != 0; --f)            {                for (y = this->Dest_Y; y != 0; --y)                {                    for (x = this->Dest_X; x != 0; --x)                        *(q++) = *(p++);                    p += x_feed;                }                p += y_feed;            }        }    }    /** clip image to specified area and add a border if necessary.     *  NOT fully tested - UNTESTED for multi-frame and multi-plane images !!     *     ** @param  src    array of pointers to source image pixels     *  @param  dest   array of pointers to destination image pixels     *  @param  value  value to be set outside the image boundaries     */    void clipBorderPixel(const T *src[],                         T *dest[],                         const T value)    {        const Uint16 s_left = (Left > 0) ? OFstatic_cast(Uint16, Left) : 0;        const Uint16 s_top = (Top > 0) ? OFstatic_cast(Uint16, Top) : 0;        const Uint16 d_left = (Left < 0 ? OFstatic_cast(Uint16, -Left) : 0);        const Uint16 d_top = (Top < 0) ? OFstatic_cast(Uint16, -Top) : 0;        const Uint16 d_right = (OFstatic_cast(unsigned long, this->Src_X) + OFstatic_cast(unsigned long, s_left) <                                OFstatic_cast(unsigned long, Columns) + OFstatic_cast(unsigned long, d_left)) ?                               (this->Src_X - 1) : (Columns + d_left - s_left - 1);        const Uint16 d_bottom = (OFstatic_cast(unsigned long, this->Src_Y) + OFstatic_cast(unsigned long, s_top) <                                 OFstatic_cast(unsigned long, Rows) + OFstatic_cast(unsigned long, d_top)) ?                                (this->Src_Y - 1) : (Rows + d_top - s_top - 1);        const Uint16 x_count = d_right - d_left + 1;        const Uint16 y_count = d_bottom - d_top + 1;        const unsigned long s_start = OFstatic_cast(unsigned long, s_top) * OFstatic_cast(unsigned long, Columns) + s_left;        const unsigned long x_feed = Columns - x_count;        const unsigned long y_feed = OFstatic_cast(unsigned long, Rows - y_count) * Columns;        const unsigned long t_feed = OFstatic_cast(unsigned long, d_top) * OFstatic_cast(unsigned long, this->Src_X);        const unsigned long b_feed = OFstatic_cast(unsigned long, this->Src_Y - d_bottom - 1) * OFstatic_cast(unsigned long, this->Src_X);        /*         *  The approach is to divide the destination image in up to four areas outside the source image         *  plus one area for the source image. The for and while loops are scanning linearly over the         *  destination image and setting the appropriate value depending on the current area. This is         *  different from most of the other algorithms in this toolkit where the source image is scanned         *  linearly.         */        register Uint16 x;        register Uint16 y;        register unsigned long i;        register const T *p;        register T *q;        for (int j = 0; j < this->Planes; ++j)        {            p = src[j] + s_start;            q = dest[j];            for (unsigned long f = this->Frames; f != 0; --f)            {                for (i = t_feed; i != 0; --i)               // top                    *(q++) = value;                for (y = y_count; y != 0; --y)              // middle part:                {                    x = 0;                    while (x < d_left)                      // - left

⌨️ 快捷键说明

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