File: chapter05.html

package info (click to toggle)
png-definitive-guide 20060430-4
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, sid, trixie
  • size: 8,848 kB
  • sloc: makefile: 11
file content (1403 lines) | stat: -rw-r--r-- 65,312 bytes parent folder | download | duplicates (3)
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>