This file is indexed.

/usr/share/doc/png-definitive-guide/html/chapter05.html is in png-definitive-guide 20060430-1.

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
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
  "http://www.w3.org/TR/html4/loose.dtd">
<HTML>
<HEAD>
<TITLE>Applications: Image Converters (PNG: The Definitive Guide)</TITLE>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">

<!-- http://www.w3.org/TR/REC-CSS2/box.html -->
<STYLE TYPE="text/css">
  P { margin-bottom: 0em }
  UL {
    margin-bottom: 0em;
    margin-top: 0em;
    list-style: disc;
  }
  LI {
    padding: 0px 0px 0px 0px;
    margin: 0px 0px 0px 0px;
  }
</STYLE>

<LINK REV="made" HREF="http://pobox.com/~newt/greg_contact.html">
<!--  Copyright (c) 1999 O'Reilly and Associates.  -->
<!--  Copyright (c) 2002-2006 Greg Roelofs.  -->
</HEAD>

<body bgcolor="#ffffff" text="#000000">


<hr> <!-- -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -->

<a href="chapter04.html"><img width=24 height=13 border=0 align="left"
 src="images/prev.png" alt="&lt;-"></a>

<a href="chapter06.html"><img width=24 height=13 border=0 align="right"
 src="images/next.png" alt="-&gt;"></a>

<div align="center">
  <a href="chapter04.html"><font size="-1" color="#000000"
   ><b>PREVIOUS</b></font></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a
     href="toc.html"><font size="-1" color="#000000"
   ><b>CONTENTS</b></font></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a
     href="chapter06.html"><font size="-1" color="#000000"
   ><b>NEXT</b></font></a>
</div>

<hr> <!-- -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -->


<h1 class="chapter">Chapter 5. Applications: Image Converters</h1>

<div class="htmltoc"><h4 class="tochead">Contents:</h4><p>
<a href="#png.ch05.div.1">5.1. pngcrush</a><br />
<a href="#png.ch05.div.2">5.2. pnmtopng</a><br />
<a href="#png.ch05.div.3">5.3. gif2png</a><br />
<a href="#png.ch05.div.4">5.4. Tiff2png</a><br />
<a href="#png.ch05.div.5">5.5. pngcheck</a><br />
<a href="#png.ch05.div.6">5.6. Other Conversion Programs</a><br />
</p></div>


<p>
<a name="INDEX-392" />
<a name="INDEX-393" />
Conversion to PNG from other image formats (or even from PNG) remains a popular
approach for the simple reason that other formats have traditionally been
better supported by applications. Even with good, current application support
for PNG, users typically have large archives of older images, at least some of
which may they desire to convert to PNG format.</p>


<p>Just as one would like to see certain basic PNG features supported in image
editors (which may be thought of as a special case of conversion utilities,
converting and optionally modifying a previously saved image file) one
would like certain basic PNG features supported in converters. These
include:</p>


<ul><li><p>Preservation of basic image types: RGB, grayscale, and palette-based</p></li><li><p>Option to convert ``truecolor'' images with fewer than 256 colors to
palette-based (or grayscale, if appropriate)</p></li><li><p>Preservation of simple transparency in palette images (e.g., when converting
from GIF), including the ability to reorder the palette so the transparent
entry comes first, which avoids wasting space in PNG's transparency chunk</p></li><li><p>Preservation of <em class="emphasis">unassociated</em> alpha transparency (e.g., when converting
from TIFF)</p></li><li><p>Preservation of gamma, chromaticity, sRGB, or full ICC profile information (see
<a href="chapter10.html">Chapter 10, "Gamma Correction and Precision Color"</a>, for details)</p></li><li><p>Option to preserve ``deep'' samples, such as from 12-bit JPEG or medical images
or 16-bit-per-sample TIFF images</p></li><li><p>Preservation of text information (e.g., from JPEG, GIF, and TIFF images)</p></li><li><p>Preservation of interlacing or ``progressiveness''</p></li><li><p>Option to scan for unused palette entries and eliminate any from the palette</p></li><li><p>Reasonable default compression settings: adaptive filtering turned on for all
image types except palette-based; ``medium'' <em class="emphasis">zlib</em> compression level (say,
between 3 and 7)</p></li><li><p>Option for maximal (slowest) compression</p></li></ul>

<p>
Clearly, different users have different needs, but fundamental things that
should be preserved when converting between image formats include the
basic pixel information, transparency, and text. Items in the preceding
list that involve optimization and compression of PNG images can be
dealt with after the initial conversion is complete, but restoring text
or transparency information that was lost in translation is tedious and
to be avoided if at all possible.</p>


<p>In the next few sections, we will look at a number of conversion utilities
in some detail. Most of these are command-line programs--not because we
want the reader to suffer,<a href="#FOOTNOTE-28">[28]</a>
but because dedicated converters such as these typically do the best job and
are often capable of batch (automated) conversions. I have also listed many
image viewers with conversion capabilities in 
<a href="chapter03.html">Chapter 3, "Applications: Image Viewers"</a> 
and several image editors in 
<a href="chapter04.html">Chapter 4, "Applications: Image Editors"</a>; 
thse are, by necessity, graphical and may be preferable for the casual user.</p><blockquote class="footnote">


<a name="FOOTNOTE-28" /><p>[28] For <em class="emphasis">real</em> suffering, write a book.</p>


</blockquote>


<div class="sect1"><a name="png.ch05.div.1" />
<h2 class="sect1">5.1. pngcrush</h2>


<p><a name="INDEX-394" />What may be the most useful conversion tool of all knows nothing of
any image format other than PNG; it converts PNGs into other
<a name="INDEX-395" />PNGs. pngcrush, by Glenn Randers-Pehrson, is a program for optimizing
PNG images--specifically, for reducing their size as much as
possible, although it can also perform simple housekeeping tasks such
as removing or replacing specific chunks,<a href="#FOOTNOTE-29">[29]</a>
or adding gamma-correction information or simple transparency. It is an
invaluable tool for use in conjunction with other converters and with
commercial image editors, which may not always produce optimal PNG files.</p><blockquote class="footnote">


<a name="FOOTNOTE-29" /><p>[29] PNG's fundamental chunk structure is described in <a href="chapter08.html">Chapter 8, "PNG Basics"</a>.</p>


</blockquote>


<p>pngcrush is currently available as a command-line, shareware program in DOS
and Linux x86 flavors. The DOS version works under Windows 95/98/NT and can
handle long filenames; it may also run in an OS/2 DOS box, but without
long-filename support. The current release, as of January 1999, is version
1.1.3 which has a home page at
<!--
<a href="http://www.netgsi.com/~glennrp/pngcrush/"
>http://www.netgsi.com/~glennrp/pngcrush/</a>.
 -->
<a href="http://pmt.sourceforge.net/pngcrush/"
>http://pmt.sourceforge.net/pngcrush/</a>.
</p>


<p>The simplest pngcrush operation is a basic ``crush'' on a single
file, specifying the output filename:</p>


<blockquote><pre class="code">pngcrush foo.png foo-crushed.png</pre></blockquote>


<p>This results in output that looks something like the following:</p>


<blockquote><pre class="code">pngcrush 1.1.3, Copyright (C) 1998, Glenn Randers-Pehrson.
 | This program was built with libpng version 1.0.3,
 |    Copyright (c) Guy Eric Schalnat, Group 42 Inc.,
 |    Copyright (c) 1996, 1997 Andreas Dilger,
 |    Copyright (c) 1998, 1999, Glenn Randers-Pehrson,
 | and zlib version 1.1.3, Copyright (c) 1998,
 |    Jean-loup Gailly and Mark Adler.
  
   foo.png IDAT length in input file =   148723
   IDAT length with method 1 (fm 0 zl 4 zs 0)=   147533
   IDAT length with method 2 (fm 1 zl 4 zs 0)=   124710
   IDAT length with method 3 (fm 5 zl 4 zs 1)=   110589
   IDAT length with method 9 (fm 5 zl 2 zs 2)=   880073
   IDAT length with method 10 (fm 5 zl 9 zs 1)=    85820
   best pngcrush method = 10 for foo-crushed.png (42.36% reduction)
  
   overall result: 42.36% reduction, 62903 bytes</pre></blockquote>


<p><a name="INDEX-396" />pngcrush typically tries the five or six compression approaches that are, according
to its heuristics, the most likely to compress the best. This involves varying
the different filter and compression settings allowed by the PNG format
(described in <a href="chapter09.html">Chapter 9, "Compression and Filtering"</a>). If pngcrush finds a
method that produces a smaller file than the original, it saves the new file
with that approach. (A 42% reduction as shown in the previous output is typical only of cases in which the
original file was compressed particularly poorly.) Note that pngcrush
operates completely losslessly with respect to the image data; 
the only loss of information it <em class="emphasis">intentionally</em>
allows is the explicit removal or replacement of chunks at the user's
direction (though a limitation in versions of the PNG reference
library prior to 1.0.6 also caused the accidental deletion of unknown,
safe-to-copy chunks).  We'll come back to that shortly.</p>


<p>pngcrush also supports a truly brute-force approach that currently tests 102
different methods but may add more in the future. This rarely improves
compression by more than a tenth of a percent over the default approach, but
for busy sites looking to conserve bandwidth, saving even a dozen bytes may
be well worth the cost of a very lengthy--but one-time--pngcrush session.
The brute-force method is invoked with the <b class="emphasis-bold">-brute</b> option, logically
enough:</p>


<blockquote><pre class="code">pngcrush -brute foo.png foo-crushed.png</pre></blockquote>


<p>In general, a site optimizing its content will want to crush all of its PNG
images (by using batch-mode conversion), and pngcrush includes two options to
support batch conversion. The first allows 
<?x-need 15?>one to specify a new extension for converted
images, which will be created in the same directory as the original:</p>


<blockquote><pre class="code">pngcrush -e -crushed.png foo.png foo2.png foo3.png foo4.png</pre></blockquote>


<p>This example crushes four images, <em class="emphasis">foo.png</em> through <em class="emphasis">foo4.png</em>,
giving them the extension <em class="emphasis">-crushed.png</em>; thus the output names are
<em class="emphasis">foo-crushed.png</em>, <em class="emphasis">foo2-crushed.png</em>, and so on. Such an approach
is handy for casual use, since an alphabetical directory listing will (usually)
list the original and crushed versions in pairs, allowing quick, after-the-fact
inspection of the changes in file sizes. But because it involves renaming
files, this is probably not the preferred approach for a web site. The
alternative is pngcrush's <b class="emphasis-bold">-d</b> option, which allows one to specify an
output directory in which to place the crushed images:</p>


<blockquote><pre class="code">pngcrush -d crushed_images foo.png foo2.png foo3.png foo4.png</pre></blockquote>


<p>This example crushes the same four images, but leaves their filenames unchanged.
The new versions will go in the <em class="emphasis">crushed_images</em> subdirectory, which
will be created if it does not already exist.</p>


<p>The <b class="emphasis-bold">-rem</b> option
allows one to remove PNG chunks. This is quite handy, and is often a great way
to trim a few dozen bytes from files (which can make a big difference in the
case of small web graphics), but it does require knowledge of PNG's
chunk names. The following example removes any timestamp chunks and both
compressed and uncompressed text chunks from <em class="emphasis">foo.png</em> and places the
result in the <em class="emphasis">crushed</em> subdirectory:</p>


<blockquote><pre class="code">pngcrush -d crushed -rem tIME -rem zTXt -rem tEXt -rem iTXt foo.png</pre></blockquote>


<p>Note that this approach is somewhat akin to doing surgery with a hatchet:
one has no control over specific instances of the listed chunks in the case
of those (like zTXt, tEXt, and iTXt) that may appear more than once. In
particular, the tEXt or iTXt chunk is where copyright info usually appears,
and that is usually not something one wants to remove.<a href="#FOOTNOTE-30">[30]</a>
</p><blockquote class="footnote">


<a name="FOOTNOTE-30" /><p>[30] Of course, if a copyright is also embedded in the image data itself, the text
version may be superfluous.</p>


</blockquote>


<p><a name="INDEX-397" />One last option is worth a quick look. pngcrush's <b class="emphasis-bold">-g</b> option allows
one to set the gamma value of the image, which in turn provides for
cross-platform consistency of the overall brightness of the image. <a href="chapter10.html">Chapter 10, "Gamma Correction and Precision Color"</a>
covers gamma and color correction in more detail, but the effect will be
familiar to any site that uses both Macintoshes and PCs: images that look
good on Macs tend to look too dark on PCs, and images that look good on PCs
tend to look too bright and washed out on Macs. The solution 
<?x-need 10?>is to include information about the system on which the image was
created, and PNG's gAMA chunk is the simplest and most effective means
of doing so. Unfortunately, not all image editors support gamma in
PNG, and as you saw in the previous chapter, some of those that do
support it store the wrong value. A site that has just received a
batch of PNG images from its Mac-based design department might do
something like the following:</p>


<blockquote><pre class="code">pngcrush -d crushed -replace_gamma 0.65909 mac.png mac2.png mac3.png</pre></blockquote>


<p>For images from a PC-based design group, the corresponding command is:</p>


<blockquote><pre class="code">pngcrush -d crushed -replace_gamma 0.45455 pc.png pc2.png pc3.png</pre></blockquote>


<p>In addition to optimizing the sizes of the images, these examples
strip any existing gamma information out of the files, on the
assumption that the values are known to be wrong and replace it with
values that are appropriate for stock Macs (with a factory-default
``system gamma'' value of 1.8) or stock PCs. If it is known that the
images that have gamma information are correct, use the <b class="emphasis-bold">-g</b>
option instead; it will add a gAMA chunk only to those images that do
not already have one.</p>


<p>I should note that pngcrush is still a relatively new utility, and it
does have a number of rough edges yet. For example, if an output file
already exists, it will be overwritten without warning. There is also
no recursion, no support for wildcards other than what the operating
system provides (i.e., only under Unix), and no way to set a default
extension or directory for crushed files (say, via an environment variable).
The program's extended options also assume a fairly advanced knowledge of
PNG files--for example, the official names


of PNG chunks, in the case of the <b class="emphasis-bold">-rem</b> option, or the numerical
color types used internally by PNG, or the precise palette index of the
color to be made transparent, in the case of the <b class="emphasis-bold">-trns</b> option.<a href="#FOOTNOTE-31">[31]</a>
Nor is there yet support for counting colors in images and automatically
converting from, say, RGB to palette format, although this is planned for
a future version. But these are relatively minor user interface issues
that will undoubtedly improve as the application matures. As regards its primary
purpose of squeezing PNG images as tightly as possible, pngcrush is quite
capable, and is likely to become an indispensable addition to the toolchest of
any image-wrangler.




<a name="INDEX-398" /></p><blockquote class="footnote">


<a name="FOOTNOTE-31" /><p>[31] Newer versions of pngcrush will print the palette, including indices, when
given both the <b class="emphasis-bold">-n</b> (``no crush'') and <b class="emphasis-bold">-verbose</b> options.</p>


</blockquote>
</div>

















</div>
<div class="sect1"><a name="png.ch05.div.2" />
<h2 class="sect1">5.2. pnmtopng</h2>


<p>
<a name="INDEX-399" />
Possibly the most complete conversion program in existence, at least with
respect to support for PNG features, is <em class="emphasis">pnmtopng</em>. In conjunction with
its inverse, 
<?hypen-place ?><em class="emphasis">pngtopnm</em>, 
<?x-need 10?>and the rest of the NetPBM suite,<a href="#FOOTNOTE-32">[32]</a>
it is capable of handling basic conversions to and from virtually any image
format. But pnmtopng really shines as a tool for adding and modifying PNG
chunk information, including such things as text annotations, palette
optimization, and support for adding or removing alpha (transparency) channels.</p><blockquote class="footnote">


<a name="FOOTNOTE-32" /><p>[32] NetPBM originated as the PBMplus package, last released in December
1991. Subsequent third-party contributions from the Internet were gathered together
and released as NetPBM in 1993 and early 1994, containing some 200 utilities
for converting and manipulating images. The package has lain dormant since
then, aside from the occasional appearance of utilities to support new image
formats like PNG, but further news on this front is expected in 1999.</p>


</blockquote>


<p>Currently, the latest version of pnmtopng is 2.37.2, released in March
1999; it can be found on the PNG home site,
<a href="http://www.libpng.org/pub/png/apps/pnmtopng.html">http://www.libpng.org/pub/png/apps/pnmtopng.html</a>, along
with pointers to the libraries on which it depends.</p>


<p>Written and maintained by Alexander Lehmann and Willem van Schaik with
contributions and fixes from others, pnmtopng is primarily a
Unix-based tool, which unfortunately limits its usefulness to a
minority of computer users. But other parts of the NetPBM suite have
been ported to OS/2 and Windows, and it is likely that a future
release of both pnmtopng and NetPBM will be more portable and may even
include ready-to-go executables.</p>


<p><a name="INDEX-400" />
<a name="INDEX-401" />To begin explaining some of pnmtopng's features, it is first necessary to
describe a little about the PBM format itself. If one wishes to
be able to convert any of 100 possible image formats into any other, there
are two options: write 10,000 individual converters to go directly from
format A to format B for all possible pairs of A and B; or write only 200
converters, 100 to go from each of the image formats into some intermediate
representation and another 100 to convert back from that intermediate format
into the 100 target formats. Once the intermediate format exists, one
need not stop at conversion programs; generic utilities to manipulate images
suddenly become possible--for example, quantization, smoothing, cropping,
contrast enhancement, and so on.


</p>


<p>PBMplus/NetPBM is that intermediate format. It was originally designed by
Jef Poskanzer and released as the PBMplus suite, with later ``interim''
packages 


released as NetPBM by Bill Davidsen. Since there has never been another PBMplus
release, I will henceforth refer to the format as NetPBM, the name by which it
is now most commonly known. The format is quite simple: three lines of text
header--which may additionally include one or more comment lines--followed
by the uncompressed image data. The image data may be stored as either text
or binary values; the latter is more efficient and far more commonly used, but
the existence of the text format means that one can actually create images or
color palettes in an ordinary text editor. There are also three basic NetPBM
image flavors: bilevel (or black and white), which is referred to as a
<a name="INDEX-402" />
<a name="INDEX-403" />
<a name="INDEX-404" />
<a name="INDEX-405" /><em class="emphasis">portable bitmap</em> or PBM file; grayscale, called a <em class="emphasis">portable graymap</em>
or PGM; and truecolor (RGB), referred to as a <em class="emphasis">portable pixmap</em> or PPM
file. Programs that can deal with more than one flavor 
<?x-need 10?>usually have ``PNM''
in their names; this stands for <em class="emphasis">portable anymap</em>. There is currently no
``real'' PNM format; it is a virtual format and a convenient catchall name.</p>


<p>One notable feature missing from the NetPBM format is provision for
alpha channels; this is a known limitation<a href="#FOOTNOTE-33">[33]</a>
with implications for converting between formats that support transparency,
such as PNG, GIF, and TIFF. pnmtopng gets around this to some extent by the
simple expedient of storing transparency information in a separate grayscale 
file. Before we get into that, let's look at some simpler cases.</p><blockquote class="footnote">


<a name="FOOTNOTE-33" /><p>[33] Alpha support is a major reason behind the expected NetPBM revisions in 1999.</p>


</blockquote>


<p>pnmtopng is a command-line program, and, thanks to its Unix heritage, it is
designed to operate as part of a multicommand pipeline. Unix pipes are a
slick method of connecting the output of one program into the input of another;
in principle there is no limit to how long such a chain can be, although in 
practice the amount of system resources that are available may constrain
things. Here is a simple example that converts a GIF image into PNG:
<a name="INDEX-406" />
<a name="INDEX-407" /></p>


<blockquote><pre class="code">giftopnm foo.gif | pnmtopng &gt; foo.png</pre></blockquote>


<p>The file <em class="emphasis">foo.gif</em> is read by <em class="emphasis">giftopnm</em> (part of the NetPBM suite)
and converted to NetPBM format, then piped into the input of pnmtopng, which
converts the image to PNG format. Since there are no more programs to be run,
pnmtopng's output is redirected into a file--in this case, <em class="emphasis">foo.png</em>.</p>


<p>Observant readers will recall that GIF images are always palette-based, yet
I didn't say anything about palettes in describing the NetPBM format. In
fact, NetPBM has no concept of palettes; giftopnm usually converts GIF images
into PPM format (the RGB flavor). Fortunately, pnmtopng is smart enough to
count the colors in an image and automatically write a palette-based PNG
image if there are 256 or fewer colors. It will likewise detect if a color
image is actually composed only of gray values; in that case, it will write
either a grayscale PNG or a palette-based one, depending on which can be
written with the fewest bits. This automatic checking comes at a cost, however:
because it requires inspection of every pixel, it can be quite slow for large
images. pnmtopng therefore includes a <b class="emphasis-bold">-force</b> option to skip the
checking. With this option, the previous example would result in
a 24-bit truecolor PNG:</p>


<blockquote><pre class="code">giftopnm foo.gif | pnmtopng -force &gt; foo24.png</pre></blockquote>


<?x-need 10?><p>Here are examples for two other popular image formats, TIFF and JPEG:
<a name="INDEX-408" />
<a name="INDEX-409" /></p>


<blockquote><pre class="code">tifftopnm foo.tiff | pnmtopng &gt; foo-was-tiff.png
djpeg foo.jpg | pnmtopng &gt; foo-was-jpeg.png</pre></blockquote>


<p>But these are all trivial conversions. Suppose I would like to convert an
existing NetPBM image into an interlaced PNG, including gamma information, a timestamp,
and some text--say, the author's name, the title of the image, its copyright,
and perhaps the date on which the original photograph was taken. The first
thing we need to do is create a small text file containing the text information.
pnmtopng treats the first word on any line that does not begin with a
blank (either a space or a tab character) as the keyword, with the actual
text following. The text may stretch over several lines, and keywords with
spaces in them must be quoted. Thus the following text file, containing four
keywords and their corresponding values, would suffice:</p>


<blockquote>
<pre class="code">Title           The Incredible and Rarely Seen Foo
Author          Greg Roelofs
Copyright       This image is hereby placed in the
                public domain by its author.
"Creation Time" 4 July 1976
    is the date on which this particular Foo was photographed.</pre>
</blockquote>


<p>Note that leading blanks (or ``white space''), including any between the
keywords and subsequent text, will not be included in the PNG text chunks.
But any newlines (or ``carriage returns,'' loosely speaking) will be included
exactly as typed; thus, there will be one in the Copyright text chunk, right
before the word ``public,'' and another in the Creation Time
text chunk, immediately after ``1976.''  In addition, there is currently a
bug in pnmtopng: when all of the text corresponding to a keyword appears on
a line following the keyword--that is, the keyword is immediately followed
by a carriage return--the program will sometimes crash. The problem will
almost certainly be fixed by the time this book reaches print, but in the
meantime, it can be avoided by adding a space after the keyword.</p>


<p>So assuming the text file were named <em class="emphasis">comments.txt</em> (and contains no
keywords followed immediately by newlines), the following command would
create the PNG image with the specified text and other information:</p>


<blockquote><pre class="code">pnmtopng -interlace -gamma 0.65909 -text comments.txt \
  -time 1998-10-25 21:00:00 foo.ppm &gt; foo.png</pre></blockquote>


<p>The first option is self-explanatory: the PNG image will be interlaced.
For the <b class="emphasis-bold">-gamma</b> option, we've used a value that corresponds to a
typical Macintosh; we're imagining that the original image was scanned and
tweaked on a Mac before being converted to PPM format (<em class="emphasis">foo.ppm</em>) on
some other system. The <b class="emphasis-bold">-time</b> option requires a little more
explanation. First, note that it is distinct from the ``Creation Time''
text chunk we included; the <b class="emphasis-bold">-time</b> option will write the special PNG
tIME chunk, which represents the time the image was last modified. But the
last modification time is clearly the time the image was converted into
PNG format, so pnmtopng really should not require the user to specify the
time information explicitly. This is particularly true, given that PNG's
time chunk is supposed to be in Coordinated Universal Time, and most users
are unlikely to know how to convert to that.<a href="#FOOTNOTE-34">[34]</a>
With luck, this oversight will also be corrected in the next release of the
program.</p><blockquote class="footnote">


<a name="FOOTNOTE-34" /><p>[34] The example here corresponds to 1:00 p.m. in the US/Pacific time zone. But had
the conversion taken place at 1:00 p.m. on the previous day, it would have been
specified as 20:00:00 in Universal Time, thanks to the fact that daylight
saving time had not yet ended.</p>


</blockquote>


<p><a name="INDEX-410" />Transparency is one of PNG's major strengths, so let's take a look at some
of pnmtopng's options there. Suppose that we wish to vignette our treasured
foo image--that is, we would like to apply an oval mask to it that gradually
fades to complete transparency, in effect transforming our image from 
rectangular to rounded. This is easily accomplished by creating the oval
mask as a grayscale (PGM) image, where white represents the regions that will
be completely opaque (i.e., the main subject matter of the image) and black
the outer, transparent regions. Then give the following command:</p>


<blockquote><pre class="code">pnmtopng -alpha ovalmask.pgm foo.ppm &gt; foo.png</pre></blockquote>


<p>This will ordinarily create a 32-bit RGBA image--in other words, truecolor
with a full alpha channel. But if it happens that the combination of the
original RGB image and the mask produces at most 256 RGBA combinations,
pnmtopng is smart enough to detect that and write a palette-based image
with transparency information instead. Moreover, it will automatically arrange
the palette and transparency entries so that all of the completely opaque 
colors are at the end of the palette; the corresponding transparency entries
may then be omitted, resulting in a smaller file.
</p>


<p>In some cases, the transparency mask contains only fully opaque and fully
transparent values, and it may happen (usually by design) that the parts of
the underlying image that correspond to the transparent region are all one
color, even though there may be thousands of colors in the opaque part.
pnmtopng will again detect this, creating a palette-based image with just
one transparency entry if possible; if there are too many colors, it will
instead write a full grayscale or RGB image with a single color marked
transparent. This results in a PNG file that's much more compact than
one with a full alpha channel.</p>


<p>Transparent images intended for display only on web browsers will always
have some sort of background specified as part of the web page, but for
images that may be rendered by a standalone viewer, it is often desirable
to include an explicit background color in the image. The <b class="emphasis-bold">-background</b>
option provides that capability; it accepts a color argument in almost any
format allowed by MIT's X Window System, including English text (assuming the
X color database file can be found). Thus, the following three commands
are equivalent (the <b class="emphasis-bold">-alpha ovalmask.pgm</b> option has been omitted
for brevity):</p>


<blockquote><pre class="code">pnmtopng -background rgbi:1.0/0.855/0.726 foo.ppm &gt; foo.png
pnmtopng -background "peach puff"         foo.ppm &gt; foo.png
pnmtopng -background "#ffdab9"            foo.ppm &gt; foo.png</pre></blockquote>


<p>For most users, the second form is probably the most easily understood but the
least precise. Making it precise requires the finely honed ability to find
the X color-database file, which can be difficult when it exists and impossible
when it doesn't<a href="#FOOTNOTE-35">[35]</a>
(it is also explicitly platform-dependent; that is, the same color name is
allowed to have different RGB values on different machines).
Therefore, the first form is likely to be the most useful. It specifies
the RGB values of the background color as decimal fractions
between 0.0 and 1.0. The values are separated by forward slashes
(<b class="emphasis-bold">/</b>) and prefixed by <b class="emphasis-bold">rgbi:</b>. The third form is the old-style
hexadecimal format that is favored by programmers but almost no one else.
(It also happens to be the format used in the demo programs I present in
<a href="chapter13.html">Chapter 13, "Reading PNG Images"</a> and <a href="chapter14.html">Chapter 14, "Reading PNG Images Progressively"</a> on reading PNG images. Oh, the embarrassment.) The
hex value need not be placed in quotation marks on a command line, but within a shell script it
should be quoted, or the hash character (<b class="emphasis-bold">#</b>) will be treated as the beginning
of a comment.</p><blockquote class="footnote">


<a name="FOOTNOTE-35" /><p>[35] For the record, it lives in <em class="emphasis">/usr/openwin/lib/X11/rgb.txt</em> on Sun
systems, <em class="emphasis">/usr/X11R6/lib/X11/rgb.txt</em> on most Linux and FreeBSD
systems, and <em class="emphasis">/usr/lib/X11/rgb.txt</em> on ``generic'' Unix/X11 systems.</p>


</blockquote>


<p>pnmtopng also potentially supports the creation of 16-bit-per-sample images
(that is, 16-bit grayscale, 32-bit gray+alpha, 48-bit RGB or 64-bit RGBA),
but only with text (ASCII) NetPBM files, and only if the underlying NetPBM
library supports 16-bit images, which is not the default behavior. The
requirement to use ASCII format for the 16-bit NetPBM image files is a current
limitation of the NetPBM suite. As with transparency and palettes, pnmtopng
detects if 16-bit samples are really just scaled 8-bit samples; if so, it will
automatically convert the image back to 8-bit samples unless the <b class="emphasis-bold">-force</b>
option is given. It can also be instructed to convert true 16-bit samples to
8-bit with the <b class="emphasis-bold">-downsample</b> option.</p>


<p>Other supported features include chromaticity information, histograms, compressed
text, explicit single-color transparency, physical pixel dimensions, and
special compression options. Quantization of truecolor images to 256 or
fewer colors is not supported by pnmtopng itself, but it is a straightforward
part of the standard NetPBM package. For example, to quantize a 24-bit TIFF
image to the 256 best colors, dither the result, and save it as a palette-based
PNG, one can use:
<a name="INDEX-411" /></p>


<blockquote><pre class="code">tifftopnm foo.tiff | ppmquant -fs 256 | pnmtopng &gt; foo.png</pre></blockquote>


<?x-need 10?><p>The <b class="emphasis-bold">-fs</b> option to ppmquant instructs it to use Floyd-Steinberg
dithering, which generally looks very nice but does require a fair amount of
computation. The <b class="emphasis-bold">256</b> parameter indicates the number of colors to be
used in the final version; any value may be used (web-savvy designers might
wish to use a smaller number of colors), but only values of 256 or
less will result in a palette-based PNG image. What about images with an
alpha channel? Unfortunately, those who wish to quantize 32-bit RGBA images
down to a 256-entry ``RGBA palette'' are stuck for now. The ppmquant algorithm
can easily be modified to support RGBA values in addition to ordinary RGB,
but until NetPBM itself is updated, there is no way to pipe transparency information
from one NetPBM utility into another.</p>


<p>For users of very large images, one other point is worth mentioning: pnmtopng
currently reads the entire image into memory buffers before doing anything
with it, which means that a 4000&nbsp;&times; 4000 RGBA image would require 64 megabytes
of real and/or virtual memory just for the uncompressed image itself. But
all is not lost; in <a href="chapter15.html">Chapter 15, "Writing PNG Images"</a>, I present a very
simple-minded NetPBM-to-PNG converter, and one of its design goals was the
ability to convert images on the fly, requiring only a very small memory
footprint. (Of course, this only works if the PNG image is not
interlaced.) The demo program also has a <b class="emphasis-bold">-time</b> option that
automatically records the current time in the proper format, as well as one
or two other potentially handy features.
<a name="INDEX-412" /></p>


















</div>
<div class="sect1"><a name="png.ch05.div.3" />
<h2 class="sect1">5.3. gif2png</h2>


<p><a name="INDEX-413" />
<a name="INDEX-414" />For simple batch conversion of GIF images into PNGs, pnmtopng is not only
overkill but also somewhat tricky to automate. Such a task is more readily
handled by <em class="emphasis">gif2png</em>, a special-purpose conversion program written by
Alexander Lehmann. Besides the raw image pixels, there are three GIF
features that translate directly into PNG features: transparency, text
(comments), and interlacing. gif2png handles the first two automatically;
only interlacing is not detected and automatically applied to the output
image, although the program does include a <b class="emphasis-bold">-i</b> option to force
interlacing.</p>


<p>The simplest usage of gif2png is to give it the name of a GIF image:</p>


<blockquote><pre class="code">gif2png foo.gif</pre></blockquote>


<p>The program will convert the image to a noninterlaced PNG, preserving
any transparency, comments, and ``graphic control'' or ``application extension''
information. It will also add its own text chunk with the Software keyword,
and it will automatically change the file extension from <em class="emphasis">.gif</em>
to <em class="emphasis">.png</em>. There is one important caveat, however: the current version,
gif2png 0.6, does not check for an existing file of the same name and will
overwrite any such file without warning.</p>


<p>Because gif2png renames the files it converts without user input, it can
be used to convert a whole directory of GIF files in a single command.
Under Unix, where the shell expands wildcard filenames (``globbing''),
this is as simple as:</p>


<blockquote><pre class="code">gif2png *.gif</pre></blockquote>


<p>On other operating systems, the filenames must be specified explicitly:</p>


<blockquote><pre class="code">gif2png a.gif b.gif c.gif d.gif e.gif foo.gif foo2.gif</pre></blockquote>


<p>To prevent gif2png from adding a Software text chunk to the output image(s),
use the <b class="emphasis-bold">-s</b> option:</p>


<blockquote><pre class="code">gif2png -s foo.gif</pre></blockquote>


<p>To do the same conversion but to an interlaced PNG, include the <b class="emphasis-bold">-i</b>
option:</p>


<blockquote><pre class="code">gif2png -s -i foo.gif
gif2png -si foo.gif</pre></blockquote>


<p><a name="INDEX-415" />gif2png does have a few drawbacks, as might be expected given its pre-1.0
version number. In addition to the problem of overwriting existing files, 
gif2png's conversion of GIF transparency information is less than ideal; although
it gets the job done, the program copies over the GIF palette without
modification, which can result in useless transparency entries in the PNG
file. For example, a 256-color GIF image whose last palette entry is the
transparent one would result in a 256-entry transparency chunk in the PNG
file, where one entry would suffice; in other words, it can waste up to 255
bytes in the output file. gif2png is also rather verbose and provides no
option to keep it quiet; in fact, its progress meter (a simple percentage
value, updated repeatedly) is supposed to be enabled only when the <b class="emphasis-bold">-p</b>
option is given, but it actually is on by default and can only be turned
<em class="emphasis">off</em> with <b class="emphasis-bold">-p</b>.</p>


<p>Despite all this, the program is quite stable and useful. It even converts
GIF comments from IBM codepage 437 to PNG's Latin-1 format, and it will
convert animated GIFs into multiple single-image PNGs. A planned option
that would have automatically deleted the GIF input images after conversion
was never implemented, nor was the capability of converting GIF Plain Text
Extensions into PNG gIFt chunks. But these are minor issues; in fact, the
gIFt chunk was officially declared Bad (that is, deprecated) in October 1998,
so its lack of support in gif2png turned out to be prescient. Indeed, the
only major problem with the program is the fact that it reads GIFs in the
first place. It is therefore (according to Unisys) subject to the LZW
<a name="INDEX-416" />patent and its associated licensing issues. Unisys initially claimed that
freeware GIF programs would be granted a free LZW license, but that later
changed, which was directly responsible for the cessation of further
development on gif2png.</p>


<p>The gif2png source code and ready-to-go binaries for Linux
can be found at <a href="http://www.catb.org/~esr/gif2png/"
>http://www.catb.org/~esr/gif2png/</a>.  (Older binaries for
DOS, OS/2, Amiga, and Macintosh may still exist elsewhere on the Web.)
A graphical port written by Nigel Stewart for 32-bit Windows, called The
Exorcist, supports drag and drop and is available from its own home page:
<!--
<a href="http://www.eisa.net.au/~nigels/Exorcist/Exorcist.html"
>http://www.eisa.net.au/~nigels/Exorcist/Exorcist.html</a>.
 -->
<a href="http://www.nigels.com/exorcist/Exorcist.html"
>http://www.nigels.com/exorcist/Exorcist.html</a>.
Version 1.1 is the latest release.
<a name="INDEX-417" />
<a name="INDEX-418" />
</p>


















</div>
<div class="sect1"><a name="png.ch05.div.4" />
<h2 class="sect1">5.4. Tiff2png</h2>


<p><a name="INDEX-419" />
<a name="INDEX-420" />The corresponding special-purpose conversion program for TIFF images was
written by Willem van Schaik and is called, predictably, <em class="emphasis">Tiff2png</em>.
By a strange coincidence, its latest version is also 0.6, but the program
is perhaps slightly less robust than gif2png. This is primarily due to the
fact that the TIFF format is hugely complex, supporting multiple forms of
text annotations, both gamma and color correction, several flavors of
transparency, many different sample depths, and numerous other options that
might conceivably be carried over into a PNG image with a little effort (or,
more likely, a lot of it).</p>


<p>Tiff2png's main features as a conversion program are its support for TIFF
sample depths up to 16 bits and its support for transparency and alpha
channels. Unlike gif2png, Tiff2png requires an explicit output filename
and is therefore somewhat less convenient for batch conversions:</p>


<blockquote><pre class="code">tiff2png foo.tiff foo.png</pre></blockquote>


<p>It is also completely quiet by default, although it supports a <b class="emphasis-bold">-v</b>
option to turn on its verbose mode:</p>


<blockquote><pre class="code">tiff2png -v foo.tiff foo.png
  
Tiff2png: foo.tiff
TIFF Directory at offset 0x10008
  Image Width: 128 Image Length: 128
  Resolution: 72, 72 pixels/inch
  Bits/Sample: 8
  Compression Scheme: None
  Photometric Interpretation: RGB color
  Extra Samples: 1&lt;assoc-alpha&gt;
  Samples/Pixel: 4
  Rows/Strip: 16
  Planar Configuration: single image plane
Tiff2png: 128x128x32 image
Tiff2png: 8 bits/sample, 4 samples/pixel
Tiff2png: maxval=255
Tiff2png: color-type = truecolor + alpha
Tiff2png: bit-depth = 8</pre></blockquote>


<?x-need 10?><p>Unfortunately, Tiff2png does not distinguish between associated (premultiplied)
alpha and unassociated alpha. The latter is the only form supported by PNG,
but Tiff2png will happily store an associated alpha channel without conversion,
as in the previous example.</p>


<p><a name="INDEX-421" />
<a name="INDEX-422" />The program also appears not to handle Intel-format
(``little-endian'': see the section entitled "Implementation" in
<a href="chapter07.html">Chapter 7, "History of the Portable Network Graphics Format"</a>) TIFF images with 16-bit samples correctly, instead storing
the samples as is--which effectively means they are inverted, given
that PNG samples must be stored in ``big-endian'' format. But lacking
any such sample images, I was unable to verify this.</p>


<p>At any rate, Tiff2png is capable of converting at least some TIFF images with
alpha transparency correctly, which gives it an advantage over the current
NetPBM suite and pnmtopng. Although TIFF is subject to the same LZW licensing
issues GIF is, it supports several other compression methods (including no
compression) and is therefore less of a problem for program authors. In
Tiff2png's case, all TIFF manipulations are handled via Sam Leffler's free
<a name="INDEX-423" /><b class="emphasis-bold">libtiff</b> library, which means Tiff2png itself can be updated at will
without worrying about the sorts of legal issues that plagued gif2png.
Source code for Tiff2png can be found on the PNG home site,
<a href="http://www.libpng.org/pub/png/apps/tiff2png.html">http://www.libpng.org/pub/png/apps/tiff2png.html</a>,
but there are presently no prebuilt executables.
<a name="INDEX-424" />
<a name="INDEX-425" />
</p>


















</div>
<div class="sect1"><a name="png.ch05.div.5" />
<h2 class="sect1">5.5. pngcheck</h2>


<p>
<a name="INDEX-426" />
<a name="INDEX-427" />
<a name="INDEX-428" />
Finally, we should take a look at an extremely useful PNG utility that is not
usually considered a conversion tool: <em class="emphasis">pngcheck</em>. pngcheck prints the
chunks in a PNG file, along with their contents, in many cases; one can loosely
think of it as a utility that ``converts PNG images to text,'' although it
does so in such a way that they could never be converted back to PNG format.
(In particular, it provides no way to print the actual pixel data, although
it can print just about everything else.)</p>


<a name="INDEX-428.01-new" />
<p>Originally written by Alexander Lehmann as a simple tool to check PNG
images for corruption, such as might occur if the file were
transferred in text mode, pngcheck was subsequently extended by
Andreas Dilger, Greg Roelofs, and others, evolving into a nearly
complete PNG syntax checker and content dumper. The latest versions
(1.99-grr1 is current as of this writing) even include partial support
for MNG files, the multi-image PNG extension described in
<a href="chapter12.html">Chapter 12, "Multiple-Image Network Graphics"</a> (<em class="emphasis">Multiple-Image Network Graphics</em>).  pngcheck is
most often used to understand why a particular image is larger than
expected--perhaps a 16-color image was saved in 24-bit RGB format
instead of palette format, or a truecolor image was saved with minimal
compression and no filtering.  But it can also be used simply to test
PNG files
<?x-need 10?>and print their dimensions, image types, and approximate compression
<a name="INDEX-429" />ratios.<a href="#FOOTNOTE-36">[36]</a></p>

<blockquote class="footnote">
<a name="FOOTNOTE-36" /><p>[36] The compression ratio is computed by dividing the total file size
by the nominal size of the uncompressed IDAT data, which means the presence
of ancillary information or even a required palette can produce negative
compression ratios--i.e., ``expansion''--in small images. In other words,
don't take it too seriously.</p>


</blockquote>


<p>The most basic use of pngcheck involves giving it one or more filenames and
no options, like so:</p>


<blockquote><pre class="code">pngcheck foo.png foo2.png foo3.png</pre></blockquote>


<p>This results in output similar to the following, except that here the lines
have been wrapped to fit the page:</p>


<blockquote><pre class="code">No errors detected in
   foo.png (578x802, 24-bit RGB, interlaced, 54.7%).
No errors detected in
   foo2.png (32x32, 4-bit colormap, interlaced, 36.1%).
No errors detected in
   foo3.png (32x32, 64-bit RGB+alpha, non-interlaced, 58.1%).</pre></blockquote>


<p>An image that has been corrupted in some way might cause an error message
such as the following:</p>


<blockquote><pre class="code">foo4.png:  File is CORRUPTED by text conversion.
foo4.png:  Chunk name 00 0d 49 48 doesn't conform to naming rules.</pre></blockquote>


<p>But pngcheck is most useful for seeing what's inside a PNG image. The
<b class="emphasis-bold">-v</b> option, for <em class="emphasis">verbose</em> mode, prints the name of each chunk
within the file, along with some basic information wherever appropriate. Because
it can be a tad lengthy, it is often a good idea to pipe the program's
verbose output through a paging filter such as <em class="emphasis">more</em>. The following
example works on both Unix-based systems and DOS, OS/2, and Windows command
lines:</p>


<blockquote><pre class="code">pngcheck -v imgcomp.png | more
  
File: imgcomp.png (34163 bytes)
  chunk IHDR at offset 0x0000c, length 13
    640 x 480 image, 32-bit RGB+alpha, non-interlaced
  chunk gAMA at offset 0x00025, length 4: 0.45455
  chunk IDAT at offset 0x00035, length 8192
    zlib:  deflated, 32K window, default compression
  chunk IDAT at offset 0x02041, length 8192
  chunk IDAT at offset 0x0404d, length 8192
  chunk IDAT at offset 0x06059, length 8192
  chunk IDAT at offset 0x08065, length 1274
  chunk IEND at offset 0x0856b, length 0
No errors detected in imgcomp.png (97.2% compression).</pre></blockquote>


<p>In this example, we see a fairly basic PNG file, a truecolor image with an
alpha channel, composed of only four chunk types: the required IHDR, IDAT,
and IEND chunks (described in <a href="chapter08.html">Chapter 8, "PNG Basics"</a>), plus the optional but highly
recommended gamma-correction chunk, gAMA (<a href="chapter10.html">Chapter 10, "Gamma Correction and Precision Color"</a>). Because the image
primarily consists of solid-colored regions and simple gradients, it compressed
unusually well; this probably indicates that dynamic filtering was used, but
there is no way to be certain, given the preceding information.
</p>


<a name="INDEX-429.01-new" />
<p>However, pngcheck can optionally use the zlib compression library in
order to look <em class="emphasis">inside</em> the compressed image data. In this case, it supports
a <b class="emphasis-bold">-vv</b> option (``very verbose'') that prints out all of the preceding information
plus filtering information. The filter output can be extremely long; for
just the first IDAT chunk in the preceding example, it looks like this:</p>


<blockquote><pre class="code">  chunk IDAT at offset 0x00035, length 8192
    zlib:  deflated, 32K window, default compression
    zlib line filters (0 none, 1 sub, 2 up, 3 avg, 4 paeth):
      0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
      0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
      0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
      0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
      1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
      1 2 2 1 2 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
      2 2 2 2 2 4 4 4 4 4 4 4 4 4 4 4 4 1 4 1 4 1 4 2 4
      2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 4 4 4 2
      (200 out of 480)</pre></blockquote>


<p>The details are too complex to cover right now, but filtering and compression
are discussed in <a href="chapter09.html">Chapter 9, "Compression and Filtering"</a>.  All that matters here is that different filters
have been used for different rows in the image, indicating that some sort of
dynamic filtering was applied (which is generally good). Unfiltered images,
on the other hand, will have all zeros for the filter numbers, and statically
filtered images will use only a single filter type. In most cases, that means
the image is not compressed as well as it could be. One major exception,
however, is palette-based images; they rarely respond well to filtering, and
most programs don't try.</p>


<p>pngcheck also supports more specific types of output. Its <b class="emphasis-bold">-p</b> option,
for example, is another rather verbose case; it prints the contents of the
palette and optional transparency chunks for colormapped images.<a href="#FOOTNOTE-37">[37]</a>
This can be useful in conjunction with a program such as pngcrush, for example,
when one wishes to specify a particular color as transparent, but more commonly
it is used to check whether the transparency chunk is full of needless opaque
values. Consider the following example:</p><blockquote class="footnote">


<a name="FOOTNOTE-37" /><p>[37] It will also print the contents of the optional histogram and suggested-palette
chunks; see <a href="chapter11.html">Chapter 11, "PNG Options and Extensions"</a>, for details.</p>


</blockquote>


<blockquote><pre class="code">pngcheck -p foo5.png
  
File: foo5.png (146 bytes)
  PLTE chunk: 4 palette entries
    0:  (  0,255,  0) = (0x00,0xff,0x00)
    1:  (255,  0,  0) = (0xff,0x00,0x00)
    2:  (255,255,  0) = (0xff,0xff,0x00)
    3:  (  0,  0,255) = (0x00,0x00,0xff)
  tRNS chunk: 3 transparency entries
    0:  255 = 0xff
    1:  255 = 0xff
    2:    0 = 0x00
No errors detected in foo5.png (32x32, 2-bit colormap, non-interlaced,
43.0%).</pre></blockquote>


<p>Here we have a four-color image: bright green, red, yellow, and blue. The
colors of the palette are listed as RGB triplets in both decimal
and hexadecimal (base 16) for convenience. The palette itself is unremarkable;
what is more interesting is the transparency chunk, tRNS. It includes three
entries, but the first two have the value 255, which indicates that the
corresponding palette entries should be treated as completely opaque. But
all palette entries are considered opaque unless explicitly given a
non-opaque transparency value--in other words, any transparency entries with
the value 255 are redundant and represent wasted space. In this case, the only
non-opaque entry corresponds to the third color, yellow; a smart
PNG-writing program would have reordered the palette so that yellow was the
first entry, thus shaving two bytes off the file. It is not uncommon to be
able to save 100 or more bytes in this manner, which can represent 10% to 20%
of the file size for small web graphics.<a href="#FOOTNOTE-38">[38]</a>
In rare cases, it may be worthwhile to waste a few transparency entries
so that the most common pixels in the image are all at the beginning of the
palette (i.e., so they all have index values near zero); with filtering
enabled, the compression engine may be able to make up the difference and
then some. But as of early 1999, filtering has yet to be demonstrated
effective on essentially any kind of palette-based image, so the possibility
of recovering wasted transparency entries with improved compression is a
rather tenuous one.</p>


<blockquote class="footnote">
<a name="FOOTNOTE-38" /><p>[38] One of the images used on the VRML98 web site had 211 transparency entries,
of which 210 were unnecessary.</p>
</blockquote>


<p>The other type of verbose pngcheck output is more useful to ordinary
users, not just content developers trying to optimize things. The <b class="emphasis-bold">-t</b>
option prints not only text chunks' keywords but also their contents:</p>


<blockquote><pre class="code">pngcheck -t ct1n0g04.png
  
File: ct1n0g04.png (796 bytes)
Title:PngSuite
Author:Willem A.J. van Schaik
(gwillem@ntuvax.ntu.ac.sg)
Copyright:Copyright Willem van Schaik, Singapore 1995
Description:A compilation of a set of images created to test the
various color-types of the PNG format. Included are
black&amp;white, color, paletted, with alpha channel, with
transparency formats. All bit-depths allowed according
to the spec are present.
Software:Created on a NeXTstation color using "pnmtopng".
Disclaimer:Freeware.
No errors detected in
   ct1n0g04.png (32x32, 4-bit grayscale, non-interlaced, -55.5%).</pre></blockquote>


<p>This example, using one of Willem van Schaik's test images from the PNG Suite,
contains six text chunks with keywords Title, Author,
Copyright, Description, Software, and Disclaimer.
The content of each chunk immediately follows the keyword and colon; this is
not the most readable approach, but the information is available and usually
understandable with only a little squinting. One deficiency of the current
version is that it does not display the contents of compressed text chunks
(zTXt), even when using the zlib compression library. This is promised to be
fixed in a future version, however.</p>


<p>The latest version of pngcheck can be found at the PNG home site,
<a href="http://www.libpng.org/pub/png/apps/pngcheck.html">http://www.libpng.org/pub/png/apps/pngcheck.html</a>.
<a name="INDEX-430" />
<a name="INDEX-431" />
<a name="INDEX-432" />
</p>


















</div>
<div class="sect1"><a name="png.ch05.div.6" />
<h2 class="sect1">5.6. Other Conversion Programs</h2>


<p>The converters we've discussed so far barely scratch the surface of
what is available. If one includes image editors and viewers that can
convert images in addition to dedicated conversion tools, there are
well over one hundred applications capable of converting to and from
the PNG format.<a href="#FOOTNOTE-38b"><font color="#006600">[38b]</font></a>
Many of these were listed in the previous two chapters
and are well worth considering, particularly for users who may be
uncomfortable dealing with command-line programs.</p>

<!--    GRR POST-1999 UPDATE    -->
<font color="#006600">

<blockquote class="footnote">
<a name="FOOTNOTE-38b" />
<p>[38b] As of mid-2003, the number has more than doubled; the
<a href="http://www.libpng.org/pub/png/pngapcv.html"><font color="#006600">PNG
home site</font></a> lists all of them.  Perhaps not surprisingly, however,
the five discussed above are still among the best.</p>
</blockquote>

</font>
<!--    END GRR POST-1999 UPDATE    -->


<p>Here is a list of some of the other dedicated (or nearly dedicated) image
converters that support PNG. The most recent version as of January 1999 is
given wherever possible.</p>


<dl>
<dt><b><em class="emphasis">ColourEdit</em></b></dt><dd><p><a name="INDEX-433" />Version of April 3, 1997, Julian Highfield. Available as
an OpenDoc part for Mac 68k/PPC (mostly tested with OpenDoc 1.1 and Mac OS
System 7.1.2); read/write support for PNGs.</p></dd>

</dl>


<blockquote><pre class="code"><a href="http://www.stile.lboro.ac.uk/~cojch/ColourEdit/">http://www.stile.lboro.ac.uk/~cojch/ColourEdit/</a></pre></blockquote><dl>
<dt><b><em class="emphasis">Creator</em></b></dt><dd><p><a name="INDEX-434" />Version 3.22, John Kortink. Available for Acorn RISC OS;
read/write support for PNGs; no alpha or gamma support.</p></dd>

</dl>


<blockquote><pre class="code"><a href="http://web.inter.nl.net/users/J.Kortink/indexsw.htm">http://web.inter.nl.net/users/J.Kortink/indexsw.htm</a></pre></blockquote><dl>
<dt><b><em class="emphasis">dicom2</em></b></dt><dd><p><a name="INDEX-435" />Version 1.8, S&eacute;bastien Barr&eacute;. Available for Windows
9x/NT, Linux x86, SunOS/Solaris SPARC; write-only support for PNGs; supports
conversion of 12-bit medical formats to 16-bit grayscale PNGs.</p></dd>

</dl>


<blockquote><pre class="code"><a href="http://www.hds.utc.fr/~barre/medical/dicom2/">http://www.hds.utc.fr/~barre/medical/dicom2/</a></pre></blockquote><dl>
<dt><b><em class="emphasis">Ghostscript</em></b></dt><dd><p><a name="INDEX-436" />Version 5.50, Aladdin Enterprises. Available for Unix,
VMS, OS/2, Windows 9x/NT, and Mac 68k/PPC; older versions available for
Windows 3.x, DOS, Amiga, Atari, and possibly Acorn RISC OS; write-only support
for PNGs.</p></dd>

</dl>


<blockquote><pre class="code"><a href="http://www.cs.wisc.edu/~ghost/">http://www.cs.wisc.edu/~ghost/</a></pre></blockquote><dl>
<dt><b><em class="emphasis">gj2png</em></b></dt><dd><p><a name="INDEX-437" />Version of February 13, 1997, Neil Aggarwal. Available for any
platform supporting Java 1.1 or later; write-only support for PNGs.</p></dd>

</dl>


<blockquote><pre class="code"><a href="http://www.anet-dfw.com/~neil/gjFrame.html">http://www.anet-dfw.com/~neil/gjFrame.html</a></pre></blockquote><dl>
<dt><b><em class="emphasis">Icons Control 95</em></b></dt><dd><p><a name="INDEX-438" />Version 7.02, Chris Doan. Available for Windows
9x/NT; read-only support for PNGs (converts various image formats to
Windows <em class="emphasis">.ico</em> format).</p></dd>

</dl>


<blockquote><pre class="code"><a href="http://members.aol.com/doanc/icnctrl.html">http://members.aol.com/doanc/icnctrl.html</a></pre></blockquote><dl>
<dt><b><em class="emphasis">Image Arithmetic</em></b></dt><dd><p><a name="INDEX-439" />Version 2.2a, Richard van Paasen. Available for
Windows 9x/NT; read/write support for PNGs.</p></dd>

</dl>


<blockquote><pre class="code"><a href="http://huizen.dds.nl/~buddha/imgart.html">http://huizen.dds.nl/~buddha/imgart.html</a></pre></blockquote><dl>
<dt><b><em class="emphasis">LatinByrd</em></b></dt><dd><p><a name="INDEX-440" />Version III v6, Stefan Schneider Software. Available for
NeXTStep/OpenStep on 68k/x86/HP-PA/SPARC; write-only support for PNGs; can
quantize 32-bit RGBA TIFF images to 8-bit RGBA-palette PNGs.</p></dd>

</dl>


<blockquote><pre class="code"><a href="http://members.ping.at/stefan/LatinByrdProductInfo.html">http://members.ping.at/stefan/LatinByrdProductInfo.html</a></pre></blockquote><dl>
<dt><b><em class="emphasis">PicCon</em></b></dt><dd><p><a name="INDEX-441" />Version 2.50, Morten Eriksen. Available for Amiga; read-only;
requires a PNG datatype such as those from Cloanto or Andreas Kleinert.</p></dd>

</dl>


<blockquote><pre class="code"><a href="http://www.aminet.org/pub/aminet/gfx/conv/PicCon250.lha">http://www.aminet.org/pub/aminet/gfx/conv/PicCon250.lha</a>
<a href="http://www.aminet.org/pub/aminet/util/dtype/PNG_dt.lha">http://www.aminet.org/pub/aminet/util/dtype/PNG_dt.lha</a>
<a href="http://www.aminet.org/pub/aminet/util/dtype/akPNG-dt.lha">http://www.aminet.org/pub/aminet/util/dtype/akPNG-dt.lha</a>
<a href="http://home.t-online.de/home/Andreas_Kleinert/support.htm">http://home.t-online.de/home/Andreas_Kleinert/support.htm</a></pre></blockquote><dl>
<dt><b><em class="emphasis">PNG-Box</em></b></dt><dd><p><a name="INDEX-442" />Version 3.25, Andreas Kleinert. Available for Amiga 68k/PPC;
write-only support for PNGs; supports interlacing and single-color transparency.
PNG-Box is a graphical ``any to PNG'' conversion utility that uses Andreas's own
SuperView Library for its image support instead of datatypes.</p></dd>

</dl>


<blockquote><pre class="code"><a href="http://www.amigaworld.com/support/png-box/">http://www.amigaworld.com/support/png-box/</a>
<a href="http://home.t-online.de/home/Andreas_Kleinert/support.htm">http://home.t-online.de/home/Andreas_Kleinert/support.htm</a>
<a href="http://www.aminet.org/pub/aminet/gfx/conv/PNG-Box.lha">http://www.aminet.org/pub/aminet/gfx/conv/PNG-Box.lha</a></pre></blockquote><dl>
<dt><b><em class="emphasis">!Png2Spr</em></b></dt><dd><p><a name="INDEX-443" />Version 1.14, Tom Tanner. Available for Acorn RISC OS;
read-only support for PNGs (converts to Acorn sprite format).</p></dd>

</dl>


<blockquote><pre class="code"><a href="http://www.argonet.co.uk/users/ttehtann/">http://www.argonet.co.uk/users/ttehtann/</a></pre></blockquote><dl>
<dt><b><em class="emphasis">ptot</em></b></dt><dd><p><a name="INDEX-444" />Version of March 10, 1995, Lee Daniel Crocker. Available as
portable source code (does <em class="emphasis">not</em> require libpng or zlib);
read-only support for PNGs (converts to TIFF); full gamma support (writes
TIFF TransferFunction tag); full alpha support for true alpha channels (no
palette-alpha or ``cheap transparency'' support).</p></dd>

</dl>


<blockquote><pre class="code"><a href="ftp://swrinde.nde.swri.edu/pub/png/applications/ptot.tar.gz">ftp://swrinde.nde.swri.edu/pub/png/applications/ptot.tar.gz</a></pre></blockquote><dl>
<dt><b><em class="emphasis">SmartSaver</em></b></dt><dd><p><a name="INDEX-445" />Version 3.0, Ulead Systems. Available for 32-bit Windows;
read/write support for PNGs; full alpha support, including at least single-color
palette transparency (not clear whether full RGBA-palette translucency is
supported); reportedly cannot write 1-bit (bilevel) images.</p></dd>

</dl>


<blockquote><pre class="code"><a href="http://www.webutilities.com/ssaver/noslip.htm">http://www.webutilities.com/ssaver/noslip.htm</a></pre></blockquote><dl>
<dt><b><em class="emphasis">Spr2Png</em></b></dt><dd><p><a name="INDEX-446" />Version 0.04b, Darren Salt. Available for Acorn RISC OS;
write-only support for PNGs; full alpha support via secondary sprite that is
used as a transparency mask or alpha channel; supports interlacing and
background color. An older version was reported 
<?x-need 10?>to produce streaks in
conversions of newer (post-RPC) sprites, but this appears to be fixed in the
current release.</p></dd>

</dl>


<blockquote><pre class="code"><a href="http://www.youmustbejoking.demon.co.uk/progs.html#spr2png">http://www.youmustbejoking.demon.co.uk/progs.html#spr2png</a></pre></blockquote><dl>
<dt><b><em class="emphasis">ThumbNailer</em></b></dt><dd><p><a name="INDEX-447" />Version 5.2, Smaller Animals Software. Available for
32-bit Windows; read/write support for PNGs; supports transparency, background
color, and text; claims full gamma support.</p></dd>

</dl>


<blockquote><pre class="code"><a href="http://www.smalleranimals.com/thumb.htm">http://www.smalleranimals.com/thumb.htm</a></pre></blockquote><dl>
<dt><b><em class="emphasis">Ultraconv</em></b></dt><dd><p><a name="INDEX-448" />Version 3.0p1, Felix Schwarz. Available for Amiga 68k/PPC;
read/write support for PNGs (natively since version 1.6, or via a datatype for
earlier versions); no alpha or gamma support.</p></dd>

</dl>


<blockquote><pre class="code"><a href="http://home.pages.de/~uconv/">http://home.pages.de/~uconv/</a></pre></blockquote><p>New conversion utilities and updated information on the ones listed here can
be found at the <em class="emphasis">Image-Conversion Applications with PNG Support</em> web page
at the PNG home site, <a href="http://www.libpng.org/pub/png/pngapcv.html">http://www.libpng.org/pub/png/pngapcv.html</a>.
This URL is expected to be stable for years, but of course there are no
guarantees on the World Wide Web! Use a search engine to look for the title
string or for one of the more oddly named utilities listed if the link
should ever break.
<a name="INDEX-449" /></p>


</div>





<hr> <!-- -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -->

<a href="chapter04.html"><img width=24 height=13 border=0 align="left"
 src="images/prev.png" alt="&lt;-"></a>

<a href="chapter06.html"><img width=24 height=13 border=0 align="right"
 src="images/next.png" alt="-&gt;"></a>

<div align="center">
  <a href="chapter04.html"><font size="-1" color="#000000"
   ><b>PREVIOUS</b></font></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a
     href="toc.html"><font size="-1" color="#000000"
   ><b>CONTENTS</b></font></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a
     href="chapter06.html"><font size="-1" color="#000000"
   ><b>NEXT</b></font></a>
</div>

<hr> <!-- -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -->



</body></html>