This file is indexed.

/usr/include/dcmtk/dcmimgle/dcmimage.h is in libdcmtk-dev 3.6.2-3build3.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

   1
   2
   3
   4
   5
   6
   7
   8
   9
  10
  11
  12
  13
  14
  15
  16
  17
  18
  19
  20
  21
  22
  23
  24
  25
  26
  27
  28
  29
  30
  31
  32
  33
  34
  35
  36
  37
  38
  39
  40
  41
  42
  43
  44
  45
  46
  47
  48
  49
  50
  51
  52
  53
  54
  55
  56
  57
  58
  59
  60
  61
  62
  63
  64
  65
  66
  67
  68
  69
  70
  71
  72
  73
  74
  75
  76
  77
  78
  79
  80
  81
  82
  83
  84
  85
  86
  87
  88
  89
  90
  91
  92
  93
  94
  95
  96
  97
  98
  99
 100
 101
 102
 103
 104
 105
 106
 107
 108
 109
 110
 111
 112
 113
 114
 115
 116
 117
 118
 119
 120
 121
 122
 123
 124
 125
 126
 127
 128
 129
 130
 131
 132
 133
 134
 135
 136
 137
 138
 139
 140
 141
 142
 143
 144
 145
 146
 147
 148
 149
 150
 151
 152
 153
 154
 155
 156
 157
 158
 159
 160
 161
 162
 163
 164
 165
 166
 167
 168
 169
 170
 171
 172
 173
 174
 175
 176
 177
 178
 179
 180
 181
 182
 183
 184
 185
 186
 187
 188
 189
 190
 191
 192
 193
 194
 195
 196
 197
 198
 199
 200
 201
 202
 203
 204
 205
 206
 207
 208
 209
 210
 211
 212
 213
 214
 215
 216
 217
 218
 219
 220
 221
 222
 223
 224
 225
 226
 227
 228
 229
 230
 231
 232
 233
 234
 235
 236
 237
 238
 239
 240
 241
 242
 243
 244
 245
 246
 247
 248
 249
 250
 251
 252
 253
 254
 255
 256
 257
 258
 259
 260
 261
 262
 263
 264
 265
 266
 267
 268
 269
 270
 271
 272
 273
 274
 275
 276
 277
 278
 279
 280
 281
 282
 283
 284
 285
 286
 287
 288
 289
 290
 291
 292
 293
 294
 295
 296
 297
 298
 299
 300
 301
 302
 303
 304
 305
 306
 307
 308
 309
 310
 311
 312
 313
 314
 315
 316
 317
 318
 319
 320
 321
 322
 323
 324
 325
 326
 327
 328
 329
 330
 331
 332
 333
 334
 335
 336
 337
 338
 339
 340
 341
 342
 343
 344
 345
 346
 347
 348
 349
 350
 351
 352
 353
 354
 355
 356
 357
 358
 359
 360
 361
 362
 363
 364
 365
 366
 367
 368
 369
 370
 371
 372
 373
 374
 375
 376
 377
 378
 379
 380
 381
 382
 383
 384
 385
 386
 387
 388
 389
 390
 391
 392
 393
 394
 395
 396
 397
 398
 399
 400
 401
 402
 403
 404
 405
 406
 407
 408
 409
 410
 411
 412
 413
 414
 415
 416
 417
 418
 419
 420
 421
 422
 423
 424
 425
 426
 427
 428
 429
 430
 431
 432
 433
 434
 435
 436
 437
 438
 439
 440
 441
 442
 443
 444
 445
 446
 447
 448
 449
 450
 451
 452
 453
 454
 455
 456
 457
 458
 459
 460
 461
 462
 463
 464
 465
 466
 467
 468
 469
 470
 471
 472
 473
 474
 475
 476
 477
 478
 479
 480
 481
 482
 483
 484
 485
 486
 487
 488
 489
 490
 491
 492
 493
 494
 495
 496
 497
 498
 499
 500
 501
 502
 503
 504
 505
 506
 507
 508
 509
 510
 511
 512
 513
 514
 515
 516
 517
 518
 519
 520
 521
 522
 523
 524
 525
 526
 527
 528
 529
 530
 531
 532
 533
 534
 535
 536
 537
 538
 539
 540
 541
 542
 543
 544
 545
 546
 547
 548
 549
 550
 551
 552
 553
 554
 555
 556
 557
 558
 559
 560
 561
 562
 563
 564
 565
 566
 567
 568
 569
 570
 571
 572
 573
 574
 575
 576
 577
 578
 579
 580
 581
 582
 583
 584
 585
 586
 587
 588
 589
 590
 591
 592
 593
 594
 595
 596
 597
 598
 599
 600
 601
 602
 603
 604
 605
 606
 607
 608
 609
 610
 611
 612
 613
 614
 615
 616
 617
 618
 619
 620
 621
 622
 623
 624
 625
 626
 627
 628
 629
 630
 631
 632
 633
 634
 635
 636
 637
 638
 639
 640
 641
 642
 643
 644
 645
 646
 647
 648
 649
 650
 651
 652
 653
 654
 655
 656
 657
 658
 659
 660
 661
 662
 663
 664
 665
 666
 667
 668
 669
 670
 671
 672
 673
 674
 675
 676
 677
 678
 679
 680
 681
 682
 683
 684
 685
 686
 687
 688
 689
 690
 691
 692
 693
 694
 695
 696
 697
 698
 699
 700
 701
 702
 703
 704
 705
 706
 707
 708
 709
 710
 711
 712
 713
 714
 715
 716
 717
 718
 719
 720
 721
 722
 723
 724
 725
 726
 727
 728
 729
 730
 731
 732
 733
 734
 735
 736
 737
 738
 739
 740
 741
 742
 743
 744
 745
 746
 747
 748
 749
 750
 751
 752
 753
 754
 755
 756
 757
 758
 759
 760
 761
 762
 763
 764
 765
 766
 767
 768
 769
 770
 771
 772
 773
 774
 775
 776
 777
 778
 779
 780
 781
 782
 783
 784
 785
 786
 787
 788
 789
 790
 791
 792
 793
 794
 795
 796
 797
 798
 799
 800
 801
 802
 803
 804
 805
 806
 807
 808
 809
 810
 811
 812
 813
 814
 815
 816
 817
 818
 819
 820
 821
 822
 823
 824
 825
 826
 827
 828
 829
 830
 831
 832
 833
 834
 835
 836
 837
 838
 839
 840
 841
 842
 843
 844
 845
 846
 847
 848
 849
 850
 851
 852
 853
 854
 855
 856
 857
 858
 859
 860
 861
 862
 863
 864
 865
 866
 867
 868
 869
 870
 871
 872
 873
 874
 875
 876
 877
 878
 879
 880
 881
 882
 883
 884
 885
 886
 887
 888
 889
 890
 891
 892
 893
 894
 895
 896
 897
 898
 899
 900
 901
 902
 903
 904
 905
 906
 907
 908
 909
 910
 911
 912
 913
 914
 915
 916
 917
 918
 919
 920
 921
 922
 923
 924
 925
 926
 927
 928
 929
 930
 931
 932
 933
 934
 935
 936
 937
 938
 939
 940
 941
 942
 943
 944
 945
 946
 947
 948
 949
 950
 951
 952
 953
 954
 955
 956
 957
 958
 959
 960
 961
 962
 963
 964
 965
 966
 967
 968
 969
 970
 971
 972
 973
 974
 975
 976
 977
 978
 979
 980
 981
 982
 983
 984
 985
 986
 987
 988
 989
 990
 991
 992
 993
 994
 995
 996
 997
 998
 999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
/*
 *
 *  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: Provides main interface to the "DICOM image toolkit"
 *
 */


#ifndef DCMIMAGE_H
#define DCMIMAGE_H

#include "dcmtk/config/osconfig.h"

#include "dcmtk/ofstd/ofcast.h"

#include "dcmtk/dcmimgle/dimoimg.h"
#include "dcmtk/dcmimgle/didispfn.h"
#include "dcmtk/dcmimgle/diutils.h"


/*------------------------*
 *  forward declarations  *
 *------------------------*/

class DcmXfer;
class DcmObject;
class DcmOverlayData;
class DcmLongString;
class DcmUnsignedShort;

class DiPixel;
class DiDocument;
class DiPluginFormat;


/*---------------------*
 *  class declaration  *
 *---------------------*/

/** Interface class for dcmimgle/dcmimage module.
 *  The main purpose of these modules is image display.
 */
class DCMTK_DCMIMGLE_EXPORT DicomImage
{

 public:

 // --- constructors and destructor

    /** constructor, open a DICOM file.
     *  Opens specified file and reads image related data, creates internal representation
     *  of image data.  Use getStatus() to obtain detailed information about any errors.
     *
     ** @param  filename  the DICOM file
     *  @param  flags     configuration flags (see diutils.h, CIF_MayDetachPixelData is set automatically)
     *  @param  fstart    first frame to be processed (optional, 0 = 1st frame), all subsequent use
     *                    of parameters labeled 'frame' in this class refers to this start frame.
     *  @param  fcount    number of frames (optional, 0 = all frames)
     */
    DicomImage(const char *filename,
               const unsigned long flags = 0,
               const unsigned long fstart = 0,
               const unsigned long fcount = 0);

#ifndef STARVIEW
    /** constructor, use a given DcmObject
     *
     ** @param  object  pointer to DICOM data structures (fileformat, dataset or item).
     *                  (do not delete while referenced, i.e. while this image object or any
     *                   descendant exists; not deleted within dcmimage unless configuration flag
     *                   CIF_TakeOverExternalDataset is set - in this case do not delete it at all)
     *  @param  xfer    transfer syntax of the 'object'.
     *                  (could also be EXS_Unknown in case of fileformat or dataset)
     *  @param  flags   configuration flags (CIF_xxx, see diutils.h)
     *  @param  fstart  first frame to be processed (optional, 0 = 1st frame), all subsequent use
     *                  of parameters labeled 'frame' in this class refers to this start frame.
     *  @param  fcount  number of frames (optional, 0 = all frames)
     */
    DicomImage(DcmObject *object,
               const E_TransferSyntax xfer,
               const unsigned long flags = 0,
               const unsigned long fstart = 0,
               const unsigned long fcount = 0);

    /** constructor, use a given DcmObject with specified rescale/slope.
     *  NB: This constructor ignores the Photometric Interpretation stored in the DICOM dataset
     *      and always creates a MONOCHROME2 image - useful in combination with Presentation States.
     *
     ** @param  object     pointer to DICOM data structures (fileformat, dataset or item).
     *                     (do not delete while referenced, i.e. while this image object or any
     *                      descendant exists; not deleted within dcmimage unless configuration flag
     *                      CIF_TakeOverExternalDataset is set - in this case do not delete it at all)
     *  @param  xfer       transfer syntax of the 'object'.
     *                     (could also be EXS_Unknown in case of fileformat or dataset)
     *  @param  slope      rescale slope (modality transformation)
     *  @param  intercept  rescale intercept (modality transformation)
     *  @param  flags      configuration flags (CIF_xxx, see diutils.h)
     *  @param  fstart     first frame to be processed (optional, 0 = 1st frame), all subsequent use
     *                     of parameters labeled 'frame' in this class refers to this start frame.
     *  @param  fcount     number of frames (optional, 0 = all frames)
     */
    DicomImage(DcmObject *object,
               const E_TransferSyntax xfer,
               const double slope,
               const double intercept,
               const unsigned long flags = 0,
               const unsigned long fstart = 0,
               const unsigned long fcount = 0);

    /** constructor, use a given DcmObject with specified modality LUT.
     *  NB: This constructor ignores the Photometric Interpretation stored in the DICOM dataset
     *      and always creates a MONOCHROME2 image - useful in combination with Presentation States.
     *
     ** @param  object       pointer to DICOM data structures (fileformat, dataset or item).
     *                       (do not delete while referenced, i.e. while this image object or any
     *                        descendant exists; not deleted within dcmimage unless configuration flag
     *                        CIF_TakeOverExternalDataset is set - in this case do not delete it at all)
     *  @param  xfer         transfer syntax of the 'object'.
     *                       (could also be EXS_Unknown in case of fileformat or dataset)
     *  @param  data         dataset element containing modality LUT data
     *  @param  descriptor   dataset element containing modality LUT descriptor
     *  @param  explanation  dataset element containing modality LUT explanation
     *  @param  flags        configuration flags (CIF_xxx, see diutils.h)
     *  @param  fstart       first frame to be processed (optional, 0 = 1st frame), all subsequent use
     *                       of parameters labeled 'frame' in this class refers to this start frame.
     *  @param  fcount       number of frames (optional, 0 = all frames)
     */
    DicomImage(DcmObject *object,
               E_TransferSyntax xfer,
               const DcmUnsignedShort &data,
               const DcmUnsignedShort &descriptor,
               const DcmLongString *explanation = NULL,
               const unsigned long flags = 0,
               const unsigned long fstart = 0,
               const unsigned long fcount = 0);
#endif

    /** destructor
     */
    virtual ~DicomImage();


 // --- multi-frame handling

    /** process next couple of frames.  If the image object has been created with less than the number
     *  of frames stored in the DICOM image, this function allows for accessing the subsequent frames.
     *  Multiple calls to this function allow for successively processing all frames stored in the
     *  file or dataset.  See parameters 'fstart' and 'fcount' of the constructor for how to initially
     *  create an instance of this class.
     *  NB: Only "original" images can be processed in this way, i.e. images that were created by one
     *      of the above constructors.  Images that were created by one of the createXXX() methods can
     *      not be processed since they are derived from original image data in a certain way, e.g.
     *      scaled.
     *
     ** @param  fcount  number of frames to be processed (0 = same number as before)
     *
     ** @return status, true if successful, false otherwise
     */
    inline int processNextFrames(const unsigned long fcount = 0)
    {
        return (Image != NULL) ?
            Image->processNextFrames(fcount) : 0;
    }


 // --- information: return requested value if successful

    /** convert status code to status string
     *
     ** @param  status  code of current internal status
     *
     ** @return pointer to status string
     */
    static const char *getString(const EI_Status status);

    /** convert photometric interpretation code to interpretation string (defined term)
     *
     ** @param  interpret  code of image's photometric interpretation
     *
     ** @return pointer to photometric interpretation string
     */
    static const char *getString(const EP_Interpretation interpret);

    /** get current status information
     *
     ** @return status code
     */
    inline EI_Status getStatus() const
    {
        return (Image != NULL) ?
            Image->getStatus() : ImageStatus;
    }

    /** get number of frames.
     *  Please note that this function does not return the number of frames stored in the
     *  DICOM file/dataset (use getNumberOfFrames() instead).  It rather refers to the
     *  number of frames processed by this class (see constructors for details).
     *
     ** @return number of frames processed by this class
     */
    inline unsigned long getFrameCount() const
    {
        return (Image != NULL) ?
            Image->getNumberOfFrames() : 0;
    }

    /** get index of first frame.
     *  This functions returns the index of the first frame processed by this class (see
     *  constructors for details).
     *
     ** @return index of first frame (0..n-1)
     */
    inline unsigned long getFirstFrame() const
    {
        return (Image != NULL) ?
            Image->getFirstFrame() : 0;
    }

    /** get number of frames stored in the DICOM file/dataset.
     *  This attribute is mandatory for DICOM images with multiple frames.
     *  For single frame images, the value defaults to 1.
     *
     ** @return number of frames stored in the DICOM file/dataset
     */
    inline unsigned long getNumberOfFrames() const
    {
        return (Image != NULL) ?
            Image->getTotalNumberOfFrames() : 0;
    }

    /** get index of representative frame.
     *  This attribute is optionally stored in the DICOM dataset (type 3).
     *
     ** @return index of representative frame (0..n-1)
     */
    inline unsigned long getRepresentativeFrame() const
    {
        return (Image != NULL) ?
            Image->getRepresentativeFrame() : 0;
    }

    /** get nominal time (in milliseconds) between individual frames.
     *  This attribute might not always be stored in the DICOM dataset.
     *
     ** @return nominal time between individual frames, 0 if absent
     */
    inline double getFrameTime() const
    {
        return (Image != NULL) ?
            Image->getFrameTime() : 0;
    }

    /** get image width in pixels
     *
     ** @return number of pixels in one row
     */
    inline unsigned long getWidth() const
    {
        return (Image != NULL) ?
            Image->getColumns() : 0;
    }

    /** get image height in pixels
     *
     ** @return number of pixels in one column
     */
    inline unsigned long getHeight() const
    {
        return (Image != NULL) ?
            Image->getRows() : 0;
    }

    /** get image depth
     *
     ** @return number of bits per sample of the internal representation
     */
    inline int getDepth() const
    {
        return (Image != NULL) ?
            Image->getBits() : 0;
    }

    /** get minimum and maximum pixel values.
     *  the resulting pixel values are stored in 'double' variables to avoid problems
     *  with different number ranges, limited to monochrome images.
     *  Please note that the min/max values refer to the full pixel data (i.e. including
     *  all possible present frames as specified in the constructor of this class).
     *
     ** @param  min   minimum pixel value (reference parameter)
     *  @param  max   maximum pixel value (reference parameter)
     *  @param  mode  0 = min/max 'used' pixel values,
     *                1 = min/max 'possible' pixel values (absolute min/max)
     *
     ** @return status code (true if successful)
     */
    inline int getMinMaxValues(double &min,
                               double &max,
                               const int mode = 0) const
    {
        return ((Image != NULL) && (Image->getMonoImagePtr() != NULL)) ?
            Image->getMonoImagePtr()->getMinMaxValues(min, max, mode) : 0;
    }

    /** get width height ratio (pixel aspect ratio: x/y).
     *  If present in the dataset and not overwritten using setWidthHeightRatio(), the following
     *  attributes are checked in order to determine this value:
     *  - Pixel Spacing, Imager Pixel Spacing, Nominal Scanned Pixel Spacing, Pixel Aspect Ratio.
     *  The first attribute (Pixel Spacing) is checked both on the main dataset level and within
     *  the Pixel Measures Sequence of the Shared Functional Groups Sequence (if present).
     *
     ** @return pixel aspect ratio (floating point value)
     */
    inline double getWidthHeightRatio() const
    {
        return (Image != NULL) ?
            Image->getColumnRowRatio() : 0;
    }

    /** get height width ratio (pixel aspect ratio: y/x).
     *  If present in the dataset and not overwritten using setWidthHeightRatio(), the following
     *  attributes are checked in order to determine this value:
     *  - Pixel Spacing, Imager Pixel Spacing, Nominal Scanned Pixel Spacing, Pixel Aspect Ratio
     *  The first attribute (Pixel Spacing) is checked both on the main dataset level and within
     *  the Pixel Measures Sequence of the Shared Functional Groups Sequence (if present).
     *
     ** @return pixel aspect ratio (floating point value)
     */
    inline double getHeightWidthRatio() const
    {
        return (Image != NULL) ?
            Image->getRowColumnRatio() : 0;
    }

    /** set width height ratio (pixel aspect ratio: x/y)
     *
     ** @param  ratio  pixel aspect ratio (x/y)
     *
     ** @return status code (true if successful)
     */
    inline int setWidthHeightRatio(const double ratio) const
    {
        return (Image != NULL) ?
            Image->setColumnRowRatio(ratio) : 0;
    }

    /** set height width ratio (pixel aspect ratio: y/x)
     *
     ** @param  ratio  pixel aspect ratio (y/x)
     *
     ** @return status code (true if successful)
     */
    inline int setHeightWidthRatio(const double ratio) const
    {
        return (Image != NULL) ?
            Image->setRowColumnRatio(ratio) : 0;
    }

    /** check whether given output value is unused
     *
     ** @param  value  output value to be checked
     *
     ** @return status, true if unused (1 = within output range, 2 = out of range), false otherwise
     */
    inline int isOutputValueUnused(const unsigned long value)
    {
        return ((Image != NULL) && (Image->getMonoImagePtr() != NULL)) ?
            Image->getMonoImagePtr()->isValueUnused(value) : 0;
    }

  // --- output: return pointer to output data if successful

    /** get number of bytes required for the rendered output of a single frame.
     *  This function determines the size of a rendered frame as created by getOutputData().
     *  Therefore, it can be used to allocate a sufficiently large memory buffer and pass
     *  its size to the second variant of getOutputData().
     *
     ** @param  bits  number of bits per sample used to render the pixel data
     *                (image depth, 1..MAX_BITS, 0 means 'bits stored' in the image)
     *                (MI_PastelColor = -1 for true color pastel mode, EXPERIMENTAL)
     *
     ** @return number of bytes if successful, 0 otherwise
     */
    inline unsigned long getOutputDataSize(const int bits = 0) const
    {
        return (Image != NULL) ?
            Image->getOutputDataSize(Image->getBits(bits)) : 0;
    }

    /** render pixel data and return pointer to internal memory buffer.
     *  apply VOI/PLUT transformation and (visible) overlay planes.
     *  internal memory buffer will be delete for the next getBitmap/Output operation.
     *  output data is always padded to 8, 16, 32, ... bits (bits allocated).
     *  Supported output color models: Monochrome 2 for monochrome images and RGB
     *  (or YCbCr_Full if flag CIF_KeepYCbCrColorModel is set) for color images.
     *  The rendered pixel data is always unsigned.
     *
     ** @param  bits    number of bits per sample used to render the pixel data
     *                  (image depth, 1..MAX_BITS, 0 means 'bits stored' in the image)
     *                  (MI_PastelColor = -1 for true color pastel mode, EXPERIMENTAL)
     *  @param  frame   number of frame to be rendered (0..n-1)
     *  @param  planar  0 = color-by-pixel (R1G1B1...R2G2B2...R3G3B3...),
     *                  1 = color-by-plane (R1R2R3...G1G2G3...B1B2B3...)
     *                  (only applicable to multi-planar/color images, otherwise ignored)
     *
     ** @return pointer to internal memory buffer containing rendered pixel data
     *          (if successful, NULL otherwise)
     */
    inline const void *getOutputData(const int bits = 0,
                                     const unsigned long frame = 0,
                                     const int planar = 0)
    {
        return (Image != NULL) ?
            Image->getOutputData(frame, Image->getBits(bits), planar) : NULL;
    }

    /** render pixel data and output to given memory buffer.
     *  apply VOI/PLUT transformation and (visible) overlay planes.
     *  output data is always padded to 8, 16, 32, ... bits (bits allocated).
     *  Supported output color models: Monochrome 2 for monochrome images and RGB
     *  (or YCbCr_Full if flag CIF_KeepYCbCrColorModel is set) for color images.
     *  The rendered pixel data is always unsigned.
     *
     ** @param  buffer  pointer to memory buffer (must already be allocated)
     *  @param  size    size of memory buffer (will be checked whether it is sufficient)
     *  @param  bits    number of bits per sample used to render the pixel data
     *                  (image depth, 1..MAX_BITS, 0 means 'bits stored' in the image)
     *                  (MI_PastelColor = -1 for true color pastel mode, EXPERIMENTAL)
     *  @param  frame   number of frame to be rendered (0..n-1)
     *  @param  planar  0 = color-by-pixel (R1G1B1...R2G2B2...R3G3B3...),
     *                  1 = color-by-plane (R1R2R3...G1G2G3...B1B2B3...)
     *                  (only applicable to multi-planar/color images, otherwise ignored)
     *
     ** @return status code (true if successful)
     */
    inline int getOutputData(void *buffer,
                             const unsigned long size,
                             const int bits = 0,
                             const unsigned long frame = 0,
                             const int planar = 0)
    {
        return (Image != NULL) ?
            Image->getOutputData(buffer, size, frame, Image->getBits(bits), planar) : 0;
    }

    /** render pixel data and return pointer to given plane (internal memory buffer).
     *  apply VOI/PLUT transformation and (visible) overlay planes
     *  internal memory buffer will be delete for the next getBitmap/Output operation.
     *  Supported output color models: Monochrome 2 for monochrome images and RGB
     *  (or YCbCr_Full if flag CIF_KeepYCbCrColorModel is set) for color images.
     *  The rendered pixel data is always unsigned.
     *
     ** @param  plane  number of plane to be rendered
     *
     ** @return pointer to internal memory buffer containing rendered pixel data
     *          (if successful, NULL otherwise)
     */
    inline const void *getOutputPlane(const int plane) const
    {
        return (Image != NULL) ?
            Image->getOutputPlane(plane) : NULL;
    }

    /** delete internal memory buffer used for rendered images.
     *  Save memory if data is no longer needed.
     */
    inline void deleteOutputData() const
    {
        if (Image != NULL)
            Image->deleteOutputData();
    }

  // --- misc

    /** check whether image is monochrome or not.
     *
     ** @return true if image is monochrome, false otherwise (i.e. color image)
     */
    inline int isMonochrome() const
    {
        return (PhotometricInterpretation == EPI_Monochrome1) || (PhotometricInterpretation == EPI_Monochrome2);
    }

    /** get code for photometric interpretation (color model).
     *
     ** @return code for photometric interpretation of the image
     */
    inline EP_Interpretation getPhotometricInterpretation() const
    {
        return PhotometricInterpretation;
    }

    /** check whether image has given SOP class UID.
     *
     ** @param  uid  SOP class UID to be checked
     *
     ** @return true if image has given SOP class UID, false otherwise
     */
    int hasSOPclassUID(const char *uid) const;

    /** get intermediate pixel data representation (read-only).
     *  This function allows to access the pixel data after they have been extracted
     *  from the DICOM data element and the modality transformation has been applied
     *  (if present and not disabled).  Please note that for monochrome images the
     *  internal representation might be signed whereas color images are automatically
     *  converted to unsigned RGB format.  Pixels are aligned to 8, 16 or 32 bits.
     *  Always use DiPixel::getRepresentation() in order to determine the integer
     *  representation of the internally stored pixel data.
     *
     ** @return pointer to intermediate pixel data representation
     */
    inline const DiPixel *getInterData() const
    {
        return (Image != NULL) ?
            Image->getInterData() : NULL;
    }

 // --- display function for output device characteristic (calibration):
 //     only applicable to grayscale images

    /** get display function
     *
     ** @return pointer to current display function, NULL if absent
     */
    inline DiDisplayFunction *getDisplayFunction() const
    {
        return ((Image != NULL) && (Image->getMonoImagePtr() != NULL)) ?
            Image->getMonoImagePtr()->getDisplayFunction() : OFstatic_cast(DiDisplayFunction *, NULL);
    }

    /** set display function
     *
     ** @param  display  object describing the output device characteristic (only referenced!)
     *
     ** @return true if successful, false otherwise
     */
    inline int setDisplayFunction(DiDisplayFunction *display)
    {
        return ((Image != NULL) && (Image->getMonoImagePtr() != NULL)) ?
            Image->getMonoImagePtr()->setDisplayFunction(display) : 0;
    }

    /** set no display function.
     *  disables display function transformation, object is not deleted!
     *
     ** @return true if successful (1 = disabled current function,
     *                              2 = there was no function to disable),
     *          false otherwise
     */
    inline int setNoDisplayFunction()
    {
        return ((Image != NULL) && (Image->getMonoImagePtr() != NULL)) ?
            Image->getMonoImagePtr()->setNoDisplayFunction() : 0;
    }

    /** delete specified display LUT(s)
     *
     ** @param  bits  parameter of LUT to be deleted (0 = all)
     *
     ** @return true if successful, false otherwise
     */
    inline int deleteDisplayLUT(const int bits = 0)
    {
        return ((Image != NULL) && (Image->getMonoImagePtr() != NULL)) ?
            Image->getMonoImagePtr()->deleteDisplayLUT(bits) : 0;
    }

    /** convert P-value to DDL.
     *  conversion uses display LUT if present, linear scaling otherwise.
     *
     ** @param  pvalue  P-value to be converted (0..65535)
     *  @param  ddl     reference to resulting DDL
     *  @param  bits    number of bits for output
     *
     ** @return true if successful (1 = display function transformation,
     *                              2 = linear scaling),
     *          false otherwise
     */
    inline int convertPValueToDDL(const Uint16 pvalue,
                                  Uint16 &ddl,
                                  const int bits = 8)
    {
        return ((Image != NULL) && (Image->getMonoImagePtr() != NULL)) ?
            Image->getMonoImagePtr()->convertPValueToDDL(pvalue, ddl, bits) : 0;
    }

 // --- windowing (voi): only applicable to grayscale images
 //                      return true if successful (see also 'dimoimg.cc')

    /** unset all VOI transformations (windows and LUTs).
     *  only applicable to monochrome images
     *
     ** @return true if successful (1 = previous window/LUT has been valid,
     *                              2 = otherwise),
     *          false otherwise (image is invalid or not monochrome)
     */
    inline int setNoVoiTransformation()
    {
        return ((Image != NULL) && (Image->getMonoImagePtr() != NULL)) ?
            Image->getMonoImagePtr()->setNoVoiTransformation() : 0;
    }

    /** set automatically calculated minimum/maximum window.
     *  possibly active VOI LUT is implicitly disabled.
     *  Please note that the min/max values refer to the full pixel data (i.e. including
     *  all possible present frames as specified in the constructor of this class).
     *
     ** @param  idx  ignore global min/max values if true (1)
     *
     ** @return true if successful (1 = window has changed,
     *                              2 = new window is the same as previous one),
     *          false otherwise
     */
    inline int setMinMaxWindow(const int idx = 0)
    {
        return ((Image != NULL) && (Image->getMonoImagePtr() != NULL)) ?
            Image->getMonoImagePtr()->setMinMaxWindow(idx) : 0;
    }

    /** set automatically calculated histogram window.
     *  possibly active VOI LUT is implicitly disabled.
     *
     ** @param  thresh  threshold value specifying percentage of histogram border which
     *                  shall be ignored (defaut: 5%).
     *
     ** @return true if successful, false otherwise
     */
    inline int setHistogramWindow(const double thresh = 0.05)
    {
        return ((Image != NULL) && (Image->getMonoImagePtr() != NULL)) ?
            Image->getMonoImagePtr()->setHistogramWindow(thresh) : 0;
    }

    /** set automatically calculated VOI window for the specified Region of Interest (ROI).
     *  The ROI is specified by means of a rectangle (left, top, width, height).  Only the part
     *  of the ROI that overlaps with the image is regarded - if the overlapping area is empty
     *  this method returns false (0).
     *  Possibly active VOI LUT is implicitly disabled.
     *
     ** @param  left_pos  x-coordinate of the top left-hand corner of the ROI (starting from 0)
     *  @param  top_pos   y-coordinate of the top left-hand corner of the ROI (starting from 0)
     *  @param  width     width in pixels of the rectangular ROI (minimum: 1)
     *  @param  height    height in pixels of the rectangular ROI (minimum: 1)
     *  @param  frame     index of the frame to be used for calculation (default: 0 = first)
     *
     ** @return true if successful (1 = window has changed,
     *                              2 = new window is the same as previous one),
     *          false otherwise
     */
    inline int setRoiWindow(const unsigned long left_pos,
                            const unsigned long top_pos,
                            const unsigned long width,
                            const unsigned long height,
                            const unsigned long frame = 0)
    {
        return ((Image != NULL) && (Image->getMonoImagePtr() != NULL)) ?
            Image->getMonoImagePtr()->setRoiWindow(left_pos, top_pos, width, height, frame) : 0;
    }

    /** set specified VOI window (given by index to window width/center sequence stored in image
     *  file).
     *  possibly active VOI LUT is implicitly disabled.
     *  NB: This function does nothing if the flag CIF_UsePresentationState is set.
     *
     ** @param  window  index to window width/center sequence (0..n-1)
     *
     ** @return true if successful, false otherwise (none monochrome or invalid index)
     */
    inline int setWindow(const unsigned long window)
    {
        return ((Image != NULL) && (Image->getMonoImagePtr() != NULL)) ?
            Image->getMonoImagePtr()->setWindow(window) : 0;
    }

    /** set specified VOI window (given by window width and center).
     *  possibly active VOI LUT is implicitly disabled.
     *
     ** @param  center  center of specified window
     *  @param  width   width of specified window (>= 1.0)
     *
     ** @return true if successful (1 = window has changed,
     *                              2 = new window is the same as previous one),
     *          false otherwise
     */
    inline int setWindow(const double center,
                         const double width)
    {
        return ((Image != NULL) && (Image->getMonoImagePtr() != NULL)) ?
            Image->getMonoImagePtr()->setWindow(center, width) : 0;
    }

    /** get current VOI window as window center and width values
     *
     ** @param  center  return current window center value
     *  @param  width   return current window width value
     *
     ** @return true if successful, false otherwise
     */
    inline int getWindow(double &center,
                         double &width)
    {
        return ((Image != NULL) && (Image->getMonoImagePtr() != NULL)) ?
            Image->getMonoImagePtr()->getWindow(center, width) : 0;
    }

    /** get number of VOI windows (stored in image file).
     *  NB: This function does nothing if the flag CIF_UsePresentationState is set.
     *
     ** @return number of VOI windows
     */
    inline unsigned long getWindowCount() const
    {
        return ((Image != NULL) && (Image->getMonoImagePtr() != NULL)) ?
            Image->getMonoImagePtr()->getWindowCount() : 0;
    }

    /** set VOI LUT function
     *
     ** @param  function  type of VOI LUT function (default, linear or sigmoid).
     *                    'default' basically means the same as 'linear'.
     *
     ** @return true if successful (1 = function has changed,
     *                              2 = function has not changed),
     *          false otherwise
     */
    inline int setVoiLutFunction(const EF_VoiLutFunction function)
    {
        return ((Image != NULL) && (Image->getMonoImagePtr() != NULL)) ?
            Image->getMonoImagePtr()->setVoiLutFunction(function) : 0;
    }

    /** get VOI LUT function.
     *  possible values are: EFV_Default, EFV_Linear, EFV_Sigmoid.
     *
     ** @return currently active VOI LUT function or EFV_Default if not set
     */
    inline EF_VoiLutFunction getVoiLutFunction() const
    {
        return ((Image != NULL) && (Image->getMonoImagePtr() != NULL)) ?
            Image->getMonoImagePtr()->getVoiLutFunction() : EFV_Default;
    }

    /** set VOI LUT (given by dcmdata elements).
     *  possibly active window/center is implicitly disabled.
     *  Given data is only referenced and not copied! Make sure that the corresponding DcmXXX
     *  objects exist as long as the VOI LUT is set.
     *
     ** @param  data         contains LUT data
     *  @param  descriptor   describes LUT structure
     *  @param  explanation  free form description of VOI LUT (optional)
     *  @param  descripMode  mode specifying the use of the bits per table entry value
     *
     ** @return true if successful, false otherwise
     */
    inline int setVoiLut(const DcmUnsignedShort &data,
                         const DcmUnsignedShort &descriptor,
                         const DcmLongString *explanation = NULL,
                         const EL_BitsPerTableEntry descripMode = ELM_UseValue)
    {
        return ((Image != NULL) && (Image->getMonoImagePtr() != NULL)) ?
            Image->getMonoImagePtr()->setVoiLut(data, descriptor, explanation, descripMode) : 0;
    }

    /** set VOI LUT (given by index to VOI LUT sequence stored in image file).
     *  possibly active window/center is implicitly disabled.
     *  NB: This function does nothing if the flag CIF_UsePresentationState is set.
     *
     ** @param  table  index to VOI LUT sequence (0..n-1)
     *  @param  descripMode  mode specifying the use of the bits per table entry value
     *
     ** @return true if successful, false otherwise (none monochrome or invalid index)
     */
    inline int setVoiLut(const unsigned long table,
                         const EL_BitsPerTableEntry descripMode = ELM_UseValue)
    {
        return ((Image != NULL) && (Image->getMonoImagePtr() != NULL)) ?
            Image->getMonoImagePtr()->setVoiLut(table, descripMode) : 0;
    }

    /** get number of VOI LUTs (stored in image file)
     *
     ** @return number of VOI LUTs
     */
    inline unsigned long getVoiLutCount() const
    {
        return ((Image != NULL) && (Image->getMonoImagePtr() != NULL)) ?
            Image->getMonoImagePtr()->getVoiLutCount() : 0;
    }

    /** get description of active VOI transformation
     *
     ** @return pointer to description text (NULL if absent)
     */
    inline const char *getVoiTransformationExplanation() const
    {
        return ((Image != NULL) && (Image->getMonoImagePtr() != NULL)) ?
            Image->getMonoImagePtr()->getVoiTransformationExplanation() : OFstatic_cast(const char *, NULL);
    }

    /** get description of specified VOI window (stored in the image file)
     *
     ** @param  window       index of the stored VOI window (0..n-1)
     *  @param  explanation  variable in which the explanation string is stored
     *
     ** @return pointer to description text (NULL if absent or index invalid)
     */
    inline const char *getVoiWindowExplanation(const unsigned long window,
                                               OFString &explanation) const
    {
        return ((Image != NULL) && (Image->getMonoImagePtr() != NULL)) ?
            Image->getMonoImagePtr()->getVoiWindowExplanation(window, explanation) : OFstatic_cast(const char *, NULL);
    }

    /** get description of specified VOI LUT (stored in the image file)
     *
     ** @param  table        index of the stored VOI LUT (0..n-1)
     *  @param  explanation  variable in which the explanation string is stored
     *
     ** @return pointer to description text (NULL if absent or index invalid)
     */
    inline const char *getVoiLutExplanation(const unsigned long table,
                                            OFString &explanation) const
    {
        return ((Image != NULL) && (Image->getMonoImagePtr() != NULL)) ?
            Image->getMonoImagePtr()->getVoiLutExplanation(table, explanation) : OFstatic_cast(const char *, NULL);
    }

    /** get description of performed modality LUT transformation
     *
     ** @return pointer to description text (NULL if absent)
     */
    inline const char *getModalityLutExplanation() const
    {
        return ((Image != NULL) && (Image->getMonoImagePtr() != NULL)) ?
            Image->getMonoImagePtr()->getModalityLutExplanation() : OFstatic_cast(const char *, NULL);
    }

 // --- hardcopy parameters

    /** get polarity. applicable to monochrome and color images.
     *  possible values are EPP_Normal and EPP_Reverse
     *
     ** @return currently active polarity mode or EPP_Normal if not applicable
     */
    inline EP_Polarity getPolarity() const
    {
        return (Image != NULL) ?
            Image->getPolarity() : EPP_Normal;
    }

    /** set polarity. applicable to monochrome and color images.
     *
     ** @param  polarity  polarity (normal or reverse)
     *
     ** @return true if successful (1 = polarity has changed,
     *                              2 = polarity has not changed),
     *          false otherwise
     */
    inline int setPolarity(const EP_Polarity polarity)
    {
        return (Image != NULL) ?
            Image->setPolarity(polarity) : 0;
    }

    /** set hardcopy parameters. only applicable to monochrome images.
     *  used to display LinOD images
     *
     ** @param  min      minimum density of the print-out (in hundreds of Optical Density,
     *                   e.g. 150 means 1.5 OD)
     *  @param  max      maximum density of the print-out (ditto)
     *  @param  reflect  reflected ambient light (in candela per square meter - cd/m^2)
     *  @param  illumin  illumination (ditto)
     *
     ** @return true if successful (1 = at least one of the parameters has changed,
     *                              2 = no parameter has changed),
     *          false otherwise
     */
    inline int setHardcopyParameters(const unsigned int min,
                                     const unsigned int max,
                                     const unsigned int reflect,
                                     const unsigned int illumin)
    {
        return ((Image != NULL) && (Image->getMonoImagePtr() != NULL)) ?
            Image->getMonoImagePtr()->setHardcopyParameters(min, max, reflect, illumin) : 0;
    }

 // --- presentation LUT: only applicable to grayscale images

    /** get shape for presentation transformation.
     *  possible values are: ESP_Default, ESP_Identity, ESP_Inverse, ESP_LinOD.
     *  If a presentation LUT is currently active ESP_Default is always returned.
     *
     ** @return currently active presentation LUT shape or ESP_Default if not set
     */
    inline ES_PresentationLut getPresentationLutShape() const
    {
        return ((Image != NULL) && (Image->getMonoImagePtr() != NULL)) ?
            Image->getMonoImagePtr()->getPresentationLutShape() : ESP_Default;
    }

    /** set shape for presentation transformation.
     *  possibly active presentation LUT is implicitly disabled.
     *
     ** @param  shape  presentation LUT shape (default, identity, inverse or lin OD).
     *                 'default' means that the output data is always created with 0 for black
     *                 and maxvalue for white (i.e. monochrome2 data is created for output).
     *
     ** @return true if successful (1 = shape has changed,
     *                              2 = shape has not changed),
     *          false otherwise
     */
    inline int setPresentationLutShape(const ES_PresentationLut shape)
    {
        return ((Image != NULL) && (Image->getMonoImagePtr() != NULL)) ?
            Image->getMonoImagePtr()->setPresentationLutShape(shape) : 0;
    }

    /** set LUT for presentation transformation.
     *  possibly active presentation LUT is implicitly disabled.
     *  Given data is only referenced and not copied! Make sure that the corresponding DcmXXX
     *  objects exist as long as the presentation LUT is set.
     *
     ** @param  data         contains LUT data
     *  @param  descriptor   describes LUT structure
     *  @param  explanation  free form description of presentation LUT (optional)
     *  @param  descripMode  mode specifying the use of the bits per table entry value
     *
     ** @return true if successful, false otherwise
     */
    inline int setPresentationLut(const DcmUnsignedShort &data,
                                  const DcmUnsignedShort &descriptor,
                                  const DcmLongString *explanation = NULL,
                                  const EL_BitsPerTableEntry descripMode = ELM_UseValue)
    {
        return ((Image != NULL) && (Image->getMonoImagePtr() != NULL)) ?
            Image->getMonoImagePtr()->setPresentationLut(data, descriptor, explanation, descripMode) : 0;
    }

    /** get description of active presentation LUT
     *
     ** @return pointer to description text (NULL if absent)
     */
    inline const char *getPresentationLutExplanation() const
    {
        return ((Image != NULL) && (Image->getMonoImagePtr() != NULL)) ?
            Image->getMonoImagePtr()->getPresentationLutExplanation() : OFstatic_cast(const char *, NULL);
    }

    /** set inverse LUT for presentation transformation.
     *  this LUT transform is e.g. used for DICOM print (12->8, 8->12 bit)
     *  possibly active presentation LUT will not be considered!
     *
     ** @param  data         contains LUT data
     *  @param  descriptor   describes LUT structure
     *  @param  descripMode  mode specifying the use of the bits per table entry value
     *
     ** @return true if successful, false otherwise
     */
    inline int setInversePresentationLut(const DcmUnsignedShort &data,
                                         const DcmUnsignedShort &descriptor,
                                         const EL_BitsPerTableEntry descripMode = ELM_UseValue)
    {
        return ((Image != NULL) && (Image->getMonoImagePtr() != NULL)) ?
            Image->getMonoImagePtr()->setInversePresentationLut(data, descriptor, descripMode) : 0;
    }

 // --- overlays: return true (!0) if successful (see also 'diovlay.cc')
 //               only applicable to grayscale images

    /** add specified plane to group of additional overlay planes.
     *  replaces old overlay plane if group number already exists.
     *
     ** @param  group        group number (0x60nn) of overlay plane
     *  @param  width        width of overlay plane (in pixels)
     *  @param  height       height of overlay plane (in pixels)
     *  @param  left_pos     x coordinate of plane origin (referring to image origin)
     *  @param  top_pos      y coordinate of plane origin
     *  @param  data         overlay plane data (dcmdata element)
     *  @param  label        overlay plane label
     *  @param  description  overlay plane description
     *  @param  mode         display mode (see 'diutils.h')
     *
     ** @return false (0) if an error occurred, true otherwise (1 = added new plane,
     *                                                          2 = replaced existing plane)
     */
    inline int addOverlay(const unsigned int group,
                          const signed int left_pos,
                          const signed int top_pos,
                          const unsigned int width,
                          const unsigned int height,
                          const DcmOverlayData &data,
                          const DcmLongString &label,
                          const DcmLongString &description,
                          const EM_Overlay mode = EMO_Default)
    {
        return ((Image != NULL) && (Image->getMonoImagePtr() != NULL)) ?
            Image->getMonoImagePtr()->addOverlay(group, left_pos, top_pos, width, height, data, label, description, mode) : 0;
    }

    /** remove specified (additional) overlay plane
     *
     ** @param  group  group number (0x60nn) of overlay plane
     *
     ** @return false (0) if an error occurred (e.g. plane doesn't exist), true otherwise
     */
    inline int removeOverlay(const unsigned int group)
    {
        return ((Image != NULL) && (Image->getOverlayPtr(1) != NULL)) ?
            Image->getOverlayPtr(1)->removePlane(group) : 0;
    }

    /** remove all additional overlay planes
     *
     ** @return false (0) if an error occurred, true otherwise (1 = all planes deleted,
     *                                                          2 = no planes to be deleted)
     */
    inline int removeAllOverlays()
    {
        return ((Image != NULL) && (Image->getMonoImagePtr() != NULL)) ?
            Image->getMonoImagePtr()->removeAllOverlays() : 0;
    }

    /** check whether specified overlay plane is visible/activated.
     *  see show/hideOverlay() to modify the visibility status.
     *
     ** @param  plane  number (0..15) or group number (0x60nn) of overlay plane
     *  @param  idx    index of overlay group (0 = dataset, 1 = additional), default: 0
     *
     ** @return true (1) if overlay plane is visible, false (0) otherwise
     */
    inline int isOverlayVisible(const unsigned int plane,
                                const unsigned int idx = 0)
    {
        return ((Image != NULL) && (Image->getOverlayPtr(idx) != NULL)) ?
            Image->getOverlayPtr(idx)->isPlaneVisible(plane) : 0;
    }

    /** activate specified overlay plane
     *
     ** @param  plane  number (0..15) or group number (0x60nn) of overlay plane
     *  @param  idx    index of overlay group (0 = dataset, 1 = additional), default: 0
     *
     ** @return false (0) if an error occurred, true otherwise (1 = plane successfully activated,
     *                                                          2 = plane has already been visible)
     */
    inline int showOverlay(const unsigned int plane,
                           const unsigned int idx = 0)
    {
        return ((Image != NULL) && (Image->getOverlayPtr(idx) != NULL)) ?
            Image->getOverlayPtr(idx)->showPlane(plane) : 0;
    }

    /** activate specified overlay plane and change some parameters
     *
     ** @param  plane   number (0..15) or group number (0x60nn) of overlay plane
     *  @param  mode    display mode (see 'diutils.h')
     *  @param  fore    plane's foreground color (in percent, default: 1.0)
     *  @param  thresh  threshold value (in percent, default: 0.5), only for EMO_ThresholdReplace
     *  @param  idx     index of overlay group (0 = dataset, 1 = additional), default: 0
     *
     ** @return false (0) if an error occurred, true otherwise
     */
    inline int showOverlay(const unsigned int plane,
                           const EM_Overlay mode,
                           const double fore = 1.0,
                           const double thresh = 0.5,
                           const unsigned int idx = 0)
    {
        return ((Image != NULL) && (Image->getOverlayPtr(idx) != NULL)) ?
            Image->getOverlayPtr(idx)->showPlane(plane, fore, thresh, mode) : 0;
    }

    /** activate specified overlay plane and change 'pvalue' (only for bitmap shutters)
     *
     ** @param  plane   number (0..15) or group number (0x60nn) of overlay plane
     *  @param  pvalue  P-value used to display overlay plane
     *
     ** @return false (0) if an error occurred, true otherwise
     */
    inline int showOverlay(const unsigned int plane,
                           const Uint16 pvalue)
    {
        return ((Image != NULL) && (Image->getOverlayPtr(1) != NULL)) ?
            Image->getOverlayPtr(1)->showPlane(plane, pvalue) : 0;
    }

    /** activate all overlay planes (make them visible)
     *
     ** @param  idx  index of overlay group (0 = dataset, 1 = additional), default: 0
     *
     ** @return false (0) if an error occurred, true otherwise (1 = planes have been successfully activated,
     *                                                          2 = no planes to be activated)
     */
    inline int showAllOverlays(const unsigned int idx = 0)
    {
        return ((Image != NULL) && (Image->getOverlayPtr(idx) != NULL)) ?
            Image->getOverlayPtr(idx)->showAllPlanes() : 0;
    }

    /** activate all overlay planes and set specified parameters
     *
     ** @param  mode    display mode (see 'diutils.h')
     *  @param  fore    plane's foreground color (in percent, default: 1.0)
     *  @param  thresh  threshold value (in percent, default: 0.5), only for EMO_ThresholdReplace
     *  @param  idx     index of overlay group (0 = dataset, 1 = additional), default: 0
     *
     ** @return false (0) if an error occurred, true otherwise (1 = planes have been successfully activated,
     *                                                          2 = no planes to be activated)
     */
    inline int showAllOverlays(const EM_Overlay mode,
                               const double fore = 1,
                               const double thresh = 0.5,
                               const unsigned int idx = 0)
    {
        return ((Image != NULL) && (Image->getOverlayPtr(idx) != NULL)) ?
            Image->getOverlayPtr(idx)->showAllPlanes(fore, thresh, mode) : 0;
    }

    /** deactivate specified overlay plane
     *
     ** @param  plane  number (0..15) or group number (0x60nn) of overlay plane
     *  @param  idx    index of overlay group (0 = dataset, 1 = additional), default: 0
     *
     ** @return false (0) if an error occurred, true otherwise (1 = plane successfully deactivated,
     *                                                          2 = plane has already been invisible)
     */
    inline int hideOverlay(const unsigned int plane,
                           const unsigned int idx = 0)
    {
        return ((Image != NULL) && (Image->getOverlayPtr(idx) != NULL)) ?
            Image->getOverlayPtr(idx)->hidePlane(plane) : 0;
    }

    /** deactivate all overlay planes (make them invisible)
     *
     ** @param  idx  index of overlay group (0 = dataset, 1 = additional), default: 0
     *
     ** @return false (0) if an error occurred, true otherwise (1 = planes have been successfully deactivated,
     *                                                          2 = no planes to be deactivated)
     */
    inline int hideAllOverlays(const unsigned int idx = 0)
    {
        return ((Image != NULL) && (Image->getOverlayPtr(idx) != NULL)) ?
            Image->getOverlayPtr(idx)->hideAllPlanes() : 0;
    }

    /** move origin of specified overlay plane to given position
     *
     ** @param  plane     number (0..15) or group number (0x60nn) of overlay plane
     *  @param  left_pos  x coordinate of new plane origin (origin = 0)
     *  @param  top_pos   y coordinate of new plane origin (origin = 0)
     *  @param  idx       index of overlay group (0 = dataset, 1 = additional), default: 0
     *
     ** @return false (0) if an error occurred, true otherwise (1 = plane has been successfully moved,
     *                                                          2 = old and new position are equal, nothing to do)
     */
    inline int placeOverlay(const unsigned int plane,
                            const signed int left_pos,
                            const signed int top_pos,
                            const unsigned int idx = 0)
    {
        return ((Image != NULL) && (Image->getOverlayPtr(idx) != NULL)) ?
            Image->getOverlayPtr(idx)->placePlane(plane, left_pos, top_pos) : 0;
    }

    /** get number of overlay planes
     *
     ** @param  idx  index of overlay group (0 = dataset, 1 = additional), default: 0
     *
     ** @return number of overlay planes stored in the image
     */
    inline unsigned int getOverlayCount(const unsigned int idx = 0) const
    {
        return ((Image != NULL) && (Image->getOverlayPtr(idx) != NULL)) ?
            Image->getOverlayPtr(idx)->getCount() : 0;
    }

    /** get group number of specified overlay plane
     *
     ** @param  plane  number (0..15) or group number (0x60nn) of overlay plane
     *  @param  idx    index of overlay group (0 = dataset, 1 = additional), default: 0
     *
     ** @return group number of given overlay plane if successful, false (0) otherwise
     */
    inline unsigned int getOverlayGroupNumber(const unsigned int plane,
                                              const unsigned int idx = 0) const
    {
        return ((Image != NULL) && (Image->getOverlayPtr(idx) != NULL)) ?
            Image->getOverlayPtr(idx)->getPlaneGroupNumber(plane) : 0;
    }

    /** get label of specified overlay plane
     *
     ** @param  plane  number (0..15) or group number (0x60nn) of overlay plane
     *  @param  idx    index of overlay group (0 = dataset, 1 = additional), default: 0
     *
     ** @return pointer to overlay plane label if successful, false (NULL) otherwise
     */
    inline const char *getOverlayLabel(const unsigned int plane,
                                       const unsigned int idx = 0) const
    {
        return ((Image != NULL) && (Image->getOverlayPtr(idx) != NULL)) ?
            Image->getOverlayPtr(idx)->getPlaneLabel(plane) : OFstatic_cast(const char *, NULL);
    }

    /** get description of specified overlay plane
     *
     ** @param  plane  number (0..15) or group number (0x60nn) of overlay plane
     *  @param  idx    index of overlay group (0 = dataset, 1 = additional), default: 0
     *
     ** @return pointer to overlay plane description if successful, false (NULL) otherwise
     */
    inline const char *getOverlayDescription(const unsigned int plane,
                                             const unsigned int idx = 0) const
    {
        return ((Image != NULL) && (Image->getOverlayPtr(idx) != NULL)) ?
            Image->getOverlayPtr(idx)->getPlaneDescription(plane) : OFstatic_cast(const char *, NULL);
    }

    /** get mode of specified overlay plane
     *
     ** @param  plane  number (0..15) or group number (0x60nn) of overlay plane
     *  @param  idx    index of overlay group (0 = dataset, 1 = additional), default: 0
     *
     ** @return mode of overlay plane if successful, EMO_Default otherwise
     */
    inline EM_Overlay getOverlayMode(const unsigned int plane,
                                     const unsigned int idx = 0) const
    {
        return ((Image != NULL) && (Image->getOverlayPtr(idx) != NULL)) ?
            Image->getOverlayPtr(idx)->getPlaneMode(plane) : EMO_Default;
    }

    /** create bitmap for specified overlay plane.
     *  (up to 16 bits per pixel with two values: 'fore' and 'back')
     *  Please note that the current origin of the overlay plane is used.  Furthermore, the size
     *  of the overlay plane is restricted to the size of the surrounding image.  Use the method
     *  getFullOverlayData() if the complete bitmap data is required regardless of its position.
     *
     ** @param  plane     number (0..15) or group number (0x60nn) of overlay plane
     *  @param  width     returns width of overlay plane (in pixels)
     *  @param  height    returns height of overlay plane (in pixels)
     *  @param  left_pos  returns x coordinate of plane's origin
     *  @param  top_pos   returns y coordinate of plane's origin
     *  @param  mode      returns display mode (see 'diutils.h')
     *  @param  frame     index of frame used for output (default: 0 = first)
     *  @param  bits      number of bits (stored) in the resulting array, default: 8, range: 1..16
     *                    Used to mask the values for foreground and background color.  The resulting
     *                    array is always padded to 8 or 16 bits with 1, 8 or 16 bits allocated
     *                    depending on the value of 'bits'.
     *  @param  fore      foreground color to be set in bitmap, default: 255, range: 0..2^bits-1
     *  @param  back      background color to be set in bitmap (transparent), default: 0, range: 0..2^bits-1
     *  @param  idx       index of overlay group (0 = dataset, planes stored in the image dataset;
     *                                            1 = additional, planes added by addOverlay();
     *                                            2 = 'additional' overlay planes hide 'dataset' planes
     *                                                when the overlay group number exists in both),
     *                    default: 2
     *
     ** @return pointer to overlay plane data (internal memory buffer)
     */
    const void *getOverlayData(const unsigned int plane,
                               unsigned int &left_pos,
                               unsigned int &top_pos,
                               unsigned int &width,
                               unsigned int &height,
                               EM_Overlay &mode,
                               const unsigned long frame = 0,
                               const int bits = 8,
                               const Uint16 fore = 0xff,
                               const Uint16 back = 0x0,
                               const unsigned int idx = 2) const
    {
        return ((Image != NULL) && (Image->getMonoImagePtr() != NULL)) ?
            Image->getMonoImagePtr()->getOverlayData(frame, plane, left_pos, top_pos, width, height, mode, idx, bits, fore, back) : NULL;
    }

    /** create bitmap for specified overlay plane.
     *  (up to 16 bits per pixel with two values: 'fore' and 'back')
     *  In contrast to the previous method the full bitmap data is always returned.
     *
     ** @param  plane   number (0..15) or group number (0x60nn) of overlay plane
     *  @param  width   returns width of overlay plane (in pixels)
     *  @param  height  returns height of overlay plane (in pixels)
     *  @param  frame   index of frame used for output (default: 0 = first)
     *  @param  bits    number of bits (stored) in the resulting array, default: 8, range: 1..16
     *                  Used to mask the values for foreground and background color.  The resulting
     *                  array is always padded to 8 or 16 bits with 1, 8 or 16 bits allocated
     *                  depending on the value of 'bits'.
     *  @param  fore    foreground color to be set in bitmap, default: 255, range: 0..2^bits-1
     *  @param  back    background color to be set in bitmap (transparent), default: 0, range: 0..2^bits-1
     *  @param  idx     index of overlay group (0 = dataset, planes stored in the image dataset;
     *                                          1 = additional, planes added by addOverlay()),
     *                  default: 0
     *
     ** @return pointer to overlay plane data (internal memory buffer)
     */
    const void *getFullOverlayData(const unsigned int plane,
                                   unsigned int &width,
                                   unsigned int &height,
                                   const unsigned long frame = 0,
                                   const int bits = 8,
                                   const Uint16 fore = 0xff,
                                   const Uint16 back = 0x0,
                                   const unsigned int idx = 0) const
    {
        return ((Image != NULL) && (Image->getMonoImagePtr() != NULL)) ?
            Image->getMonoImagePtr()->getFullOverlayData(frame, plane, width, height, idx, bits, fore, back) : NULL;
    }

    /** delete buffer for overlay plane data.
     *  Save memory if data is no longer needed.
     */
    inline void deleteOverlayData() const
    {
        if ((Image != NULL) && (Image->getMonoImagePtr() != NULL))
            Image->getMonoImagePtr()->deleteOverlayData();
    }

    /** create bitmap for specified overlay plane and store it in (6xxx,3000) format.
     *  (1 bit allocated and stored, foreground color is 1, background color is 0,
     *   data is 16 bit padded - even length)
     *  memory is allocated but not handled internally - must be deleted from calling program.
     *
     ** @param  buffer  stores pointer to overlay data (memory is allocated internally)
     *  @param  plane   number (0..15) or group number (0x60nn) of overlay plane
     *  @param  width   returns width of overlay plane (in pixels)
     *  @param  height  returns height of overlay plane (in pixels)
     *  @param  frames  returns number of frames
     *  @param  idx     index of overlay group (0 = dataset, planes stored in the image dataset;
     *                                          1 = additional, planes added by addOverlay()),
     *                  default: 0
     *
     ** @return number of bytes allocated for the 'buffer' if successful, 0 otherwise
     */
    unsigned long create6xxx3000OverlayData(Uint8 *&buffer,
                                            const unsigned int plane,
                                            unsigned int &width,
                                            unsigned int &height,
                                            unsigned long &frames,
                                            const unsigned int idx = 0) const
    {
        return ((Image != NULL) && (Image->getMonoImagePtr() != NULL)) ?
            Image->getMonoImagePtr()->create6xxx3000OverlayData(buffer, plane, width, height, frames, idx) : 0;
    }


 // --- create...Image: return pointer to new 'DicomImage' object, memory isn't handled internally !

    /** create copy of current image object.
     *  memory is not handled internally - must be deleted from calling program.
     *
     ** @param  fstart  first frame to be processed (0 = 1st frame)
     *  @param  fcount  number of frames (0 = all frames)
     *
     ** @return pointer to new DicomImage object (NULL if an error occurred)
     */
    DicomImage *createDicomImage(unsigned long fstart = 0,
                                 unsigned long fcount = 0) const;

    /** create scaled copy of current image object (given by exact size).
     *  memory is not handled internally - must be deleted from calling program.
     *
     ** @param  width        width of new image (in pixels)
     *  @param  height       height of new image (in pixels)
     *  @param  interpolate  specifies whether scaling algorithm should use interpolation (if necessary).
     *                       default: no interpolation (0), preferred interpolation algorithm (if applicable):
     *                         1 = pbmplus algorithm, 2 = c't algorithm, 3 = bilinear magnification,
     *                         4 = bicubic magnification
     *  @param  aspect       specifies whether pixel aspect ratio should be taken into consideration
     *                       (if true, width OR height should be 0, i.e. this component will be calculated
     *                        automatically)
     *
     ** @return pointer to new DicomImage object (NULL if an error occurred)
     */
    DicomImage *createScaledImage(const unsigned long width,
                                  const unsigned long height = 0,
                                  const int interpolate = 0,
                                  int aspect = 0) const;

    /** create scaled copy of current image object (given by scaling factors).
     *  memory is not handled internally - must be deleted from calling program.
     *
     ** @param  xfactor      width of new image is multiplied with this factor (> 0)
     *  @param  yfactor      height of new image is multiplied with this factor (> 0)
     *  @param  interpolate  specifies whether scaling algorithm should use interpolation (if necessary).
     *                       default: no interpolation (0), preferred interpolation algorithm (if applicable):
     *                         1 = pbmplus algorithm, 2 = c't algorithm, 3 = bilinear magnification,
     *                         4 = bicubic magnification
     *  @param  aspect       specifies whether pixel aspect ratio should be taken into consideration
     *                       (if true, width OR height should be 0, i.e. this component will be calculated
     *                        automatically)
     *
     ** @return pointer to new DicomImage object (NULL if an error occurred)
     */
    DicomImage *createScaledImage(const double xfactor,
                                  const double yfactor = 0,
                                  const int interpolate = 0,
                                  const int aspect = 0) const;

    /** create scaled copy of specified (clipping) area of the current image object.
     *  memory is not handled internally - must be deleted from calling program.
     *  NB: Clipping and interpolated scaling at the same moment is not yet fully implemented!
     *
     ** @param  left_pos      x coordinate of top left corner of area to be scaled
     *                        (referring to image origin, negative values create a border around the image)
     *  @param  top_pos       y coordinate of top left corner of area to be scaled
     *  @param  clip_width    width of area to be scaled
     *  @param  clip_height   height of area to be scaled
     *  @param  scale_width   width of scaled image (in pixels)
     *  @param  scale_height  height of scaled image (in pixels)
     *  @param  interpolate   specifies whether scaling algorithm should use interpolation (if necessary).
     *                        default: no interpolation (0), preferred interpolation algorithm (if applicable):
     *                          1 = pbmplus algorithm, 2 = c't algorithm, 3 = bilinear magnification,
     *                          4 = bicubic magnification
     *  @param  aspect        specifies whether pixel aspect ratio should be taken into consideration
     *                        (if true, width OR height should be 0, i.e. this component will be calculated
     *                         automatically)
     *  @param  pvalue        P-value used for the border outside the image (0..65535)
     *
     ** @return pointer to new DicomImage object (NULL if an error occurred)
     */
    DicomImage *createScaledImage(const signed long left_pos,
                                  const signed long top_pos,
                                  unsigned long clip_width,
                                  unsigned long clip_height,
                                  unsigned long scale_width = 0,
                                  unsigned long scale_height = 0,
                                  const int interpolate = 0,
                                  int aspect = 0,
                                  const Uint16 pvalue = 0) const;

    /** create scaled copy of specified (clipping) area of the current image object.
     *  memory is not handled internally - must be deleted from calling program.
     *  NB: Clipping and interpolated scaling at the same moment is not yet fully implemented!
     *
     ** @param  left_pos     x coordinate of top left corner of area to be scaled
     *                       (referring to image origin, negative values create a border around the image)
     *  @param  top_pos      y coordinate of top left corner of area to be scaled
     *  @param  width        width of area to be scaled
     *  @param  height       height of area to be scaled
     *  @param  xfactor      width of new image is multiplied with this factor (> 0)
     *  @param  yfactor      height of new image is multiplied with this factor (> 0)
     *  @param  interpolate  specifies whether scaling algorithm should use interpolation (if necessary).
     *                       default: no interpolation (0), preferred interpolation algorithm (if applicable):
     *                         1 = pbmplus algorithm, 2 = c't algorithm, 3 = bilinear magnification,
     *                         4 = bicubic magnification
     *  @param  aspect       specifies whether pixel aspect ratio should be taken into consideration
     *                       (if true, width OR height should be 0, i.e. this component will be calculated
     *                        automatically)
     *  @param  pvalue       P-value used for the border outside the image (0..65535)
     *
     ** @return pointer to new DicomImage object (NULL if an error occurred)
     */
    DicomImage *createScaledImage(const signed long left_pos,
                                  const signed long top_pos,
                                  unsigned long width,
                                  unsigned long height,
                                  const double xfactor,
                                  const double yfactor = 0,
                                  const int interpolate = 0,
                                  const int aspect = 0,
                                  const Uint16 pvalue = 0) const;

    /** create copy of specified area of the current image object (clipping).
     *  memory is not handled internally - must be deleted from calling program.
     *
     ** @param  left_pos  x coordinate of top left corner of area to be copied
     *                    (referring to image origin, negative values create a border around the image)
     *  @param  top_pos   y coordinate of top left corner of area to be copied
     *  @param  width     width of area to be copied/clipped
     *  @param  height    height of area to be copied/clipped
     *  @param  pvalue    P-value used for the border outside the image (0..65535)
     *
     ** @return pointer to new DicomImage object (NULL if an error occurred)
     */
    DicomImage *createClippedImage(const signed long left_pos,
                                   const signed long top_pos,
                                   unsigned long width = 0,
                                   unsigned long height = 0,
                                   const Uint16 pvalue = 0) const;

    /** flip current image (horizontally and/or vertically)
     *
     ** @param  horz  flip horizontally if true
     *  @param  vert  flip vertically if true
     *
     ** @return true if successful (1 = flipped at least direction,
     *                              2 = not flipped, because of image resolution - width and/or height equal to 1),
     *          false otherwise
     */
    int flipImage(int horz = 1,
                  int vert = 0) const;

    /** create a flipped copy of the current image.
     *  memory is not handled internally - must be deleted from calling program.
     *
     ** @param  horz  flip horizontally if true
     *  @param  vert  flip vertically if true
     *
     ** @return pointer to new DicomImage object (NULL if an error occurred)
     */
    DicomImage *createFlippedImage(int horz = 1,
                                   int vert = 0) const;

    /** rotate current image (by steps of 90 degrees)
     *
     ** @param  degree  angle by which the image shall be rotated (-360, -270, -180, -90, 0, 90, 180, 270, 360)
     *
     ** @return true if successful (1 = rotated by at least 90 degrees,
     *                              2 = not rotated, because of image resolution or angle),
     *          false otherwise
     */
    int rotateImage(signed int degree) const;

    /** create a rotated copy of the current image.
     *  memory is not handled internally - must be deleted from calling program.
     *
     ** @param  degree  angle by which the image shall be rotated (-360, -270, -180, -90, 0, 90, 180, 270, 360)
     *
     ** @return pointer to new DicomImage object (NULL if an error occurred)
     */
    DicomImage *createRotatedImage(signed int degree) const;

    /** create monochrome copy of the current image.
     *  equal to createDicomImage() for monochrome images.
     *  memory is not handled internally - must be deleted from calling program.
     *  This method does not work if original YCbCr color model is retained (see CIF_KeepYCbCrColorModel).
     *
     ** @param  red    coefficient by which the red component is weighted (default: NTSC value)
     *  @param  green  coefficient by which the green component is weighted (default: NTSC value)
     *  @param  blue   coefficient by which the blue component is weighted (default: NTSC value)
     *
     ** @return pointer to new DicomImage object (NULL if an error occurred)
     */
    DicomImage *createMonochromeImage(const double red = 0.299,
                                      const double green = 0.587,
                                      const double blue = 0.114) const;

    /** create true color (24/32 bit) or palette (8 bit) bitmap for MS Windows.
     *  8 bit images require an appropriate color palette (256 entries, values: 0 to 255) and are only
     *  applicable to monochrome images, the beginning of a each line starts on a 32-bit address (if
     *  'padding' is true); 24 bit images store 24 bits per pixel (BGR) and do align each line to a
     *  32-bit address (if 'padding' is true); 32 bit images store 32 bits per pixel (ARGB), but only
     *  use the lower 24 bits (-RGB).
     *  The memory buffer can be allocated both externally (from the calling program) and internally
     *  (inside this class/module).  If the 'data' parameter is not NULL and the 'size' parameter, which
     *  describes the size (in bytes) of the allocated buffer, is sufficiently large, the bitmap is stored
     *  in this buffer.  Otherwise (i.e. 'data' is NULL) the memory is allocated internally.  Please note
     *  that in both cases the memory is not handled internally after this method has finished and,
     *  therefore, must be deleted from the calling program.
     *  This method does not work if original YCbCr color model is retained (see CIF_KeepYCbCrColorModel).
     *
     ** @param  data        untyped pointer memory buffer (set to NULL if not allocated externally)
     *  @param  size        size of the memory buffer in bytes (if 0 'data' is set to NULL)
     *  @param  frame       index of frame to be converted (default: 0 = first frame)
     *  @param  bits        number of bits per pixel used for the output bitmap (8, 24 or 32, default: 24)
     *  @param  upsideDown  flag indicating whether the first line stored is the top-most (default: 0) or
     *                      the bottom-most of the source image (as required by the BMP file format)
     *  @param  padding     align each line to a 32-bit address if true (default)
     *
     ** @return number of bytes allocated by the bitmap, or 0 if an error occurred
     */
    unsigned long createWindowsDIB(void *&data,
                                   const unsigned long size,
                                   const unsigned long frame = 0,
                                   const int bits = 24,
                                   const int upsideDown = 0,
                                   const int padding = 1)
    {
        return (Image != NULL) ?
            Image->createDIB(data, size, frame, bits, upsideDown, padding) : 0;
    }

    /** create true color (32 bit) or palette (8 bit) bitmap for Java (AWT default format).
     *  32 bit images allocate 32 bits per pixel (RGB), but only use the upper 24 bits.  The sample
     *  order for color images is: Red, Green, Blue.
     *  Memory is not handled internally - must be deleted from calling program.
     *  This method does not work if original YCbCr color model is retained (see CIF_KeepYCbCrColorModel).
     *
     ** @param  data   resulting pointer to bitmap data (set to NULL if an error occurred)
     *  @param  frame  index of frame to be converted (default: 0 = first frame)
     *  @param  bits   number of bits per pixel used for the output bitmap (8 or 32, default: 32)
     *
     ** @return number of bytes allocated by the bitmap, or 0 if an error occurred
     */
    unsigned long createJavaAWTBitmap(void *&data,
                                      const unsigned long frame = 0,
                                      const int bits = 32)
    {
        return (Image != NULL) ?
            Image->createAWTBitmap(data, frame, bits) : 0;
    }

    /** create 12 bit packed (monochrome) bitmap for DICOM printers.
     *  Memory is not handled internally - must be deleted from calling program.
     *
     ** @param  buffer  pointer to input memory buffer (16 bits allocated, 12 bits stored)
     *  @param  size    size of memory buffer (will be checked whether it is sufficient)
     *  @param  count   number of entries (pixels) in input buffer
     *
     ** @return pointer to memory buffer containing the packed output bitmap data (NULL if an error occurred)
     */
    static void *create12BitPackedBitmap(const void *buffer,
                                         const unsigned long size,
                                         const unsigned long count)
    {
        return DiMonoImage::createPackedBitmap(buffer, size, count, 16, 12);
    }

    /** create new single frame DicomImage with applied grayscale transformations.
     *  The method getOutputData() is used internally for the new bitmap.
     *  Limited to monochrome images.
     *
     ** @param  frame  index of frame to be converted
     *  @param  bits   number of bits per pixel used for the output bitmap
     *
     ** @return pointer to new DicomImage object (NULL if an error occurred)
     */
    DicomImage *createMonoOutputImage(const unsigned long frame,
                                      const int bits);

 // --- output image file: return true ('1') if successful

    /** render pixel data of the given frame and write image related attributes to DICOM dataset.
     *  Applies VOI/PLUT transformation and (visible) overlay planes, output data is
     *  always padded to 8, 16, 32, ... bits (bits allocated).  Replaces any modality
     *  transformation in the dataset by a linear rescale/slope since the modality
     *  transformation is rendered into the pixel data.  Replaces the VOI transformations
     *  in the dataset by a "max range" VOI window.  Removes all Overlay Plane Module
     *  attributes for embedded overlay planes from the dataset.
     *  Writes the following DICOM attributes (from Image Pixel Module):
     *    - Photometric Interpretation, Samples per Pixel
     *    - Columns, Rows, Number of Frames
     *    - Bits Allocated, Bits Stored, High Bit
     *    - Planar Configuration (only if "Samples per Pixel" is greater than 1)
     *    - Pixel Representation, Pixel Data
     *  Updates the following DICOM attributes (if present in the original image dataset):
     *    - Pixel Spacing and/or Pixel Aspect Ratio
     *  Supported output color models: Monochrome 2 for monochrome images and RGB
     *  (or YCbCr_Full if flag CIF_KeepYCbCrColorModel is set) for color images.
     *
     ** @param  dataset  reference to DICOM dataset where the image attributes are stored
     *  @param  bits     number of bits per sample (image depth, 1..MAX_BITS)
     *  @param  frame    number of frame to be rendered (0..n-1)
     *  @param  planar   0 = color-by-pixel (R1G1B1...R2G2B2...R3G3B3...),
     *                   1 = color-by-plane (R1R2R3...G1G2G3...B1B2B3...)
     *                   (only applicable to multi-planar/color images, otherwise ignored)
     *
     ** @return true if successful, false otherwise
     */
    inline int writeFrameToDataset(DcmItem &dataset,
                                   const int bits = 0,
                                   const unsigned long frame = 0,
                                   const int planar = 0)
    {
        return (Image != NULL) ?
            Image->writeFrameToDataset(dataset, frame, bits, planar) : 0;
    }

    /** write current image and related attributes to DICOM dataset.
     *  Uses the internal representation of the pixel data, therefore the output data is
     *  always padded to 8, 16, 32, ... bits (bits allocated).  Replaces any modality
     *  transformation in the dataset by a linear rescale/slope since the modality
     *  transformation is rendered into the pixel data.  Removes all Overlay Plane Module
     *  attributes for embedded overlay planes from the dataset.
     *  Writes the following DICOM attributes (from Image Pixel Module):
     *    - Photometric Interpretation, Samples per Pixel
     *    - Columns, Rows, Number of Frames
     *    - Bits Allocated, Bits Stored, High Bit
     *    - Planar Configuration (only if "Samples per Pixel" is greater than 1)
     *    - Pixel Representation, Pixel Data
     *  Updates the following DICOM attributes (if present in the original image dataset):
     *    - Pixel Spacing and/or Pixel Aspect Ratio
     *  Supported output color models: Monochrome 1 or 2 for monochrome images and RGB
     *  (or YCbCr_Full if flag CIF_KeepYCbCrColorModel is set) for color images.
     *
     ** @param  dataset  reference to DICOM dataset where the image attributes are stored
     *  @param  mode     0 = determine value of BitsStored from 'used' pixel values,
     *                   1 = determine value of BitsStored from 'possible' pixel values
     *                   (used for monochrome images only)
     *  @param  planar   0 = color-by-pixel (R1G1B1...R2G2B2...R3G3B3...),
     *                   1 = color-by-plane (R1R2R3...G1G2G3...B1B2B3...),
     *                   2 = same as original DICOM image (i.e. color-by-pixel or color-by-plane)
     *                   (only applicable to multi-planar/color images, otherwise ignored)
     *
     ** @return true if successful, false otherwise
     */
    inline int writeImageToDataset(DcmItem &dataset,
                                   const int mode = 0,
                                   const int planar = 2)
    {
        return (Image != NULL) ?
            Image->writeImageToDataset(dataset, mode, planar) : 0;
    }

    /** write pixel data to PPM file (specified by filename).
     *  pixel data is written in ASCII format.
     *  This method does not work if original YCbCr color model is retained
     *  (see CIF_KeepYCbCrColorModel).
     *
     ** @param  filename  name of output file (%d is replaced by frame number if present)
     *  @param  bits      number of bits used for output of pixel data
     *                    (default: full resolution, max: 32;
     *                     MI_PastelColor = -1 for true color pastel mode, EXPERIMENTAL)
     *  @param  frame     index of frame used for output (default: first frame = 0)
     *
     ** @return true if successful, false otherwise
     */
    int writePPM(const char *filename,
                 const int bits = 0,
                 const unsigned long frame = 0);

    /** write pixel data to PPM file (specified by open C++ stream).
     *  pixel data is written in ASCII format.
     *  This method does not work if original YCbCr color model is retained
     *  (see CIF_KeepYCbCrColorModel).
     *
     ** @param  stream  open C++ output stream
     *  @param  bits    number of bits used for output of pixel data
     *                  (default: full resolution, max: 32;
     *                   MI_PastelColor = -1 for true color pastel mode, EXPERIMENTAL)
     *  @param  frame   index of frame used for output (default: first frame = 0)
     *
     ** @return true if successful, false otherwise
     */
    int writePPM(STD_NAMESPACE ostream& stream,
                 const int bits = 0,
                 const unsigned long frame = 0);

    /** write pixel data to PPM file (specified by open C stream).
     *  pixel data is written in ASCII format.
     *  This method does not work if original YCbCr color model is retained
     *  (see CIF_KeepYCbCrColorModel).
     *
     ** @param  stream  open C output stream
     *  @param  bits    number of bits used for output of pixel data
     *                  (default: full resolution, max: 32;
     *                   MI_PastelColor = -1 for true color pastel mode, EXPERIMENTAL)
     *  @param  frame   index of frame used for output (default: first frame = 0)
     *
     ** @return true if successful, false otherwise
     */
    int writePPM(FILE *stream,
                 const int bits = 0,
                 const unsigned long frame = 0);

    /** write pixel data to raw PPM file (specified by filename).
     *  pixel data is written in binary format.
     *  This method does not work if original YCbCr color model is retained
     *  (see CIF_KeepYCbCrColorModel).
     *
     ** @param  filename  name of output file (%d is replaced by frame number if present)
     *  @param  bits      number of bits used for output of pixel data
     *                    (default: full resolution, max: 8;
     *                     MI_PastelColor = -1 for true color pastel mode, EXPERIMENTAL)
     *  @param  frame     index of frame used for output (default: first frame = 0)
     *
     ** @return true if successful, false otherwise
     */
    int writeRawPPM(const char *filename,
                    const int bits = 0,
                    const unsigned long frame= 0);

    /** write pixel data to raw PPM file (specified by open C stream).
     *  pixel data is written in binary format.
     *  This method does not work if original YCbCr color model is retained
     *  (see CIF_KeepYCbCrColorModel).
     *
     ** @param  stream  open C output stream (binary mode required!)
     *  @param  bits    number of bits used for output of pixel data
     *                  (default: full resolution, max: 8;
     *                   MI_PastelColor = -1 for true color pastel mode, EXPERIMENTAL)
     *  @param  frame   index of frame used for output (default: first frame = 0)
     *
     ** @return true if successful, false otherwise
     */
    int writeRawPPM(FILE *stream,
                    const int bits = 0,
                    const unsigned long frame = 0);

    /** write pixel data to BMP file (specified by open C stream).
     *  pixel data is written in palette or truecolor mode.
     *  This method does not work if original YCbCr color model is retained
     *  (see CIF_KeepYCbCrColorModel).
     *
     ** @param  stream  open C output stream (binary mode required!)
     *  @param  bits    number of bits used for output of pixel data
     *                  (8, 24 or 32, default (0): 8 for monochrome and 24 for color images)
     *  @param  frame   index of frame used for output (default: first frame = 0)
     *
     ** @return true if successful, false otherwise
     */
    int writeBMP(FILE *stream,
                 const int bits = 0,
                 const unsigned long frame = 0);

    /** write pixel data to BMP file (specified by filename).
     *  pixel data is written in palette or truecolor mode.
     *  This method does not work if original YCbCr color model is retained
     *  (see CIF_KeepYCbCrColorModel).
     *
     ** @param  filename  name of output file (%d is replaced by frame number if present)
     *  @param  bits      number of bits used for output of pixel data
     *                    (8, 24 or 32, default (0): 8 for monochrome and 24 for color images)
     *  @param  frame     index of frame used for output (default: first frame = 0)
     *
     ** @return true if successful, false otherwise
     */
    int writeBMP(const char *filename,
                 const int bits = 0,
                 const unsigned long frame = 0);

    /** write pixel data to pluggable image format file (specified by open C stream).
     *  Format specific parameters may be set directly in the instantiated 'plugin' class.
     *
     ** @param  plugin  pointer to image format plugin (derived from abstract class DiPluginFormat)
     *  @param  stream  open C output stream (binary mode required!)
     *  @param  frame   index of frame used for output (default: first frame = 0)
     *
     ** @return true if successful, false otherwise
     */
    int writePluginFormat(const DiPluginFormat *plugin,
                          FILE *stream,
                          const unsigned long frame = 0);

    /** write pixel data to pluggable image format file (specified by filename).
     *  Format specific parameters may be set directly in the instantiated 'plugin' class.
     *
     ** @param  plugin    pointer to image format plugin (derived from abstract class DiPluginFormat)
     *  @param  filename  name of output file (%d is replaced by frame number if present)
     *  @param  frame     index of frame used for output (default: first frame = 0)
     *
     ** @return true if successful, false otherwise
     */
    int writePluginFormat(const DiPluginFormat *plugin,
                          const char *filename,
                          const unsigned long frame = 0);


 protected:

    /** constructor, create copy of given image object with different image data and photometric interpretation
     *
     ** @param  dicom      source object to be copied
     *  @param  image      new image data
     *  @param  interpret  new photometric interpretation
     */
    DicomImage(const DicomImage *dicom,
               DiImage *image,
               const EP_Interpretation interpret = EPI_Unknown);

    /** initialize object.
     *  create internal image object depending on color model. is used for all 'real' constructors.
     */
    void Init();

    /** check whether data dictionary is present
     *
     ** @return true if dictionary is present, false otherwise
     */
    int checkDataDictionary();

    /** get SOP class UID of current image object
     *
     ** @return SOP class UID (or NULL if an error occurred)
     */
    const char *getSOPclassUID() const;

    /** normalize given degree value (for internal use).
     *  negative value are mapped to positive range (-360 -> 0, -270 -> 90, -180 -> 180, -90 -> 270),
     *  360 is set to 0, all other values are rejected
     *
     ** @param  degree  value to be normalized, valid values are: 0, 90, 180, 270
     *
     ** @return true if successful, false otherwise (invalid value)
     */
    int normalizeDegreeValue(signed int &degree) const;


 private:

    /// current state of converting progress (error level)
    EI_Status ImageStatus;
    /// DICOM color model (enumeration)
    EP_Interpretation PhotometricInterpretation;

    /// points to document object
    DiDocument *Document;
    /// points to image object
    DiImage    *Image;

 // --- declarations to avoid compiler warnings

    DicomImage(const DicomImage &);
    DicomImage &operator=(const DicomImage &);
};


#endif