diimage.h 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678
  1. /*
  2. *
  3. * Copyright (C) 1996-2016, 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: DicomImage (Header)
  19. *
  20. */
  21. #ifndef DIIMAGE_H
  22. #define DIIMAGE_H
  23. #include "dcmtk/config/osconfig.h"
  24. #include "dcmtk/dcmdata/dcitem.h"
  25. #include "dcmtk/dcmdata/dcfcache.h"
  26. #ifdef SUNCC
  27. #include "dcmtk/dcmimgle/didocu.h"
  28. #endif
  29. #include "dcmtk/dcmimgle/diovlay.h"
  30. #include "dcmtk/dcmimgle/diutils.h"
  31. #define INCLUDE_CSTDIO
  32. #include "dcmtk/ofstd/ofstdinc.h"
  33. #include "dcmtk/ofstd/ofstream.h"
  34. /*------------------------*
  35. * forward declarations *
  36. *------------------------*/
  37. class DcmPixelData;
  38. class DcmUnsignedShort;
  39. #ifndef SUNCC
  40. class DiDocument;
  41. #endif
  42. class DiPixel;
  43. class DiMonoImage;
  44. class DiInputPixel;
  45. /*---------------------*
  46. * class declaration *
  47. *---------------------*/
  48. /** Base class for images.
  49. * NB: This is an internal class of module dcmimgle/dcmimage. Please do not
  50. * use it directly. Instead use the main interface class DicomImage.
  51. */
  52. class DCMTK_DCMIMGLE_EXPORT DiImage
  53. {
  54. public:
  55. /** constructor
  56. *
  57. ** @param docu pointer to the DICOM document
  58. * @param status status of the image object
  59. * @param spp samples per pixel
  60. */
  61. DiImage(const DiDocument *docu,
  62. const EI_Status status,
  63. const int spp);
  64. /** destructor
  65. */
  66. virtual ~DiImage();
  67. /** process next couple of frames
  68. *
  69. ** @param fcount number of frames to be processed (0 = same number as before)
  70. *
  71. ** @return status, true if successful, false otherwise
  72. */
  73. virtual int processNextFrames(const unsigned long fcount);
  74. /** get status of the image object
  75. *
  76. ** @return status of the image object
  77. */
  78. inline EI_Status getStatus() const
  79. {
  80. return ImageStatus;
  81. }
  82. /** get number of frames
  83. *
  84. ** @return number of frames
  85. */
  86. inline Uint32 getNumberOfFrames() const
  87. {
  88. return NumberOfFrames;
  89. }
  90. /** get index of first frame
  91. *
  92. ** @return index of first frame
  93. */
  94. inline Uint32 getFirstFrame() const
  95. {
  96. return FirstFrame;
  97. }
  98. /** get total number of frames
  99. *
  100. ** @return total number of frames
  101. */
  102. inline Uint32 getTotalNumberOfFrames() const
  103. {
  104. return TotalNumberOfFrames;
  105. }
  106. /** get representative frame
  107. *
  108. ** @return representative frame
  109. */
  110. inline Uint32 getRepresentativeFrame() const
  111. {
  112. return RepresentativeFrame;
  113. }
  114. /** get frame time
  115. *
  116. ** @return frame time
  117. */
  118. inline double getFrameTime() const
  119. {
  120. return FrameTime;
  121. }
  122. /** get number of rows
  123. *
  124. ** @return number of rows
  125. */
  126. inline Uint16 getRows() const
  127. {
  128. return Rows;
  129. }
  130. /** get number of columns
  131. *
  132. ** @return number of columns
  133. */
  134. inline Uint16 getColumns() const
  135. {
  136. return Columns;
  137. }
  138. /** get pixel's width
  139. *
  140. ** @return pixel's width
  141. */
  142. inline double getPixelWidth() const
  143. {
  144. return (PixelWidth > 0) ? PixelWidth : 1;
  145. }
  146. /** get pixel's height
  147. *
  148. ** @return pixel's height
  149. */
  150. inline double getPixelHeight() const
  151. {
  152. return (PixelHeight > 0) ? PixelHeight : 1;
  153. }
  154. /** get pixel's rows/column ratio
  155. *
  156. ** @return pixel's rows/column ratio
  157. */
  158. inline double getRowColumnRatio() const
  159. {
  160. return getPixelHeight() / getPixelWidth();
  161. }
  162. /** get pixel's column/rows ratio
  163. *
  164. ** @return pixel's column/rows ratio
  165. */
  166. inline double getColumnRowRatio() const
  167. {
  168. return getPixelWidth() / getPixelHeight();
  169. }
  170. /** set pixel's rows/column ratio
  171. *
  172. ** @param ratio pixel's rows/column ratio
  173. *
  174. ** @return status, true if successful, false otherwise
  175. */
  176. int setRowColumnRatio(const double ratio);
  177. /** set pixel's column/rows ratio
  178. *
  179. ** @param ratio pixel's column/rows ratio
  180. *
  181. ** @return status, true if successful, false otherwise
  182. */
  183. int setColumnRowRatio(const double ratio);
  184. /** get polarity.
  185. * possible values are EPP_Normal and EPP_Reverse
  186. *
  187. ** @return currently active polarity mode
  188. */
  189. inline EP_Polarity getPolarity() const
  190. {
  191. return Polarity;
  192. }
  193. /** set polarity.
  194. *
  195. ** @param polarity polarity (normal or reverse)
  196. *
  197. ** @return true if successful (1 = polarity has changed,
  198. * 2 = polarity has not changed)
  199. * false otherwise
  200. */
  201. int setPolarity(const EP_Polarity polarity);
  202. /** get number of bits per sample.
  203. * If the optional parameter is specified the value will be checked and in any case
  204. * a valid value will be returned.
  205. *
  206. ** @param bits value to be returned (if less than 1 or greater than the maximum (32)
  207. * the default value will be used which is equal to the bits per sample
  208. * value stored in the DICOM dataset)
  209. *
  210. ** @return status, true if successful, false otherwise
  211. */
  212. virtual int getBits(const int bits = 0) const
  213. {
  214. return ((bits < 1) || (bits > MAX_BITS)) ? BitsPerSample : bits;
  215. }
  216. /** get color model of internal pixel representation.
  217. * Possible values are: EPI_Monochrome1, EPI_Monochrome2, EPI_RGB and EPI_YBR_Full
  218. *
  219. ** @return color model of internal pixel representation
  220. */
  221. virtual EP_Interpretation getInternalColorModel() const = 0;
  222. /** get access to intermediate pixel data representation (abstract)
  223. *
  224. ** @return pointer to intermediate pixel data
  225. */
  226. virtual const DiPixel *getInterData() const = 0;
  227. /** get number of bytes required for the rendered output of a single frame
  228. *
  229. * @param bits number of bits for the output pixel data (depth)
  230. *
  231. ** @return number of bytes if successful, 0 otherwise
  232. */
  233. virtual unsigned long getOutputDataSize(const int bits = 0) const = 0;
  234. /** get pixel data with specified format (abstract).
  235. * (memory is handled internally)
  236. *
  237. ** @param frame number of frame to be rendered
  238. * @param bits number of bits for the output pixel data (depth)
  239. * @param planar flag, whether the output data (for multi-planar images) should be planar or not
  240. *
  241. ** @return untyped pointer to the pixel data if successful, NULL otherwise
  242. */
  243. virtual const void *getOutputData(const unsigned long frame,
  244. const int bits,
  245. const int planar) = 0;
  246. /** get pixel data with specified format (abstract).
  247. * (memory is handled externally)
  248. *
  249. ** @param buffer untyped pointer to the externally allocated memory buffer
  250. * @param size size of the memory buffer in bytes (will be checked)
  251. * @param frame number of frame to be rendered
  252. * @param bits number of bits for the output pixel data (depth)
  253. * @param planar flag, whether the output data (for multi-planar images) should be planar or not
  254. *
  255. ** @return status, true if successful, false otherwise
  256. */
  257. virtual int getOutputData(void *buffer,
  258. const unsigned long size,
  259. const unsigned long frame,
  260. const int bits,
  261. const int planar) = 0;
  262. /** get pixel data of specified plane (abstract).
  263. * (memory is handled internally)
  264. *
  265. ** @param plane number of plane which should be rendered (starting from 0)
  266. *
  267. ** @return untyped pointer to the pixel data if successful, NULL otherwise
  268. */
  269. virtual const void *getOutputPlane(const int plane) const = 0;
  270. /** delete internally handled output memory buffer (abstract)
  271. */
  272. virtual void deleteOutputData() = 0;
  273. /** get pointer to the object managing the overlay planes
  274. *
  275. ** (#)param idx index of overlay group (here: not used, since only applicable for monochrome images)
  276. *
  277. ** @return pointer to the overlay managing object, here: NULL
  278. */
  279. virtual DiOverlay *getOverlayPtr(const unsigned int /*idx*/)
  280. {
  281. return NULL;
  282. }
  283. /** get pointer to monochrome image object
  284. *
  285. ** @return pointer to monochrome image object (here: always NULL)
  286. */
  287. virtual DiMonoImage *getMonoImagePtr()
  288. {
  289. return NULL;
  290. }
  291. /** create copy of current image object (abstract)
  292. *
  293. ** @param fstart first frame to be processed (not fully implemented!)
  294. * @param fcount number of frames (not fully implemented!)
  295. *
  296. ** @return pointer to new DiImage object (NULL if an error occurred)
  297. */
  298. virtual DiImage *createImage(const unsigned long fstart,
  299. const unsigned long fcount) const = 0;
  300. /** create scaled copy of specified (clipping) area of the current image object (abstract).
  301. *
  302. ** @param left_pos x coordinate of top left corner of area to be scaled
  303. * (referring to image origin, negative values create a border around the image)
  304. * @param top_pos y coordinate of top left corner of area to be scaled
  305. * @param clip_width width of area to be scaled
  306. * @param clip_height height of area to be scaled
  307. * @param scale_width width of scaled image (in pixels)
  308. * @param scale_height height of scaled image (in pixels)
  309. * @param interpolate specifies whether scaling algorithm should use interpolation (if necessary).
  310. * default: no interpolation (0), preferred interpolation algorithm (if applicable):
  311. * 1 = pbmplus algorithm, 2 = c't algorithm, 3 = bilinear magnification,
  312. * 4 = bicubic magnification
  313. * @param aspect specifies whether pixel aspect ratio should be taken into consideration
  314. * (if true, width OR height should be 0, i.e. this component will be calculated
  315. * automatically)
  316. * @param pvalue P-value used for the border outside the image (0..65535)
  317. *
  318. ** @return pointer to new DiImage object (NULL if an error occurred)
  319. */
  320. virtual DiImage *createScale(const signed long left_pos,
  321. const signed long top_pos,
  322. const unsigned long clip_width,
  323. const unsigned long clip_height,
  324. const unsigned long scale_width,
  325. const unsigned long scale_height,
  326. const int interpolate,
  327. const int aspect,
  328. const Uint16 pvalue) const = 0;
  329. /** flip current image horizontally and/or vertically (abstract)
  330. *
  331. ** @param horz flip horizontally if true
  332. * @param vert flip vertically if true
  333. *
  334. ** @return true if successful, false otherwise
  335. */
  336. virtual int flip(const int horz,
  337. const int vert) = 0;
  338. /** create a flipped copy of the current image (abstract).
  339. *
  340. ** @param horz flip horizontally if true
  341. * @param vert flip vertically if true
  342. *
  343. ** @return pointer to new DiImage object (NULL if an error occurred)
  344. */
  345. virtual DiImage *createFlip(const int horz,
  346. const int vert) const = 0;
  347. /** rotate current image (by steps of 90 degrees)
  348. *
  349. ** @param degree angle by which the image shall be rotated
  350. *
  351. ** @return true if successful, false otherwise
  352. */
  353. virtual int rotate(const int degree);
  354. /** create a rotated copy of the current image (abstract).
  355. *
  356. ** @param degree angle by which the image shall be rotated
  357. *
  358. ** @return pointer to new DiImage object (NULL if an error occurred)
  359. */
  360. virtual DiImage *createRotate(const int degree) const = 0;
  361. /** create monochrome copy of the current image (abstract).
  362. *
  363. ** @param red coefficient by which the red component is weighted
  364. * @param green coefficient by which the green component is weighted
  365. * @param blue coefficient by which the blue component is weighted
  366. *
  367. ** @return pointer to new DiImage object (NULL if an error occurred)
  368. */
  369. virtual DiImage *createMono(const double red,
  370. const double green,
  371. const double blue) const = 0;
  372. /** create true color (24/32 bit) or palette (8 bit) bitmap for MS Windows (abstract).
  373. *
  374. ** @param data untyped pointer memory buffer (set to NULL if not allocated externally)
  375. * @param size size of the memory buffer in bytes (if 0 'data' is set to NULL)
  376. * @param frame index of frame to be converted (starting from 0)
  377. * @param bits number of bits per pixel used for the output bitmap (8, 24 or 32)
  378. * @param upsideDown specifies the order of lines in the images (0 = top-down, bottom-up otherwise)
  379. * @param padding align each line to a 32-bit address if true (default)
  380. *
  381. ** @return number of bytes allocated by the bitmap, or 0 if an error occurred
  382. */
  383. virtual unsigned long createDIB(void *&data,
  384. const unsigned long size,
  385. const unsigned long frame,
  386. const int bits,
  387. const int upsideDown,
  388. const int padding = 1) = 0;
  389. /** create true color (32 bit) bitmap for Java AWT (abstract).
  390. *
  391. ** @param data resulting pointer to bitmap data (set to NULL if an error occurred)
  392. * @param frame index of frame to be converted
  393. * @param bits number of bits per pixel used for the output bitmap (8 or 32)
  394. *
  395. ** @return number of bytes allocated by the bitmap, or 0 if an error occurred
  396. */
  397. virtual unsigned long createAWTBitmap(void *&data,
  398. const unsigned long frame,
  399. const int bits) = 0;
  400. /** render pixel data of given frame and write image related attributes to DICOM dataset.
  401. *
  402. ** @param dataset reference to DICOM dataset where the image attributes are stored
  403. * @param frame index of frame used for output
  404. * @param bits number of bits used for output of pixel data
  405. * @param planar flag, whether the output data (for multi-planar images) should be planar or not
  406. *
  407. ** @return true if successful, false otherwise
  408. */
  409. int writeFrameToDataset(DcmItem &dataset,
  410. const unsigned long frame = 0,
  411. const int bits = 0,
  412. const int planar = 0);
  413. /** write current image and related attributes to DICOM dataset.
  414. *
  415. ** @param dataset reference to DICOM dataset where the image attributes are stored
  416. * @param mode determine value of BitsStored from 'used' or 'possible' pixel values
  417. * @param planar flag, whether the output data (for multi-planar images) should be planar or not
  418. *
  419. ** @return true if successful, false otherwise
  420. */
  421. virtual int writeImageToDataset(DcmItem &dataset,
  422. const int mode = 0,
  423. const int planar = 2) = 0;
  424. /** write pixel data to PPM file (abstract).
  425. * pixel data is written in ASCII format.
  426. *
  427. ** @param stream open C++ output stream
  428. * @param frame index of frame used for output
  429. * @param bits number of bits used for output of pixel data
  430. *
  431. ** @return true if successful, false otherwise
  432. */
  433. virtual int writePPM(STD_NAMESPACE ostream& stream,
  434. const unsigned long frame,
  435. const int bits) = 0;
  436. /** write pixel data to PPM file (abstract).
  437. * pixel data is written in ASCII format.
  438. *
  439. ** @param stream open C output stream
  440. * @param frame index of frame used for output
  441. * @param bits number of bits used for output of pixel data
  442. *
  443. ** @return true if successful, false otherwise
  444. */
  445. virtual int writePPM(FILE *stream,
  446. const unsigned long frame,
  447. const int bits) = 0;
  448. /** write pixel data to raw PPM file (abstract)
  449. *
  450. ** @param stream open C output stream
  451. * @param frame index of frame used for output
  452. * @param bits number of bits used for output of pixel data
  453. *
  454. ** @return true if successful, false otherwise
  455. */
  456. virtual int writeRawPPM(FILE *stream,
  457. const unsigned long frame,
  458. const int bits) = 0;
  459. /** write pixel data to BMP file
  460. *
  461. ** @param stream open C output stream
  462. * @param frame index of frame used for output (default: first frame = 0)
  463. * @param bits number of bits used for output of pixel data (8, 24 or 32)
  464. *
  465. ** @return true if successful, false otherwise
  466. */
  467. virtual int writeBMP(FILE *stream,
  468. const unsigned long frame,
  469. const int bits);
  470. protected:
  471. /** constructor
  472. *
  473. ** @param docu pointer to the DICOM document
  474. * @param status status of the image object
  475. */
  476. DiImage(const DiDocument *docu,
  477. const EI_Status status);
  478. /** constructor, copy
  479. *
  480. ** @param image pointer to reference image
  481. * @param fstart first frame to be processed
  482. * @param fcount number of frames
  483. */
  484. DiImage(const DiImage *image,
  485. const unsigned long fstart,
  486. const unsigned long fcount);
  487. /** constructor, scale/clip
  488. *
  489. ** @param image pointer to reference image
  490. * @param width number of columns of the new image
  491. * @param height number of rows of the new image
  492. * @param aspect flag indicating whether pixel aspect ratio should be used or not
  493. */
  494. DiImage(const DiImage *image,
  495. const Uint16 width,
  496. const Uint16 height,
  497. const int aspect = 0);
  498. /** constructor, rotate
  499. *
  500. ** @param image pointer to reference image
  501. * @param degree angle by which the image shall be rotated
  502. */
  503. DiImage(const DiImage *image,
  504. const int degree = 0);
  505. /** constructor, createMonoOutput
  506. *
  507. ** @param image pointer to reference image
  508. * @param frame number of frame stored in the new image object
  509. * @param stored number of bits stored
  510. * @param alloc number of bits allocated
  511. */
  512. DiImage(const DiImage *image,
  513. const unsigned long frame,
  514. const int stored,
  515. const int alloc);
  516. /** delete internally handled object for the input pixel data conversion
  517. */
  518. void deleteInputData();
  519. /** check and possibly correct values for pixel spacing, aspect ratio etc.
  520. */
  521. void checkPixelExtension();
  522. /** create input pixel data representation from DICOM dataset structures
  523. */
  524. void convertPixelData();
  525. /** update Image Pixel Module attributes in the given dataset.
  526. * Removes smallest/largest pixel value and updates pixel aspect ratio as well
  527. * as pixel spacing (if required).
  528. * Used in writeXXXToDataset() routines.
  529. *
  530. ** @param dataset reference to DICOM image dataset
  531. */
  532. virtual void updateImagePixelModuleAttributes(DcmItem &dataset);
  533. /** detach pixel data.
  534. * removes storage area used for the pixel data from memory
  535. *
  536. ** @return status, true if successful, false otherwise
  537. */
  538. int detachPixelData();
  539. /// copy of status variable declared in class 'DicomImage'
  540. EI_Status ImageStatus;
  541. /// points to special object, which encapsulates the dcmdata module
  542. const DiDocument *Document;
  543. /// first frame to be processed
  544. Uint32 FirstFrame;
  545. /// number of frames in case of multi-frame images (otherwise '1')
  546. Uint32 NumberOfFrames;
  547. /// total number of frames stored in the dataset
  548. Uint32 TotalNumberOfFrames;
  549. /// number of representative frame, type 3 attribute (default '0')
  550. Uint32 RepresentativeFrame;
  551. /// nominal time between individual frames (0 if absent)
  552. double FrameTime;
  553. /// number of rows (in pixel)
  554. Uint16 Rows;
  555. /// number of columns (in pixel)
  556. Uint16 Columns;
  557. /// width of each pixel according to 'PixelSpacing/AspectRatio'
  558. double PixelWidth;
  559. /// height of each pixel according to 'PixelSpacing/AspectRatio'
  560. double PixelHeight;
  561. /// number of bits allocated for each pixel
  562. Uint16 BitsAllocated;
  563. /// number of bits stored for each pixel (see 'BitsPerSample')
  564. Uint16 BitsStored;
  565. /// position of highest stored bit
  566. Uint16 HighBit;
  567. /// actual number of bits per sample (depth)
  568. int BitsPerSample;
  569. /// number of samples per pixel (1, 3 or 4)
  570. int SamplesPerPixel;
  571. /// polarity (normal or reverse)
  572. EP_Polarity Polarity;
  573. /// is 'true' if pixel data is signed
  574. int hasSignedRepresentation;
  575. /// is 'true' if attribute 'PixelSpacing' is present
  576. int hasPixelSpacing;
  577. /// is 'true' if attribute 'ImagerPixelSpacing' is present
  578. int hasImagerPixelSpacing;
  579. /// is 'true' if attribute 'hasNominalScannedPixelSpacing' is present
  580. int hasNominalScannedPixelSpacing;
  581. /// is 'true' if attribute 'PixelAspectRatio' is present
  582. int hasPixelAspectRatio;
  583. /// is 'false' if derived from original image data (e.g. scaled)
  584. int isOriginal;
  585. /// points to intermediate pixel representation (template object)
  586. DiInputPixel *InputData;
  587. /// file cache object used for partial read
  588. DcmFileCache FileCache;
  589. /// current pixel item fragment (for encapsulated pixel data)
  590. Uint32 CurrentFragment;
  591. // --- declarations to avoid compiler warnings
  592. DiImage(const DiImage &);
  593. DiImage &operator=(const DiImage &);
  594. };
  595. #endif