From 1fd361a1ea06e44286c213ca1f814f49306fdc43 Mon Sep 17 00:00:00 2001 From: giraffedata Date: Sat, 19 Aug 2006 03:12:28 +0000 Subject: Create Subversion repository git-svn-id: http://svn.code.sf.net/p/netpbm/code/trunk@1 9d0c8265-081b-0410-96cb-a4ca84ce46f8 --- GNUmakefile | 393 + Makefile | 14 + Makefile.common | 545 + Makefile.config.in | 624 + Makefile.srcdir | 1 + README | 213 + analyzer/Makefile | 48 + analyzer/pamfile.c | 243 + analyzer/pamsharpmap.c | 188 + analyzer/pamsharpness.c | 153 + analyzer/pamslice.c | 199 + analyzer/pamsumm.c | 231 + analyzer/pamtilt.c | 437 + analyzer/pbmminkowski.c | 168 + analyzer/pgmhist.c | 87 + analyzer/pgmminkowski.c | 222 + analyzer/pgmtexture.c | 1047 ++ analyzer/pnmhistmap.c | 483 + analyzer/pnmpsnr.c | 209 + analyzer/ppmhist.c | 290 + build_complete | 1 + buildtools/Makefile | 46 + buildtools/Makefile.manpage | 366 + buildtools/README.pkg | 144 + buildtools/config_template | 52 + buildtools/configure.pl | 2111 ++++ buildtools/empty_depend | 19 + buildtools/endiangen | Bin 0 -> 14005 bytes buildtools/endiangen.c | 97 + buildtools/install.sh | 255 + buildtools/installnetpbm.pl | 919 ++ buildtools/installosf | 31 + buildtools/libopt | Bin 0 -> 18008 bytes buildtools/libopt.c | 541 + buildtools/make_merge.sh | 12 + buildtools/makecat | 18 + buildtools/makeman | 333 + buildtools/makepointerman | 91 + buildtools/mkinstalldirs | 41 + buildtools/stamp-date | 23 + buildtools/typegen | Bin 0 -> 14159 bytes buildtools/typegen.c | 113 + configure | 18 + converter/Makefile | 17 + converter/bmp.h | 256 + converter/other/Makefile | 238 + converter/other/README.JPEG | 397 + converter/other/anytopnm | 544 + converter/other/bmepsoe.c | 539 + converter/other/bmepsoe.h | 79 + converter/other/bmptopnm.c | 1477 +++ converter/other/cameratopam/COPYRIGHT | 35 + converter/other/cameratopam/Makefile | 37 + converter/other/cameratopam/bayer.h | 43 + converter/other/cameratopam/camera.c | 1781 +++ converter/other/cameratopam/camera.h | 131 + converter/other/cameratopam/cameratopam.c | 906 ++ converter/other/cameratopam/canon.c | 172 + converter/other/cameratopam/canon.h | 13 + converter/other/cameratopam/decode.c | 172 + converter/other/cameratopam/decode.h | 22 + converter/other/cameratopam/dng.c | 73 + converter/other/cameratopam/dng.h | 2 + converter/other/cameratopam/foveon.c | 790 ++ converter/other/cameratopam/foveon.h | 14 + converter/other/cameratopam/global_variables.h | 55 + converter/other/cameratopam/identify.c | 1183 ++ converter/other/cameratopam/identify.h | 11 + converter/other/cameratopam/ljpeg.c | 141 + converter/other/cameratopam/ljpeg.h | 17 + converter/other/cameratopam/util.c | 83 + converter/other/cameratopam/util.h | 16 + converter/other/dithers.h | 91 + converter/other/exif.c | 1030 ++ converter/other/exif.h | 56 + converter/other/fiasco/Makefile | 59 + converter/other/fiasco/README.netpbm | 41 + converter/other/fiasco/binerror.c | 143 + converter/other/fiasco/binerror.h | 50 + converter/other/fiasco/buttons.c | 510 + converter/other/fiasco/buttons.h | 50 + converter/other/fiasco/codec/Makefile | 27 + converter/other/fiasco/codec/approx.c | 702 ++ converter/other/fiasco/codec/approx.h | 30 + converter/other/fiasco/codec/bintree.c | 94 + converter/other/fiasco/codec/bintree.h | 43 + converter/other/fiasco/codec/coder.c | 965 ++ converter/other/fiasco/codec/coder.h | 24 + converter/other/fiasco/codec/coeff.c | 369 + converter/other/fiasco/codec/coeff.h | 61 + converter/other/fiasco/codec/control.c | 276 + converter/other/fiasco/codec/control.h | 33 + converter/other/fiasco/codec/cwfa.h | 107 + converter/other/fiasco/codec/decoder.c | 1532 +++ converter/other/fiasco/codec/decoder.h | 70 + converter/other/fiasco/codec/dfiasco.c | 398 + converter/other/fiasco/codec/dfiasco.h | 38 + converter/other/fiasco/codec/domain-pool.c | 986 ++ converter/other/fiasco/codec/domain-pool.h | 75 + converter/other/fiasco/codec/ip.c | 324 + converter/other/fiasco/codec/ip.h | 37 + converter/other/fiasco/codec/motion.c | 338 + converter/other/fiasco/codec/motion.h | 35 + converter/other/fiasco/codec/mwfa.c | 864 ++ converter/other/fiasco/codec/mwfa.h | 44 + converter/other/fiasco/codec/options.c | 894 ++ converter/other/fiasco/codec/options.h | 80 + converter/other/fiasco/codec/prediction.c | 629 + converter/other/fiasco/codec/prediction.h | 36 + converter/other/fiasco/codec/subdivide.c | 650 + converter/other/fiasco/codec/subdivide.h | 33 + converter/other/fiasco/codec/tiling.c | 239 + converter/other/fiasco/codec/tiling.h | 40 + converter/other/fiasco/codec/wfa.h | 141 + converter/other/fiasco/codec/wfalib.c | 774 ++ converter/other/fiasco/codec/wfalib.h | 66 + converter/other/fiasco/config.h | 96 + converter/other/fiasco/display.c | 422 + converter/other/fiasco/display.h | 49 + converter/other/fiasco/doc/README.LIB | 51 + converter/other/fiasco/doc/fiasco_c_options.3 | 1 + .../other/fiasco/doc/fiasco_c_options_delete.3 | 1 + converter/other/fiasco/doc/fiasco_c_options_new.3 | 432 + .../fiasco/doc/fiasco_c_options_set_basisfile.3 | 1 + .../doc/fiasco_c_options_set_chroma_quality.3 | 1 + .../fiasco/doc/fiasco_c_options_set_comment.3 | 1 + .../doc/fiasco_c_options_set_frame_pattern.3 | 1 + .../doc/fiasco_c_options_set_optimizations.3 | 1 + .../fiasco/doc/fiasco_c_options_set_prediction.3 | 1 + .../doc/fiasco_c_options_set_progress_meter.3 | 1 + .../fiasco/doc/fiasco_c_options_set_quantization.3 | 1 + .../fiasco/doc/fiasco_c_options_set_smoothing.3 | 1 + .../other/fiasco/doc/fiasco_c_options_set_tiling.3 | 1 + .../other/fiasco/doc/fiasco_c_options_set_title.3 | 1 + .../fiasco/doc/fiasco_c_options_set_video_param.3 | 1 + converter/other/fiasco/doc/fiasco_coder.3 | 106 + converter/other/fiasco/doc/fiasco_d_options.3 | 1 + .../other/fiasco/doc/fiasco_d_options_delete.3 | 1 + converter/other/fiasco/doc/fiasco_d_options_new.3 | 122 + .../fiasco/doc/fiasco_d_options_set_4_2_0_format.3 | 1 + .../doc/fiasco_d_options_set_magnification.3 | 1 + .../fiasco/doc/fiasco_d_options_set_smoothing.3 | 1 + converter/other/fiasco/doc/fiasco_decoder.3 | 1 + converter/other/fiasco/doc/fiasco_decoder_delete.3 | 1 + .../other/fiasco/doc/fiasco_decoder_get_comment.3 | 1 + .../other/fiasco/doc/fiasco_decoder_get_frame.3 | 1 + .../fiasco/doc/fiasco_decoder_get_framerate.3 | 1 + .../other/fiasco/doc/fiasco_decoder_get_height.3 | 1 + .../other/fiasco/doc/fiasco_decoder_get_length.3 | 1 + .../other/fiasco/doc/fiasco_decoder_get_title.3 | 1 + .../other/fiasco/doc/fiasco_decoder_get_width.3 | 1 + .../other/fiasco/doc/fiasco_decoder_is_color.3 | 1 + converter/other/fiasco/doc/fiasco_decoder_new.3 | 194 + .../other/fiasco/doc/fiasco_decoder_write_frame.3 | 1 + .../other/fiasco/doc/fiasco_get_error_message.3 | 41 + converter/other/fiasco/doc/fiasco_get_verbosity.3 | 1 + converter/other/fiasco/doc/fiasco_image.3 | 1 + converter/other/fiasco/doc/fiasco_image_delete.3 | 1 + .../other/fiasco/doc/fiasco_image_get_height.3 | 1 + .../other/fiasco/doc/fiasco_image_get_width.3 | 1 + converter/other/fiasco/doc/fiasco_image_is_color.3 | 1 + converter/other/fiasco/doc/fiasco_image_new.3 | 95 + converter/other/fiasco/doc/fiasco_options.3 | 1 + converter/other/fiasco/doc/fiasco_options_delete.3 | 1 + converter/other/fiasco/doc/fiasco_options_new.3 | 441 + .../fiasco/doc/fiasco_options_set_4_2_0_format.3 | 1 + .../fiasco/doc/fiasco_options_set_basisfile.3 | 1 + .../fiasco/doc/fiasco_options_set_chroma_quality.3 | 1 + .../fiasco/doc/fiasco_options_set_frame_pattern.3 | 1 + .../fiasco/doc/fiasco_options_set_magnification.3 | 1 + .../fiasco/doc/fiasco_options_set_optimizations.3 | 1 + .../fiasco/doc/fiasco_options_set_prediction.3 | 1 + .../fiasco/doc/fiasco_options_set_progress_meter.3 | 1 + .../fiasco/doc/fiasco_options_set_quantization.3 | 1 + .../fiasco/doc/fiasco_options_set_smoothing.3 | 1 + .../other/fiasco/doc/fiasco_options_set_tiling.3 | 1 + .../fiasco/doc/fiasco_options_set_video_param.3 | 1 + converter/other/fiasco/doc/fiasco_renderer.3 | 1 + .../other/fiasco/doc/fiasco_renderer_delete.3 | 1 + converter/other/fiasco/doc/fiasco_renderer_new.3 | 125 + .../other/fiasco/doc/fiasco_renderer_render.3 | 1 + converter/other/fiasco/doc/fiasco_set_verbosity.3 | 46 + converter/other/fiasco/fiasco.h | 425 + converter/other/fiasco/fiascotopnm.c | 477 + converter/other/fiasco/getopt.c | 1002 ++ converter/other/fiasco/getopt.h | 129 + converter/other/fiasco/getopt1.c | 189 + converter/other/fiasco/input/Makefile | 26 + converter/other/fiasco/input/basis.c | 141 + converter/other/fiasco/input/basis.h | 26 + converter/other/fiasco/input/matrices.c | 644 + converter/other/fiasco/input/matrices.h | 27 + converter/other/fiasco/input/mc.c | 334 + converter/other/fiasco/input/mc.h | 28 + converter/other/fiasco/input/nd.c | 237 + converter/other/fiasco/input/nd.h | 28 + converter/other/fiasco/input/read.c | 499 + converter/other/fiasco/input/read.h | 31 + converter/other/fiasco/input/tree.c | 303 + converter/other/fiasco/input/tree.h | 28 + converter/other/fiasco/input/weights.c | 200 + converter/other/fiasco/input/weights.h | 27 + converter/other/fiasco/lib/Makefile | 33 + converter/other/fiasco/lib/arith.c | 708 ++ converter/other/fiasco/lib/arith.h | 122 + converter/other/fiasco/lib/bit-io.c | 327 + converter/other/fiasco/lib/bit-io.h | 58 + converter/other/fiasco/lib/dither.c | 1892 +++ converter/other/fiasco/lib/dither.h | 27 + converter/other/fiasco/lib/error.c | 326 + converter/other/fiasco/lib/error.h | 39 + converter/other/fiasco/lib/image.c | 512 + converter/other/fiasco/lib/image.h | 59 + converter/other/fiasco/lib/list.c | 258 + converter/other/fiasco/lib/list.h | 72 + converter/other/fiasco/lib/macros.h | 70 + converter/other/fiasco/lib/misc.c | 563 + converter/other/fiasco/lib/misc.h | 98 + converter/other/fiasco/lib/mvcode.c | 14 + converter/other/fiasco/lib/mvcode.h | 6 + converter/other/fiasco/lib/rpf.c | 223 + converter/other/fiasco/lib/rpf.h | 47 + converter/other/fiasco/lib/types.h | 38 + converter/other/fiasco/output/Makefile | 26 + converter/other/fiasco/output/matrices.c | 547 + converter/other/fiasco/output/matrices.h | 28 + converter/other/fiasco/output/mc.c | 250 + converter/other/fiasco/output/mc.h | 28 + converter/other/fiasco/output/nd.c | 244 + converter/other/fiasco/output/nd.h | 27 + converter/other/fiasco/output/tree.c | 176 + converter/other/fiasco/output/tree.h | 27 + converter/other/fiasco/output/weights.c | 200 + converter/other/fiasco/output/weights.h | 27 + converter/other/fiasco/output/write.c | 250 + converter/other/fiasco/output/write.h | 28 + converter/other/fiasco/params.c | 727 ++ converter/other/fiasco/params.h | 61 + converter/other/fiasco/pnmtofiasco.c | 411 + converter/other/fiasco/system.fiascorc | 120 + converter/other/fitstopnm.c | 494 + converter/other/gemtopnm.c | 305 + converter/other/giftopnm.c | 1460 +++ converter/other/hdifftopam.c | 156 + converter/other/infotopam.c | 543 + converter/other/jbig/ANNOUNCE | 243 + converter/other/jbig/Makefile | 47 + converter/other/jbig/README.Netpbm | 12 + converter/other/jbig/jbig.c | 2905 +++++ converter/other/jbig/jbig.doc | 721 ++ converter/other/jbig/jbig.h | 267 + converter/other/jbig/jbig_tab.c | 428 + converter/other/jbig/jbigtopnm.c | 286 + converter/other/jbig/pnmtojbig.c | 463 + converter/other/jpeg2000/Makefile | 77 + converter/other/jpeg2000/jpeg2ktopam.c | 498 + converter/other/jpeg2000/libjasper/Makefile | 28 + converter/other/jpeg2000/libjasper/Makefile.common | 41 + converter/other/jpeg2000/libjasper/README | 17 + converter/other/jpeg2000/libjasper/base/Makefile | 21 + .../other/jpeg2000/libjasper/base/jas_debug.c | 186 + .../other/jpeg2000/libjasper/base/jas_getopt.c | 217 + .../other/jpeg2000/libjasper/base/jas_image.c | 968 ++ converter/other/jpeg2000/libjasper/base/jas_init.c | 200 + .../other/jpeg2000/libjasper/base/jas_malloc.c | 167 + converter/other/jpeg2000/libjasper/base/jas_seq.c | 475 + .../other/jpeg2000/libjasper/base/jas_stream.c | 1204 ++ .../other/jpeg2000/libjasper/base/jas_string.c | 145 + converter/other/jpeg2000/libjasper/base/jas_tvp.c | 286 + .../other/jpeg2000/libjasper/base/jas_version.c | 116 + converter/other/jpeg2000/libjasper/base/partlist | 1 + .../jpeg2000/libjasper/include/jasper/jas_debug.h | 161 + .../jpeg2000/libjasper/include/jasper/jas_fix.h | 406 + .../jpeg2000/libjasper/include/jasper/jas_getopt.h | 178 + .../jpeg2000/libjasper/include/jasper/jas_image.h | 593 + .../jpeg2000/libjasper/include/jasper/jas_init.h | 128 + .../jpeg2000/libjasper/include/jasper/jas_malloc.h | 171 + .../jpeg2000/libjasper/include/jasper/jas_math.h | 164 + .../jpeg2000/libjasper/include/jasper/jas_seq.h | 348 + .../jpeg2000/libjasper/include/jasper/jas_stream.h | 498 + .../jpeg2000/libjasper/include/jasper/jas_string.h | 143 + .../jpeg2000/libjasper/include/jasper/jas_tvp.h | 198 + .../jpeg2000/libjasper/include/jasper/jas_types.h | 14 + .../libjasper/include/jasper/jas_types.h.orig | 228 + .../libjasper/include/jasper/jas_version.h | 167 + .../jpeg2000/libjasper/include/jasper/jasper.h | 137 + converter/other/jpeg2000/libjasper/jp2/Makefile | 19 + converter/other/jpeg2000/libjasper/jp2/jp2_cod.c | 928 ++ converter/other/jpeg2000/libjasper/jp2/jp2_cod.h | 347 + converter/other/jpeg2000/libjasper/jp2/jp2_dec.c | 649 + converter/other/jpeg2000/libjasper/jp2/jp2_dec.h | 134 + converter/other/jpeg2000/libjasper/jp2/jp2_enc.c | 414 + converter/other/jpeg2000/libjasper/jp2/partlist | 1 + converter/other/jpeg2000/libjasper/jpc/Makefile | 22 + converter/other/jpeg2000/libjasper/jpc/jpc_bs.c | 478 + converter/other/jpeg2000/libjasper/jpc/jpc_bs.h | 280 + converter/other/jpeg2000/libjasper/jpc/jpc_cod.h | 127 + converter/other/jpeg2000/libjasper/jpc/jpc_cs.c | 1614 +++ converter/other/jpeg2000/libjasper/jpc/jpc_cs.h | 812 ++ converter/other/jpeg2000/libjasper/jpc/jpc_dec.c | 2334 ++++ converter/other/jpeg2000/libjasper/jpc/jpc_dec.h | 745 ++ converter/other/jpeg2000/libjasper/jpc/jpc_enc.c | 2624 ++++ converter/other/jpeg2000/libjasper/jpc/jpc_enc.h | 695 ++ converter/other/jpeg2000/libjasper/jpc/jpc_fix.h | 193 + converter/other/jpeg2000/libjasper/jpc/jpc_flt.h | 129 + converter/other/jpeg2000/libjasper/jpc/jpc_math.c | 170 + converter/other/jpeg2000/libjasper/jpc/jpc_math.h | 155 + converter/other/jpeg2000/libjasper/jpc/jpc_mct.c | 337 + converter/other/jpeg2000/libjasper/jpc/jpc_mct.h | 160 + converter/other/jpeg2000/libjasper/jpc/jpc_mqcod.c | 228 + converter/other/jpeg2000/libjasper/jpc/jpc_mqcod.h | 174 + converter/other/jpeg2000/libjasper/jpc/jpc_mqdec.c | 339 + converter/other/jpeg2000/libjasper/jpc/jpc_mqdec.h | 320 + converter/other/jpeg2000/libjasper/jpc/jpc_mqenc.c | 441 + converter/other/jpeg2000/libjasper/jpc/jpc_mqenc.h | 285 + converter/other/jpeg2000/libjasper/jpc/jpc_qmfb.c | 1125 ++ converter/other/jpeg2000/libjasper/jpc/jpc_qmfb.h | 235 + converter/other/jpeg2000/libjasper/jpc/jpc_t1cod.c | 537 + converter/other/jpeg2000/libjasper/jpc/jpc_t1cod.h | 344 + converter/other/jpeg2000/libjasper/jpc/jpc_t1dec.c | 954 ++ converter/other/jpeg2000/libjasper/jpc/jpc_t1dec.h | 137 + converter/other/jpeg2000/libjasper/jpc/jpc_t1enc.c | 1008 ++ converter/other/jpeg2000/libjasper/jpc/jpc_t1enc.h | 142 + converter/other/jpeg2000/libjasper/jpc/jpc_t2cod.c | 733 ++ converter/other/jpeg2000/libjasper/jpc/jpc_t2cod.h | 348 + converter/other/jpeg2000/libjasper/jpc/jpc_t2dec.c | 626 + converter/other/jpeg2000/libjasper/jpc/jpc_t2dec.h | 144 + converter/other/jpeg2000/libjasper/jpc/jpc_t2enc.c | 704 ++ converter/other/jpeg2000/libjasper/jpc/jpc_t2enc.h | 155 + .../other/jpeg2000/libjasper/jpc/jpc_tagtree.c | 426 + .../other/jpeg2000/libjasper/jpc/jpc_tagtree.h | 216 + converter/other/jpeg2000/libjasper/jpc/jpc_tsfb.c | 662 + converter/other/jpeg2000/libjasper/jpc/jpc_tsfb.h | 222 + converter/other/jpeg2000/libjasper/jpc/jpc_util.c | 243 + converter/other/jpeg2000/libjasper/jpc/jpc_util.h | 126 + converter/other/jpeg2000/libjasper/jpc/partlist | 1 + converter/other/jpeg2000/libjasper/partlist | 4 + converter/other/jpeg2000/libjasper_compat.h | 24 + converter/other/jpeg2000/pamtojpeg2k.c | 522 + converter/other/jpegdatasource.c | 183 + converter/other/jpegdatasource.h | 18 + converter/other/jpegtopnm.c | 970 ++ converter/other/pamrgbatopng.c | 150 + converter/other/pamtodjvurle.c | 293 + converter/other/pamtofits.c | 304 + converter/other/pamtohdiff.c | 142 + converter/other/pamtohtmltbl.c | 284 + converter/other/pamtopfm.c | 304 + converter/other/pamtopnm.c | 155 + converter/other/pamtosvg/Makefile | 55 + converter/other/pamtosvg/README | 109 + converter/other/pamtosvg/autotrace.c | 220 + converter/other/pamtosvg/autotrace.h | 258 + converter/other/pamtosvg/bitmap.c | 116 + converter/other/pamtosvg/bitmap.h | 53 + converter/other/pamtosvg/curve.c | 314 + converter/other/pamtosvg/curve.h | 160 + converter/other/pamtosvg/epsilon-equal.c | 19 + converter/other/pamtosvg/epsilon-equal.h | 20 + converter/other/pamtosvg/exception.c | 55 + converter/other/pamtosvg/exception.h | 43 + converter/other/pamtosvg/fit.c | 1923 +++ converter/other/pamtosvg/fit.h | 34 + converter/other/pamtosvg/image-header.h | 19 + converter/other/pamtosvg/image-proc.c | 516 + converter/other/pamtosvg/image-proc.h | 42 + converter/other/pamtosvg/logreport.c | 17 + converter/other/pamtosvg/logreport.h | 28 + converter/other/pamtosvg/message.h | 47 + converter/other/pamtosvg/output-svg.c | 130 + converter/other/pamtosvg/output-svg.h | 37 + converter/other/pamtosvg/pamtosvg.c | 395 + converter/other/pamtosvg/pamtosvg.test | 6 + converter/other/pamtosvg/point.h | 8 + converter/other/pamtosvg/pxl-outline.c | 1370 +++ converter/other/pamtosvg/pxl-outline.h | 79 + converter/other/pamtosvg/spline.c | 193 + converter/other/pamtosvg/spline.h | 90 + converter/other/pamtosvg/testgrid.svg | 5 + converter/other/pamtosvg/testline.svg | 5 + converter/other/pamtosvg/thin-image.c | 373 + converter/other/pamtosvg/thin-image.h | 37 + converter/other/pamtosvg/vector.c | 254 + converter/other/pamtosvg/vector.h | 71 + converter/other/pamtotga.c | 572 + converter/other/pamtotiff.c | 1110 ++ converter/other/pamtouil.c | 438 + converter/other/pamtoxvmini.c | 250 + converter/other/pbmtopgm.c | 80 + converter/other/pclxl.h | 390 + converter/other/pfmtopam.c | 395 + converter/other/pgmtopbm.c | 723 ++ converter/other/pgmtoppm.c | 153 + converter/other/pm_tiff.h | 41 + converter/other/pngtopnm.c | 1096 ++ converter/other/pngtxt.c | 315 + converter/other/pngtxt.h | 13 + converter/other/pnmtoddif.c | 611 + converter/other/pnmtojpeg.c | 1098 ++ converter/other/pnmtopalm/LICENSE | 16 + converter/other/pnmtopalm/Makefile | 35 + converter/other/pnmtopalm/README | 57 + converter/other/pnmtopalm/gen_palm_colormap.c | 24 + converter/other/pnmtopalm/palm.h | 66 + converter/other/pnmtopalm/palmcolor8.map | 235 + converter/other/pnmtopalm/palmcolormap.c | 277 + converter/other/pnmtopalm/palmgray1.map | 4 + converter/other/pnmtopalm/palmgray2.map | 6 + converter/other/pnmtopalm/palmgray4.map | 8 + converter/other/pnmtopalm/palmtopnm.c | 1131 ++ converter/other/pnmtopalm/pnmtopalm.c | 1235 ++ converter/other/pnmtopclxl.c | 1204 ++ converter/other/pnmtoplainpnm | 3 + converter/other/pnmtopng.README | 101 + converter/other/pnmtopng.c | 2745 +++++ converter/other/pnmtops.c | 1323 ++ converter/other/pnmtorast.c | 310 + converter/other/pnmtorle.c | 267 + converter/other/pnmtosgi.c | 354 + converter/other/pnmtosir.c | 146 + converter/other/pnmtotiffcmyk.c | 1000 ++ converter/other/pnmtoxwd.c | 505 + converter/other/ppmtopgm.c | 95 + converter/other/pstopnm.c | 899 ++ converter/other/pstopnm.csh | 301 + converter/other/rast.c | 465 + converter/other/rast.h | 111 + converter/other/rasttopnm.c | 263 + converter/other/rla.h | 45 + converter/other/rlatopam.c | 433 + converter/other/rletopnm.c | 497 + converter/other/sgi.h | 33 + converter/other/sgitopnm.c | 463 + converter/other/sirtopnm.c | 95 + converter/other/svgtopam.c | 940 ++ converter/other/tiff.c | 468 + converter/other/tifftopnm.c | 1062 ++ converter/other/x10wd.h | 32 + converter/other/x11wd.h | 82 + converter/other/xwdtopnm.c | 1280 ++ converter/other/zeisstopnm.c | 187 + converter/pbm/Makefile | 78 + converter/pbm/atktopbm.c | 362 + converter/pbm/brushtopbm.c | 107 + converter/pbm/cmuwm.h | 17 + converter/pbm/cmuwmtopbm.c | 114 + converter/pbm/ddbugtopbm.c | 173 + converter/pbm/escp2topbm.c | 143 + converter/pbm/g3.h | 146 + converter/pbm/g3topbm.c | 739 ++ converter/pbm/icontopbm.c | 159 + converter/pbm/macp.h | 12 + converter/pbm/macptopbm.c | 140 + converter/pbm/mdaspec.txt | 239 + converter/pbm/mdatopbm.c | 271 + converter/pbm/mgr.h | 25 + converter/pbm/mgrtopbm.c | 145 + converter/pbm/mrftopbm.c | 210 + converter/pbm/pbmto10x.c | 169 + converter/pbm/pbmto4425.c | 179 + converter/pbm/pbmtoascii.c | 165 + converter/pbm/pbmtoatk.c | 188 + converter/pbm/pbmtobbnbg.c | 152 + converter/pbm/pbmtocmuwm.c | 117 + converter/pbm/pbmtodjvurle.c | 140 + converter/pbm/pbmtoepsi.c | 252 + converter/pbm/pbmtoepson.c | 338 + converter/pbm/pbmtoescp2.c | 186 + converter/pbm/pbmtog3.c | 485 + converter/pbm/pbmtog3.test | 23 + converter/pbm/pbmtogem.c | 252 + converter/pbm/pbmtogo.c | 309 + converter/pbm/pbmtoibm23xx.c | 213 + converter/pbm/pbmtoicon.c | 134 + converter/pbm/pbmtolj.c | 564 + converter/pbm/pbmtoln03.c | 260 + converter/pbm/pbmtolps.c | 181 + converter/pbm/pbmtomacp.c | 301 + converter/pbm/pbmtomatrixorbital.c | 87 + converter/pbm/pbmtomda.c | 201 + converter/pbm/pbmtomgr.c | 120 + converter/pbm/pbmtomrf.c | 338 + converter/pbm/pbmtonokia.c | 225 + converter/pbm/pbmtopi3.c | 123 + converter/pbm/pbmtopk.c | 976 ++ converter/pbm/pbmtoplot.c | 76 + converter/pbm/pbmtoppa/CREDITS | 12 + converter/pbm/pbmtoppa/INSTALL-MORE | 187 + converter/pbm/pbmtoppa/LICENSE | 342 + converter/pbm/pbmtoppa/Makefile | 25 + converter/pbm/pbmtoppa/README.Netpbm | 30 + converter/pbm/pbmtoppa/README.REDHAT | 29 + converter/pbm/pbmtoppa/cutswath.c | 360 + converter/pbm/pbmtoppa/cutswath.h | 4 + converter/pbm/pbmtoppa/defaults.h | 65 + converter/pbm/pbmtoppa/pbm.c | 135 + converter/pbm/pbmtoppa/pbmtoppa.c | 449 + converter/pbm/pbmtoppa/pbmtoppa.conf.hp1000 | 18 + converter/pbm/pbmtoppa/pbmtoppa.conf.hp720 | 18 + converter/pbm/pbmtoppa/pbmtoppa.conf.hp820 | 18 + converter/pbm/pbmtoppa/ppa.c | 526 + converter/pbm/pbmtoppa/ppa.h | 74 + converter/pbm/pbmtoppa/ppapbm.h | 29 + converter/pbm/pbmtopsg3.c | 374 + converter/pbm/pbmtoptx.c | 101 + converter/pbm/pbmtowbmp.c | 70 + converter/pbm/pbmtox10bm.c | 120 + converter/pbm/pbmtoxbm.c | 165 + converter/pbm/pbmtoybm.c | 114 + converter/pbm/pbmtozinc.c | 128 + converter/pbm/pi3topbm.c | 112 + converter/pbm/pktopbm.c | 442 + converter/pbm/thinkjettopbm.c | 1792 +++ converter/pbm/thinkjettopbm.l | 251 + converter/pbm/wbmptopbm.c | 112 + converter/pbm/xbmtopbm.c | 255 + converter/pbm/ybmtopbm.c | 113 + converter/pgm/Makefile | 23 + converter/pgm/asciitopgm.c | 163 + converter/pgm/bioradtopgm.c | 152 + converter/pgm/fstopgm.c | 138 + converter/pgm/hipstopgm.c | 181 + converter/pgm/lispmtopgm.c | 172 + converter/pgm/pgmtofs.c | 153 + converter/pgm/pgmtolispm.c | 148 + converter/pgm/pgmtopgm.c | 44 + converter/pgm/psidtopgm.c | 128 + converter/pgm/rawtopgm.c | 284 + converter/pgm/sbigtopgm.c | 208 + converter/pgm/spottopgm.c | 231 + converter/ppm/411toppm.c | 261 + converter/ppm/Makefile | 49 + converter/ppm/autocad.h | 64 + converter/ppm/eyuvtoppm.c | 338 + converter/ppm/gouldtoppm.c | 122 + converter/ppm/hpcdtoppm/Makefile | 25 + converter/ppm/hpcdtoppm/README | 20 + converter/ppm/hpcdtoppm/hpcdtoppm | 25 + converter/ppm/hpcdtoppm/pcdovtoppm | 214 + converter/ppm/ilbm.h | 256 + converter/ppm/ilbmtoppm.c | 2381 ++++ converter/ppm/imgtoppm.c | 142 + converter/ppm/leaftoppm.c | 216 + converter/ppm/mitsu.h | 97 + converter/ppm/mtvtoppm.c | 68 + converter/ppm/neotoppm.c | 104 + converter/ppm/pc1toppm.c | 233 + converter/ppm/pcxstd.ppm | 19 + converter/ppm/pcxtoppm.c | 710 ++ converter/ppm/pi1toppm.c | 92 + converter/ppm/picttoppm.c | 3788 ++++++ converter/ppm/pjtoppm.c | 253 + converter/ppm/ppmtoacad.c | 394 + converter/ppm/ppmtoarbtxt.c | 505 + converter/ppm/ppmtobmp.c | 795 ++ converter/ppm/ppmtoeyuv.c | 396 + converter/ppm/ppmtogif.c | 1681 +++ converter/ppm/ppmtoicr.c | 320 + converter/ppm/ppmtoilbm.c | 2362 ++++ converter/ppm/ppmtoleaf.c | 250 + converter/ppm/ppmtolj.c | 297 + converter/ppm/ppmtomitsu.c | 604 + converter/ppm/ppmtompeg/BUGS | 43 + converter/ppm/ppmtompeg/CHANGES | 180 + converter/ppm/ppmtompeg/COPYRIGHT | 20 + converter/ppm/ppmtompeg/HISTORY | 313 + converter/ppm/ppmtompeg/LOGIC | 126 + converter/ppm/ppmtompeg/Makefile | 140 + converter/ppm/ppmtompeg/bframe.c | 1347 +++ converter/ppm/ppmtompeg/bitio.c | 536 + converter/ppm/ppmtompeg/block.c | 1045 ++ converter/ppm/ppmtompeg/bsearch.c | 1088 ++ converter/ppm/ppmtompeg/combine.c | 357 + converter/ppm/ppmtompeg/docs/EXTENSIONS | 41 + converter/ppm/ppmtompeg/docs/INPUT.FORMAT | 79 + converter/ppm/ppmtompeg/docs/parallel.param | 142 + converter/ppm/ppmtompeg/docs/param-summary | 14 + converter/ppm/ppmtompeg/docs/template.param | 154 + converter/ppm/ppmtompeg/docs/users-guide.ps | 3233 +++++ converter/ppm/ppmtompeg/examples/basicspeed.param | 34 + converter/ppm/ppmtompeg/examples/decoded.test | 81 + converter/ppm/ppmtompeg/examples/decoded2.test | 81 + converter/ppm/ppmtompeg/examples/decorig.param | 35 + converter/ppm/ppmtompeg/examples/default.param | 34 + converter/ppm/ppmtompeg/examples/fastspeed.param | 46 + converter/ppm/ppmtompeg/examples/foobar.param | 34 + converter/ppm/ppmtompeg/examples/frame.test | 37 + converter/ppm/ppmtompeg/examples/gop.combine | 11 + converter/ppm/ppmtompeg/examples/gop.test | 43 + converter/ppm/ppmtompeg/examples/gop1.param | 35 + converter/ppm/ppmtompeg/examples/hello.param | 60 + converter/ppm/ppmtompeg/examples/i.test | 37 + converter/ppm/ppmtompeg/examples/ispeed.jpeg.param | 48 + converter/ppm/ppmtompeg/examples/ispeed.param | 45 + converter/ppm/ppmtompeg/examples/jpeg.test | 66 + converter/ppm/ppmtompeg/examples/jpeg19.param | 35 + converter/ppm/ppmtompeg/examples/jpegout19.param | 35 + converter/ppm/ppmtompeg/examples/localdisk.param | 34 + converter/ppm/ppmtompeg/examples/localremote.test | 80 + converter/ppm/ppmtompeg/examples/luxo.param | 34 + converter/ppm/ppmtompeg/examples/luxo18.param | 35 + converter/ppm/ppmtompeg/examples/luxo19.5.param | 35 + converter/ppm/ppmtompeg/examples/luxo19.param | 35 + converter/ppm/ppmtompeg/examples/luxo2.param | 35 + converter/ppm/ppmtompeg/examples/luxo48.param | 35 + converter/ppm/ppmtompeg/examples/luxo49.param | 35 + converter/ppm/ppmtompeg/examples/luxo50.param | 35 + converter/ppm/ppmtompeg/examples/luxo52.5.param | 35 + converter/ppm/ppmtompeg/examples/luxo52.param | 35 + converter/ppm/ppmtompeg/examples/luxo53.param | 35 + converter/ppm/ppmtompeg/examples/luxobug.param | 34 + converter/ppm/ppmtompeg/examples/luxoskip.param | 34 + converter/ppm/ppmtompeg/examples/med.param | 36 + converter/ppm/ppmtompeg/examples/med18.param | 34 + converter/ppm/ppmtompeg/examples/medspeed.param | 38 + converter/ppm/ppmtompeg/examples/nametest.param | 60 + converter/ppm/ppmtompeg/examples/nosearch.param | 34 + converter/ppm/ppmtompeg/examples/par3.param | 43 + converter/ppm/ppmtompeg/examples/par4.param | 45 + converter/ppm/ppmtompeg/examples/par5.param | 47 + converter/ppm/ppmtompeg/examples/parallel.2 | 87 + converter/ppm/ppmtompeg/examples/parallel.param | 141 + converter/ppm/ppmtompeg/examples/parallel.test | 85 + converter/ppm/ppmtompeg/examples/param.template | 107 + converter/ppm/ppmtompeg/examples/payam.param | 37 + converter/ppm/ppmtompeg/examples/payam18.param | 34 + converter/ppm/ppmtompeg/examples/pnm.param | 37 + converter/ppm/ppmtompeg/examples/ppm.param | 37 + converter/ppm/ppmtompeg/examples/prof.b.param | 48 + converter/ppm/ppmtompeg/examples/prof.bhalf.param | 48 + converter/ppm/ppmtompeg/examples/prof.param | 36 + converter/ppm/ppmtompeg/examples/prof.ss.param | 48 + converter/ppm/ppmtompeg/examples/prof2.param | 36 + converter/ppm/ppmtompeg/examples/prof3.param | 36 + converter/ppm/ppmtompeg/examples/prof4.param | 35 + converter/ppm/ppmtompeg/examples/remote.test | 85 + converter/ppm/ppmtompeg/examples/search1.param | 34 + converter/ppm/ppmtompeg/examples/search10.param | 34 + converter/ppm/ppmtompeg/examples/search11.param | 34 + converter/ppm/ppmtompeg/examples/search12.param | 34 + converter/ppm/ppmtompeg/examples/search13.param | 34 + converter/ppm/ppmtompeg/examples/search14.param | 34 + converter/ppm/ppmtompeg/examples/search15.param | 34 + converter/ppm/ppmtompeg/examples/search16.param | 34 + converter/ppm/ppmtompeg/examples/search17.param | 34 + converter/ppm/ppmtompeg/examples/search18.param | 34 + converter/ppm/ppmtompeg/examples/search19.5.param | 35 + converter/ppm/ppmtompeg/examples/search19.param | 42 + converter/ppm/ppmtompeg/examples/search2.param | 34 + converter/ppm/ppmtompeg/examples/search20.param | 34 + converter/ppm/ppmtompeg/examples/search21.param | 34 + converter/ppm/ppmtompeg/examples/search22.param | 34 + converter/ppm/ppmtompeg/examples/search23.param | 34 + converter/ppm/ppmtompeg/examples/search24.param | 34 + converter/ppm/ppmtompeg/examples/search25.param | 34 + converter/ppm/ppmtompeg/examples/search26.param | 34 + converter/ppm/ppmtompeg/examples/search27.param | 34 + converter/ppm/ppmtompeg/examples/search28.param | 34 + converter/ppm/ppmtompeg/examples/search29.param | 34 + converter/ppm/ppmtompeg/examples/search3.param | 34 + converter/ppm/ppmtompeg/examples/search30.param | 34 + converter/ppm/ppmtompeg/examples/search31.param | 34 + converter/ppm/ppmtompeg/examples/search32.param | 34 + converter/ppm/ppmtompeg/examples/search33.param | 34 + converter/ppm/ppmtompeg/examples/search34.param | 34 + converter/ppm/ppmtompeg/examples/search35.param | 34 + converter/ppm/ppmtompeg/examples/search36.param | 34 + converter/ppm/ppmtompeg/examples/search37.param | 34 + converter/ppm/ppmtompeg/examples/search38.param | 34 + converter/ppm/ppmtompeg/examples/search39.param | 34 + converter/ppm/ppmtompeg/examples/search4.param | 34 + converter/ppm/ppmtompeg/examples/search40.param | 34 + converter/ppm/ppmtompeg/examples/search41.param | 34 + converter/ppm/ppmtompeg/examples/search42.param | 34 + converter/ppm/ppmtompeg/examples/search43.param | 34 + converter/ppm/ppmtompeg/examples/search44.param | 34 + converter/ppm/ppmtompeg/examples/search45.param | 34 + converter/ppm/ppmtompeg/examples/search46.param | 34 + converter/ppm/ppmtompeg/examples/search47.param | 34 + converter/ppm/ppmtompeg/examples/search48.param | 35 + converter/ppm/ppmtompeg/examples/search49.param | 35 + converter/ppm/ppmtompeg/examples/search5.param | 34 + converter/ppm/ppmtompeg/examples/search50.param | 35 + converter/ppm/ppmtompeg/examples/search51.param | 34 + converter/ppm/ppmtompeg/examples/search52.5.param | 35 + converter/ppm/ppmtompeg/examples/search52.param | 35 + converter/ppm/ppmtompeg/examples/search53.param | 35 + converter/ppm/ppmtompeg/examples/search6.param | 34 + converter/ppm/ppmtompeg/examples/search7.param | 34 + converter/ppm/ppmtompeg/examples/search8.param | 34 + converter/ppm/ppmtompeg/examples/search9.param | 34 + converter/ppm/ppmtompeg/examples/seq.param | 36 + converter/ppm/ppmtompeg/examples/sequoia.param | 35 + converter/ppm/ppmtompeg/examples/sequoia19.param | 35 + converter/ppm/ppmtompeg/examples/sequoia2.param | 36 + converter/ppm/ppmtompeg/examples/simple.param | 40 + converter/ppm/ppmtompeg/examples/slice.param | 47 + converter/ppm/ppmtompeg/examples/slimed.param | 34 + converter/ppm/ppmtompeg/examples/slowspeed.param | 38 + converter/ppm/ppmtompeg/examples/stanford.param | 34 + converter/ppm/ppmtompeg/examples/subtest.param | 34 + converter/ppm/ppmtompeg/examples/temp.param | 35 + converter/ppm/ppmtompeg/examples/template.param | 154 + converter/ppm/ppmtompeg/examples/tennis.param | 37 + converter/ppm/ppmtompeg/examples/tennis18.param | 35 + converter/ppm/ppmtompeg/examples/tennis19.5.param | 35 + converter/ppm/ppmtompeg/examples/tennis19.param | 35 + converter/ppm/ppmtompeg/examples/tennis48.param | 35 + converter/ppm/ppmtompeg/examples/tennis49.param | 35 + converter/ppm/ppmtompeg/examples/tennis50.param | 35 + converter/ppm/ppmtompeg/examples/tennis52.5.param | 35 + converter/ppm/ppmtompeg/examples/tennis52.param | 35 + converter/ppm/ppmtompeg/examples/tennis53.param | 35 + converter/ppm/ppmtompeg/examples/tennisbug.param | 35 + converter/ppm/ppmtompeg/examples/testp.param | 45 + converter/ppm/ppmtompeg/examples/walk.param | 61 + converter/ppm/ppmtompeg/examples/walk1.param | 61 + converter/ppm/ppmtompeg/examples/walk18.param | 35 + converter/ppm/ppmtompeg/examples/walk19.5.param | 35 + converter/ppm/ppmtompeg/examples/walk19.param | 35 + converter/ppm/ppmtompeg/examples/walk2.param | 61 + converter/ppm/ppmtompeg/examples/walk3.param | 61 + converter/ppm/ppmtompeg/examples/walk4.param | 61 + converter/ppm/ppmtompeg/examples/walk48.param | 35 + converter/ppm/ppmtompeg/examples/walk49.param | 35 + converter/ppm/ppmtompeg/examples/walk5.param | 62 + converter/ppm/ppmtompeg/examples/walk50.param | 35 + converter/ppm/ppmtompeg/examples/walk52.5.param | 35 + converter/ppm/ppmtompeg/examples/walk52.param | 35 + converter/ppm/ppmtompeg/examples/walk53.param | 35 + converter/ppm/ppmtompeg/examples/walk93.param | 62 + converter/ppm/ppmtompeg/file.c | 322 + converter/ppm/ppmtompeg/frame.c | 836 ++ converter/ppm/ppmtompeg/frametype.c | 365 + converter/ppm/ppmtompeg/fsize.c | 134 + converter/ppm/ppmtompeg/gethostname.c | 26 + converter/ppm/ppmtompeg/gethostname.h | 7 + converter/ppm/ppmtompeg/headers/all.h | 95 + converter/ppm/ppmtompeg/headers/ansi.h | 76 + converter/ppm/ppmtompeg/headers/bitio.h | 140 + converter/ppm/ppmtompeg/headers/block.h | 53 + converter/ppm/ppmtompeg/headers/byteorder.h | 77 + converter/ppm/ppmtompeg/headers/combine.h | 20 + converter/ppm/ppmtompeg/headers/dct.h | 79 + converter/ppm/ppmtompeg/headers/frame.h | 147 + converter/ppm/ppmtompeg/headers/frames.h | 487 + converter/ppm/ppmtompeg/headers/frametype.h | 17 + converter/ppm/ppmtompeg/headers/fsize.h | 49 + converter/ppm/ppmtompeg/headers/general.h | 174 + converter/ppm/ppmtompeg/headers/huff.h | 34 + converter/ppm/ppmtompeg/headers/input.h | 70 + converter/ppm/ppmtompeg/headers/jpeg.h | 12 + converter/ppm/ppmtompeg/headers/mheaders.h | 114 + converter/ppm/ppmtompeg/headers/motion_search.h | 154 + converter/ppm/ppmtompeg/headers/mpeg.h | 116 + converter/ppm/ppmtompeg/headers/mproto.h | 132 + converter/ppm/ppmtompeg/headers/mtypes.h | 109 + converter/ppm/ppmtompeg/headers/opts.h | 125 + converter/ppm/ppmtompeg/headers/parallel.h | 135 + converter/ppm/ppmtompeg/headers/param.h | 87 + converter/ppm/ppmtompeg/headers/postdct.h | 40 + converter/ppm/ppmtompeg/headers/prototypes.h | 78 + converter/ppm/ppmtompeg/headers/psocket.h | 41 + converter/ppm/ppmtompeg/headers/rate.h | 204 + converter/ppm/ppmtompeg/headers/readframe.h | 69 + converter/ppm/ppmtompeg/headers/rgbtoycc.h | 39 + converter/ppm/ppmtompeg/headers/specifics.h | 36 + converter/ppm/ppmtompeg/huff.c | 131 + converter/ppm/ppmtompeg/huff.h | 34 + converter/ppm/ppmtompeg/huff.table | 172 + converter/ppm/ppmtompeg/iframe.c | 1062 ++ converter/ppm/ppmtompeg/input.c | 515 + converter/ppm/ppmtompeg/jpeg.c | 634 + converter/ppm/ppmtompeg/jrevdct.c | 1278 ++ converter/ppm/ppmtompeg/memory.c | 71 + converter/ppm/ppmtompeg/mfwddct.c | 393 + converter/ppm/ppmtompeg/mheaders.c | 1192 ++ converter/ppm/ppmtompeg/moutput.c | 442 + converter/ppm/ppmtompeg/mpeg.c | 1717 +++ converter/ppm/ppmtompeg/mquant.c | 44 + converter/ppm/ppmtompeg/nojpeg.c | 61 + converter/ppm/ppmtompeg/noparallel.c | 229 + converter/ppm/ppmtompeg/opts.c | 536 + converter/ppm/ppmtompeg/parallel.c | 2278 ++++ converter/ppm/ppmtompeg/param.c | 1077 ++ converter/ppm/ppmtompeg/parse_huff.pl | 198 + converter/ppm/ppmtompeg/pframe.c | 1072 ++ converter/ppm/ppmtompeg/postdct.c | 626 + converter/ppm/ppmtompeg/ppmtompeg.c | 722 ++ converter/ppm/ppmtompeg/psearch.c | 989 ++ converter/ppm/ppmtompeg/psocket.c | 452 + converter/ppm/ppmtompeg/qtest.c | 63 + converter/ppm/ppmtompeg/rate.c | 986 ++ converter/ppm/ppmtompeg/readframe.c | 1016 ++ converter/ppm/ppmtompeg/rgbtoycc.c | 204 + converter/ppm/ppmtompeg/specifics.c | 688 ++ converter/ppm/ppmtompeg/subsample.c | 280 + converter/ppm/ppmtompeg/tst/README | 30 + converter/ppm/ppmtompeg/tst/gop.param | 30 + converter/ppm/ppmtompeg/tst/par3.param | 43 + converter/ppm/ppmtompeg/tst/short.param | 31 + converter/ppm/ppmtompeg/tst/test_all | 19 + converter/ppm/ppmtompeg/tst/ts.mpg | Bin 0 -> 40978 bytes converter/ppm/ppmtompeg/tst/ts.param | 29 + converter/ppm/ppmtompeg/tst/ts.stat | 52 + converter/ppm/ppmtompeg/tst/ts/stennis.30.jpg | Bin 0 -> 19080 bytes converter/ppm/ppmtompeg/tst/ts/stennis.31.jpg | Bin 0 -> 18678 bytes converter/ppm/ppmtompeg/tst/ts/stennis.32.jpg | Bin 0 -> 18379 bytes converter/ppm/ppmtompeg/tst/ts/stennis.33.jpg | Bin 0 -> 18012 bytes converter/ppm/ppmtompeg/tst/ts/stennis.34.jpg | Bin 0 -> 17871 bytes converter/ppm/ppmtompeg/tst/ts/stennis.35.jpg | Bin 0 -> 17398 bytes converter/ppm/ppmtompeg/tst/ts/stennis.36.jpg | Bin 0 -> 17085 bytes converter/ppm/ppmtompeg/tst/ts/stennis.37.jpg | Bin 0 -> 16806 bytes converter/ppm/ppmtompeg/tst/ts/stennis.38.jpg | Bin 0 -> 16522 bytes converter/ppm/ppmtompeg/tst/ts/stennis.39.jpg | Bin 0 -> 16291 bytes converter/ppm/ppmtompeg/tst/ts2.param | 33 + converter/ppm/ppmtompeg/tst/ts2.stat | 52 + converter/ppm/ppmtompeg/tst/ts3.param | 32 + converter/ppm/ppmtompeg/tst/ts4.param | 56 + converter/ppm/ppmtompeg/tst/tsd.param | 32 + converter/ppm/ppmtompeg/tst/tsd.stat | 52 + converter/ppm/ppmtompeg/tst/tstl.param | 31 + converter/ppm/ppmtoneo.c | 123 + converter/ppm/ppmtopcx.c | 906 ++ converter/ppm/ppmtopi1.c | 120 + converter/ppm/ppmtopict.c | 481 + converter/ppm/ppmtopj.c | 256 + converter/ppm/ppmtopjxl.c | 423 + converter/ppm/ppmtoppm.c | 44 + converter/ppm/ppmtopuzz.c | 96 + converter/ppm/ppmtorgb3.c | 99 + converter/ppm/ppmtosixel.c | 215 + converter/ppm/ppmtoterm.c | 173 + converter/ppm/ppmtowinicon.c | 881 ++ converter/ppm/ppmtoxpm.c | 659 + converter/ppm/ppmtoyuv.c | 97 + converter/ppm/ppmtoyuvsplit.c | 197 + converter/ppm/qrttoppm.c | 69 + converter/ppm/rawtoppm.c | 244 + converter/ppm/rgb3toppm.c | 88 + converter/ppm/sldtoppm.c | 650 + converter/ppm/spctoppm.c | 212 + converter/ppm/sputoppm.c | 108 + converter/ppm/tgatoppm.c | 462 + converter/ppm/vidtoppm.c | 270 + converter/ppm/winico.h | 88 + converter/ppm/winico.html | 701 ++ converter/ppm/winicontoppm.c | 899 ++ converter/ppm/xim.h | 125 + converter/ppm/ximtoppm.c | 438 + converter/ppm/xpmtoppm.README | 69 + converter/ppm/xpmtoppm.c | 832 ++ converter/ppm/xvminitoppm.c | 207 + converter/ppm/yuvsplittoppm.c | 251 + converter/ppm/yuvtoppm.c | 115 + converter/tga.h | 46 + doc/COPYRIGHT.PATENT | 125 + doc/GPL_LICENSE.txt | 340 + doc/HISTORY | 3385 ++++++ doc/INSTALL | 248 + doc/Netpbm.programming | 358 + doc/README.CYGWIN | 79 + doc/README.DJGPP | 65 + doc/USERDOC | 155 + doc/copyright_summary | 382 + doc/lgpl_v21.txt | 504 + doc/netpbm.1 | 4 + doc/netpbm.html | 3 + editor/Makefile | 86 + editor/dithers.h | 87 + editor/pamaddnoise.c | 486 + editor/pamcomp.c | 619 + editor/pamcut.c | 573 + editor/pamcut.test | 10 + editor/pamdeinterlace.c | 132 + editor/pamdice.c | 494 + editor/pamdither.c | 319 + editor/pamditherbw.c | 743 ++ editor/pamedge.c | 203 + editor/pamenlarge.c | 117 + editor/pamenlarge.test | 8 + editor/pamflip.c | 910 ++ editor/pamflip.test | 12 + editor/pamfunc.c | 221 + editor/pammasksharpen.c | 192 + editor/pammixinterlace.c | 173 + editor/pamoil.c | 137 + editor/pamperspective.c | 1331 ++ editor/pampop9.c | 108 + editor/pamscale.c | 2149 ++++ editor/pamstretch-gen | 80 + editor/pamstretch.c | 408 + editor/pamthreshold.c | 623 + editor/pbmclean.c | 239 + editor/pbmlife.c | 114 + editor/pbmmask.c | 222 + editor/pbmpscale.c | 199 + editor/pbmreduce.c | 208 + editor/pgmabel.c | 316 + editor/pgmbentley.c | 64 + editor/pgmdeshadow.c | 343 + editor/pgmenhance.c | 112 + editor/pgmmedian.c | 462 + editor/pgmmorphconv.c | 253 + editor/pnmalias.c | 250 + editor/pnmcat.c | 427 + editor/pnmcomp.c | 459 + editor/pnmconvol.c | 1989 +++ editor/pnmcrop.c | 613 + editor/pnmcut.c | 427 + editor/pnmflip | 80 + editor/pnmgamma.c | 753 ++ editor/pnmhisteq.c | 416 + editor/pnmindex.c | 638 + editor/pnmindex.csh | 189 + editor/pnmindex.sh | 215 + editor/pnminvert.c | 115 + editor/pnminvert.test | 15 + editor/pnmmargin | 88 + editor/pnmmontage.c | 439 + editor/pnmnlfilt.c | 1028 ++ editor/pnmnorm.c | 620 + editor/pnmpad.c | 387 + editor/pnmpaste.c | 185 + editor/pnmquant | 275 + editor/pnmremap.c | 872 ++ editor/pnmrotate.c | 808 ++ editor/pnmscale.c | 748 ++ editor/pnmscalefixed.c | 590 + editor/pnmshear.c | 227 + editor/pnmsmooth.README | 21 + editor/pnmsmooth.c | 241 + editor/pnmstitch.c | 2408 ++++ editor/pnmtile.c | 63 + editor/ppm3d.c | 138 + editor/ppmbrighten.c | 337 + editor/ppmchange.c | 232 + editor/ppmcolormask.c | 245 + editor/ppmdim.c | 112 + editor/ppmdist.c | 170 + editor/ppmdither.c | 309 + editor/ppmdraw.c | 885 ++ editor/ppmfade | 309 + editor/ppmflash.c | 114 + editor/ppmglobe.c | 172 + editor/ppmlabel.c | 212 + editor/ppmmix.c | 131 + editor/ppmntsc.c | 499 + editor/ppmquant | 30 + editor/ppmquantall | 97 + editor/ppmquantall.csh | 57 + editor/ppmrelief.c | 90 + editor/ppmshadow | 273 + editor/ppmshadow.doc | 627 + editor/ppmshift.c | 137 + editor/ppmspread.c | 127 + editor/ppmtv.c | 105 + generator/Makefile | 40 + generator/pamgauss.c | 207 + generator/pamgradient.c | 215 + generator/pamseq.c | 202 + generator/pamstereogram.c | 885 ++ generator/pamstereogram.test | 70 + generator/pbmmake.c | 184 + generator/pbmmake.test | 9 + generator/pbmpage.c | 291 + generator/pbmtext.c | 732 ++ generator/pbmtextps.c | 377 + generator/pbmupc.c | 544 + generator/pgmcrater.c | 383 + generator/pgmkernel.c | 91 + generator/pgmmake.c | 111 + generator/pgmnoise.c | 77 + generator/pgmramp.c | 170 + generator/ppmcie.c | 1201 ++ generator/ppmcolors.c | 87 + generator/ppmforge.c | 1182 ++ generator/ppmmake.c | 117 + generator/ppmpat.c | 1060 ++ generator/ppmrainbow | 74 + generator/ppmrough.c | 292 + generator/ppmwheel.c | 157 + installnetpbm | 3 + inttypes_netpbm.h | 8 + lib/Makefile | 278 + lib/bitio.c | 207 + lib/bitio.h | 89 + lib/colorname.c | 208 + lib/colorname.h | 43 + lib/compile.h | 5 + lib/fileio.c | 170 + lib/fileio.h | 22 + lib/libpam.c | 1098 ++ lib/libpam.h | 17 + lib/libpamcolor.c | 102 + lib/libpammap.c | 662 + lib/libpamn.c | 542 + lib/libpamread.c | 277 + lib/libpamwrite.c | 397 + lib/libpbm.h | 12 + lib/libpbm1.c | 62 + lib/libpbm2.c | 180 + lib/libpbm3.c | 282 + lib/libpbmfont.c | 1136 ++ lib/libpbmvms.c | 734 ++ lib/libpgm.h | 24 + lib/libpgm1.c | 324 + lib/libpgm2.c | 226 + lib/libpm.c | 1494 +++ lib/libpnm1.c | 222 + lib/libpnm2.c | 128 + lib/libpnm3.c | 393 + lib/libppm.h | 15 + lib/libppm1.c | 328 + lib/libppm2.c | 208 + lib/libppmcmap.c | 650 + lib/libppmcolor.c | 710 ++ lib/libppmd.c | 1177 ++ lib/libppmfloyd.c | 270 + lib/libppmfuzzy.c | 434 + lib/libsystem.c | 319 + lib/libsystem_dummy.c | 47 + lib/lum.h | 123 + lib/mkstemp.c | 8 + lib/pam.h | 490 + lib/pammap.h | 124 + lib/path.c | 468 + lib/pbm.h | 97 + lib/pbmfont.h | 75 + lib/pgm.h | 136 + lib/pm.h | 346 + lib/pm_gamma.h | 68 + lib/pm_system.h | 43 + lib/pnm.h | 134 + lib/ppm.h | 300 + lib/ppmcmap.h | 111 + lib/ppmdfont.c | 133 + lib/ppmdfont.h | 74 + lib/ppmdraw.h | 303 + lib/ppmfloyd.h | 67 + lib/rgb.txt | 881 ++ lib/standard.ppmdfont | Bin 0 -> 3899 bytes lib/standardppmdfont.c | 3177 +++++ lib/util/LICENSE.txt | 121 + lib/util/Makefile | 29 + lib/util/bitreverse.h | 46 + lib/util/filename.c | 26 + lib/util/filename.h | 7 + lib/util/intcode.h | 86 + lib/util/lexheader | 9 + lib/util/mallocvar.h | 107 + lib/util/nstring.c | 906 ++ lib/util/nstring.h | 157 + lib/util/pm_c_util.h | 62 + lib/util/shhopt-1.1.6.lsm | 16 + lib/util/shhopt.README | 200 + lib/util/shhopt.c | 939 ++ lib/util/shhopt.h | 240 + lib/util/testnstring.c | 30 + lib/util/wordaccess.h | 65 + lib/util/wordaccess_64_le.h | 52 + lib/util/wordaccess_gcc3_be.h | 40 + lib/util/wordaccess_gcc3_le.h | 54 + lib/util/wordaccess_generic.h | 89 + manweb | 427 + netpbm.c | 80 + other/Makefile | 75 + other/pamarith.c | 503 + other/pambayer.c | 297 + other/pamchannel.c | 199 + other/pamdepth.c | 175 + other/pamendian.c | 70 + other/pamlookup.c | 299 + other/pampick.c | 250 + other/pamsplit.c | 187 + other/pamstack.c | 240 + other/pamsummcol.c | 257 + other/pamx/COPYRIGHT | 72 + other/pamx/Makefile | 43 + other/pamx/Makefile2 | 51 + other/pamx/fill.c | 82 + other/pamx/fill.h | 16 + other/pamx/image.c | 331 + other/pamx/image.h | 90 + other/pamx/pamx.c | 364 + other/pamx/send.c | 872 ++ other/pamx/send.h | 38 + other/pamx/valtomem.h | 65 + other/pamx/window.c | 1209 ++ other/pamx/window.h | 38 + other/pamx/ximageinfo.h | 25 + other/pnmcolormap.c | 973 ++ other/ppmdcfont.c | 200 + other/ppmddumpfont.c | 89 + other/ppmdmkfont.c | 705 ++ other/ppmsvgalib.c | 283 + other/ppmtomap | 5 + pm_config.h | 302 + pm_config.in.h | 278 + testgrid.pbm | 3 + testimg.ppm | 4 + urt/Makefile | 33 + urt/README | 20 + urt/Runput.c | 356 + urt/Runput.h | 23 + urt/cmd_name.c | 54 + urt/rle.h | 492 + urt/rle_addhist.c | 115 + urt/rle_code.h | 70 + urt/rle_config.h | 105 + urt/rle_error.c | 118 + urt/rle_getcom.c | 99 + urt/rle_getrow.c | 562 + urt/rle_getskip.c | 162 + urt/rle_global.c | 85 + urt/rle_hdr.c | 297 + urt/rle_open_f.c | 310 + urt/rle_put.h | 104 + urt/rle_putcom.c | 169 + urt/rle_putrow.c | 728 ++ urt/rle_row_alc.c | 129 + urt/scanargs.c | 948 ++ urt/vaxshort.c | 50 + urt/vaxshort.h | 5 + version.h | 1 + vms/Add_List.com | 59 + vms/Make_PBMplus.com | 519 + vms/Make_PBMplusShr.com | 280 + vms/NetPBM.TeX | 12115 +++++++++++++++++++ vms/PBMplus.hlp | 6814 +++++++++++ vms/RGB.txt | 738 ++ vms/SetUp.com | 37 + vms/stamp-date.com | 25 + 1133 files changed, 318857 insertions(+) create mode 100644 GNUmakefile create mode 100644 Makefile create mode 100644 Makefile.common create mode 100644 Makefile.config.in create mode 100644 Makefile.srcdir create mode 100644 README create mode 100644 analyzer/Makefile create mode 100644 analyzer/pamfile.c create mode 100644 analyzer/pamsharpmap.c create mode 100644 analyzer/pamsharpness.c create mode 100644 analyzer/pamslice.c create mode 100644 analyzer/pamsumm.c create mode 100644 analyzer/pamtilt.c create mode 100644 analyzer/pbmminkowski.c create mode 100644 analyzer/pgmhist.c create mode 100644 analyzer/pgmminkowski.c create mode 100644 analyzer/pgmtexture.c create mode 100644 analyzer/pnmhistmap.c create mode 100644 analyzer/pnmpsnr.c create mode 100644 analyzer/ppmhist.c create mode 100644 build_complete create mode 100644 buildtools/Makefile create mode 100644 buildtools/Makefile.manpage create mode 100644 buildtools/README.pkg create mode 100644 buildtools/config_template create mode 100755 buildtools/configure.pl create mode 100755 buildtools/empty_depend create mode 100755 buildtools/endiangen create mode 100644 buildtools/endiangen.c create mode 100755 buildtools/install.sh create mode 100755 buildtools/installnetpbm.pl create mode 100755 buildtools/installosf create mode 100755 buildtools/libopt create mode 100644 buildtools/libopt.c create mode 100755 buildtools/make_merge.sh create mode 100755 buildtools/makecat create mode 100755 buildtools/makeman create mode 100755 buildtools/makepointerman create mode 100755 buildtools/mkinstalldirs create mode 100755 buildtools/stamp-date create mode 100755 buildtools/typegen create mode 100644 buildtools/typegen.c create mode 100755 configure create mode 100644 converter/Makefile create mode 100644 converter/bmp.h create mode 100644 converter/other/Makefile create mode 100644 converter/other/README.JPEG create mode 100755 converter/other/anytopnm create mode 100644 converter/other/bmepsoe.c create mode 100644 converter/other/bmepsoe.h create mode 100644 converter/other/bmptopnm.c create mode 100644 converter/other/cameratopam/COPYRIGHT create mode 100644 converter/other/cameratopam/Makefile create mode 100644 converter/other/cameratopam/bayer.h create mode 100644 converter/other/cameratopam/camera.c create mode 100644 converter/other/cameratopam/camera.h create mode 100644 converter/other/cameratopam/cameratopam.c create mode 100644 converter/other/cameratopam/canon.c create mode 100644 converter/other/cameratopam/canon.h create mode 100644 converter/other/cameratopam/decode.c create mode 100644 converter/other/cameratopam/decode.h create mode 100644 converter/other/cameratopam/dng.c create mode 100644 converter/other/cameratopam/dng.h create mode 100644 converter/other/cameratopam/foveon.c create mode 100644 converter/other/cameratopam/foveon.h create mode 100644 converter/other/cameratopam/global_variables.h create mode 100644 converter/other/cameratopam/identify.c create mode 100644 converter/other/cameratopam/identify.h create mode 100644 converter/other/cameratopam/ljpeg.c create mode 100644 converter/other/cameratopam/ljpeg.h create mode 100644 converter/other/cameratopam/util.c create mode 100644 converter/other/cameratopam/util.h create mode 100644 converter/other/dithers.h create mode 100644 converter/other/exif.c create mode 100644 converter/other/exif.h create mode 100644 converter/other/fiasco/Makefile create mode 100644 converter/other/fiasco/README.netpbm create mode 100644 converter/other/fiasco/binerror.c create mode 100644 converter/other/fiasco/binerror.h create mode 100644 converter/other/fiasco/buttons.c create mode 100644 converter/other/fiasco/buttons.h create mode 100644 converter/other/fiasco/codec/Makefile create mode 100644 converter/other/fiasco/codec/approx.c create mode 100644 converter/other/fiasco/codec/approx.h create mode 100644 converter/other/fiasco/codec/bintree.c create mode 100644 converter/other/fiasco/codec/bintree.h create mode 100644 converter/other/fiasco/codec/coder.c create mode 100644 converter/other/fiasco/codec/coder.h create mode 100644 converter/other/fiasco/codec/coeff.c create mode 100644 converter/other/fiasco/codec/coeff.h create mode 100644 converter/other/fiasco/codec/control.c create mode 100644 converter/other/fiasco/codec/control.h create mode 100644 converter/other/fiasco/codec/cwfa.h create mode 100644 converter/other/fiasco/codec/decoder.c create mode 100644 converter/other/fiasco/codec/decoder.h create mode 100644 converter/other/fiasco/codec/dfiasco.c create mode 100644 converter/other/fiasco/codec/dfiasco.h create mode 100644 converter/other/fiasco/codec/domain-pool.c create mode 100644 converter/other/fiasco/codec/domain-pool.h create mode 100644 converter/other/fiasco/codec/ip.c create mode 100644 converter/other/fiasco/codec/ip.h create mode 100644 converter/other/fiasco/codec/motion.c create mode 100644 converter/other/fiasco/codec/motion.h create mode 100644 converter/other/fiasco/codec/mwfa.c create mode 100644 converter/other/fiasco/codec/mwfa.h create mode 100644 converter/other/fiasco/codec/options.c create mode 100644 converter/other/fiasco/codec/options.h create mode 100644 converter/other/fiasco/codec/prediction.c create mode 100644 converter/other/fiasco/codec/prediction.h create mode 100644 converter/other/fiasco/codec/subdivide.c create mode 100644 converter/other/fiasco/codec/subdivide.h create mode 100644 converter/other/fiasco/codec/tiling.c create mode 100644 converter/other/fiasco/codec/tiling.h create mode 100644 converter/other/fiasco/codec/wfa.h create mode 100644 converter/other/fiasco/codec/wfalib.c create mode 100644 converter/other/fiasco/codec/wfalib.h create mode 100644 converter/other/fiasco/config.h create mode 100644 converter/other/fiasco/display.c create mode 100644 converter/other/fiasco/display.h create mode 100644 converter/other/fiasco/doc/README.LIB create mode 100644 converter/other/fiasco/doc/fiasco_c_options.3 create mode 100644 converter/other/fiasco/doc/fiasco_c_options_delete.3 create mode 100644 converter/other/fiasco/doc/fiasco_c_options_new.3 create mode 100644 converter/other/fiasco/doc/fiasco_c_options_set_basisfile.3 create mode 100644 converter/other/fiasco/doc/fiasco_c_options_set_chroma_quality.3 create mode 100644 converter/other/fiasco/doc/fiasco_c_options_set_comment.3 create mode 100644 converter/other/fiasco/doc/fiasco_c_options_set_frame_pattern.3 create mode 100644 converter/other/fiasco/doc/fiasco_c_options_set_optimizations.3 create mode 100644 converter/other/fiasco/doc/fiasco_c_options_set_prediction.3 create mode 100644 converter/other/fiasco/doc/fiasco_c_options_set_progress_meter.3 create mode 100644 converter/other/fiasco/doc/fiasco_c_options_set_quantization.3 create mode 100644 converter/other/fiasco/doc/fiasco_c_options_set_smoothing.3 create mode 100644 converter/other/fiasco/doc/fiasco_c_options_set_tiling.3 create mode 100644 converter/other/fiasco/doc/fiasco_c_options_set_title.3 create mode 100644 converter/other/fiasco/doc/fiasco_c_options_set_video_param.3 create mode 100644 converter/other/fiasco/doc/fiasco_coder.3 create mode 100644 converter/other/fiasco/doc/fiasco_d_options.3 create mode 100644 converter/other/fiasco/doc/fiasco_d_options_delete.3 create mode 100644 converter/other/fiasco/doc/fiasco_d_options_new.3 create mode 100644 converter/other/fiasco/doc/fiasco_d_options_set_4_2_0_format.3 create mode 100644 converter/other/fiasco/doc/fiasco_d_options_set_magnification.3 create mode 100644 converter/other/fiasco/doc/fiasco_d_options_set_smoothing.3 create mode 100644 converter/other/fiasco/doc/fiasco_decoder.3 create mode 100644 converter/other/fiasco/doc/fiasco_decoder_delete.3 create mode 100644 converter/other/fiasco/doc/fiasco_decoder_get_comment.3 create mode 100644 converter/other/fiasco/doc/fiasco_decoder_get_frame.3 create mode 100644 converter/other/fiasco/doc/fiasco_decoder_get_framerate.3 create mode 100644 converter/other/fiasco/doc/fiasco_decoder_get_height.3 create mode 100644 converter/other/fiasco/doc/fiasco_decoder_get_length.3 create mode 100644 converter/other/fiasco/doc/fiasco_decoder_get_title.3 create mode 100644 converter/other/fiasco/doc/fiasco_decoder_get_width.3 create mode 100644 converter/other/fiasco/doc/fiasco_decoder_is_color.3 create mode 100644 converter/other/fiasco/doc/fiasco_decoder_new.3 create mode 100644 converter/other/fiasco/doc/fiasco_decoder_write_frame.3 create mode 100644 converter/other/fiasco/doc/fiasco_get_error_message.3 create mode 100644 converter/other/fiasco/doc/fiasco_get_verbosity.3 create mode 100644 converter/other/fiasco/doc/fiasco_image.3 create mode 100644 converter/other/fiasco/doc/fiasco_image_delete.3 create mode 100644 converter/other/fiasco/doc/fiasco_image_get_height.3 create mode 100644 converter/other/fiasco/doc/fiasco_image_get_width.3 create mode 100644 converter/other/fiasco/doc/fiasco_image_is_color.3 create mode 100644 converter/other/fiasco/doc/fiasco_image_new.3 create mode 100644 converter/other/fiasco/doc/fiasco_options.3 create mode 100644 converter/other/fiasco/doc/fiasco_options_delete.3 create mode 100644 converter/other/fiasco/doc/fiasco_options_new.3 create mode 100644 converter/other/fiasco/doc/fiasco_options_set_4_2_0_format.3 create mode 100644 converter/other/fiasco/doc/fiasco_options_set_basisfile.3 create mode 100644 converter/other/fiasco/doc/fiasco_options_set_chroma_quality.3 create mode 100644 converter/other/fiasco/doc/fiasco_options_set_frame_pattern.3 create mode 100644 converter/other/fiasco/doc/fiasco_options_set_magnification.3 create mode 100644 converter/other/fiasco/doc/fiasco_options_set_optimizations.3 create mode 100644 converter/other/fiasco/doc/fiasco_options_set_prediction.3 create mode 100644 converter/other/fiasco/doc/fiasco_options_set_progress_meter.3 create mode 100644 converter/other/fiasco/doc/fiasco_options_set_quantization.3 create mode 100644 converter/other/fiasco/doc/fiasco_options_set_smoothing.3 create mode 100644 converter/other/fiasco/doc/fiasco_options_set_tiling.3 create mode 100644 converter/other/fiasco/doc/fiasco_options_set_video_param.3 create mode 100644 converter/other/fiasco/doc/fiasco_renderer.3 create mode 100644 converter/other/fiasco/doc/fiasco_renderer_delete.3 create mode 100644 converter/other/fiasco/doc/fiasco_renderer_new.3 create mode 100644 converter/other/fiasco/doc/fiasco_renderer_render.3 create mode 100644 converter/other/fiasco/doc/fiasco_set_verbosity.3 create mode 100644 converter/other/fiasco/fiasco.h create mode 100644 converter/other/fiasco/fiascotopnm.c create mode 100644 converter/other/fiasco/getopt.c create mode 100644 converter/other/fiasco/getopt.h create mode 100644 converter/other/fiasco/getopt1.c create mode 100644 converter/other/fiasco/input/Makefile create mode 100644 converter/other/fiasco/input/basis.c create mode 100644 converter/other/fiasco/input/basis.h create mode 100644 converter/other/fiasco/input/matrices.c create mode 100644 converter/other/fiasco/input/matrices.h create mode 100644 converter/other/fiasco/input/mc.c create mode 100644 converter/other/fiasco/input/mc.h create mode 100644 converter/other/fiasco/input/nd.c create mode 100644 converter/other/fiasco/input/nd.h create mode 100644 converter/other/fiasco/input/read.c create mode 100644 converter/other/fiasco/input/read.h create mode 100644 converter/other/fiasco/input/tree.c create mode 100644 converter/other/fiasco/input/tree.h create mode 100644 converter/other/fiasco/input/weights.c create mode 100644 converter/other/fiasco/input/weights.h create mode 100644 converter/other/fiasco/lib/Makefile create mode 100644 converter/other/fiasco/lib/arith.c create mode 100644 converter/other/fiasco/lib/arith.h create mode 100644 converter/other/fiasco/lib/bit-io.c create mode 100644 converter/other/fiasco/lib/bit-io.h create mode 100644 converter/other/fiasco/lib/dither.c create mode 100644 converter/other/fiasco/lib/dither.h create mode 100644 converter/other/fiasco/lib/error.c create mode 100644 converter/other/fiasco/lib/error.h create mode 100644 converter/other/fiasco/lib/image.c create mode 100644 converter/other/fiasco/lib/image.h create mode 100644 converter/other/fiasco/lib/list.c create mode 100644 converter/other/fiasco/lib/list.h create mode 100644 converter/other/fiasco/lib/macros.h create mode 100644 converter/other/fiasco/lib/misc.c create mode 100644 converter/other/fiasco/lib/misc.h create mode 100644 converter/other/fiasco/lib/mvcode.c create mode 100644 converter/other/fiasco/lib/mvcode.h create mode 100644 converter/other/fiasco/lib/rpf.c create mode 100644 converter/other/fiasco/lib/rpf.h create mode 100644 converter/other/fiasco/lib/types.h create mode 100644 converter/other/fiasco/output/Makefile create mode 100644 converter/other/fiasco/output/matrices.c create mode 100644 converter/other/fiasco/output/matrices.h create mode 100644 converter/other/fiasco/output/mc.c create mode 100644 converter/other/fiasco/output/mc.h create mode 100644 converter/other/fiasco/output/nd.c create mode 100644 converter/other/fiasco/output/nd.h create mode 100644 converter/other/fiasco/output/tree.c create mode 100644 converter/other/fiasco/output/tree.h create mode 100644 converter/other/fiasco/output/weights.c create mode 100644 converter/other/fiasco/output/weights.h create mode 100644 converter/other/fiasco/output/write.c create mode 100644 converter/other/fiasco/output/write.h create mode 100644 converter/other/fiasco/params.c create mode 100644 converter/other/fiasco/params.h create mode 100644 converter/other/fiasco/pnmtofiasco.c create mode 100644 converter/other/fiasco/system.fiascorc create mode 100644 converter/other/fitstopnm.c create mode 100644 converter/other/gemtopnm.c create mode 100644 converter/other/giftopnm.c create mode 100644 converter/other/hdifftopam.c create mode 100644 converter/other/infotopam.c create mode 100644 converter/other/jbig/ANNOUNCE create mode 100644 converter/other/jbig/Makefile create mode 100644 converter/other/jbig/README.Netpbm create mode 100644 converter/other/jbig/jbig.c create mode 100644 converter/other/jbig/jbig.doc create mode 100644 converter/other/jbig/jbig.h create mode 100644 converter/other/jbig/jbig_tab.c create mode 100644 converter/other/jbig/jbigtopnm.c create mode 100644 converter/other/jbig/pnmtojbig.c create mode 100644 converter/other/jpeg2000/Makefile create mode 100644 converter/other/jpeg2000/jpeg2ktopam.c create mode 100644 converter/other/jpeg2000/libjasper/Makefile create mode 100644 converter/other/jpeg2000/libjasper/Makefile.common create mode 100644 converter/other/jpeg2000/libjasper/README create mode 100644 converter/other/jpeg2000/libjasper/base/Makefile create mode 100644 converter/other/jpeg2000/libjasper/base/jas_debug.c create mode 100644 converter/other/jpeg2000/libjasper/base/jas_getopt.c create mode 100644 converter/other/jpeg2000/libjasper/base/jas_image.c create mode 100644 converter/other/jpeg2000/libjasper/base/jas_init.c create mode 100644 converter/other/jpeg2000/libjasper/base/jas_malloc.c create mode 100644 converter/other/jpeg2000/libjasper/base/jas_seq.c create mode 100644 converter/other/jpeg2000/libjasper/base/jas_stream.c create mode 100644 converter/other/jpeg2000/libjasper/base/jas_string.c create mode 100644 converter/other/jpeg2000/libjasper/base/jas_tvp.c create mode 100644 converter/other/jpeg2000/libjasper/base/jas_version.c create mode 100644 converter/other/jpeg2000/libjasper/base/partlist create mode 100644 converter/other/jpeg2000/libjasper/include/jasper/jas_debug.h create mode 100644 converter/other/jpeg2000/libjasper/include/jasper/jas_fix.h create mode 100644 converter/other/jpeg2000/libjasper/include/jasper/jas_getopt.h create mode 100644 converter/other/jpeg2000/libjasper/include/jasper/jas_image.h create mode 100644 converter/other/jpeg2000/libjasper/include/jasper/jas_init.h create mode 100644 converter/other/jpeg2000/libjasper/include/jasper/jas_malloc.h create mode 100644 converter/other/jpeg2000/libjasper/include/jasper/jas_math.h create mode 100644 converter/other/jpeg2000/libjasper/include/jasper/jas_seq.h create mode 100644 converter/other/jpeg2000/libjasper/include/jasper/jas_stream.h create mode 100644 converter/other/jpeg2000/libjasper/include/jasper/jas_string.h create mode 100644 converter/other/jpeg2000/libjasper/include/jasper/jas_tvp.h create mode 100644 converter/other/jpeg2000/libjasper/include/jasper/jas_types.h create mode 100644 converter/other/jpeg2000/libjasper/include/jasper/jas_types.h.orig create mode 100644 converter/other/jpeg2000/libjasper/include/jasper/jas_version.h create mode 100644 converter/other/jpeg2000/libjasper/include/jasper/jasper.h create mode 100644 converter/other/jpeg2000/libjasper/jp2/Makefile create mode 100644 converter/other/jpeg2000/libjasper/jp2/jp2_cod.c create mode 100644 converter/other/jpeg2000/libjasper/jp2/jp2_cod.h create mode 100644 converter/other/jpeg2000/libjasper/jp2/jp2_dec.c create mode 100644 converter/other/jpeg2000/libjasper/jp2/jp2_dec.h create mode 100644 converter/other/jpeg2000/libjasper/jp2/jp2_enc.c create mode 100644 converter/other/jpeg2000/libjasper/jp2/partlist create mode 100644 converter/other/jpeg2000/libjasper/jpc/Makefile create mode 100644 converter/other/jpeg2000/libjasper/jpc/jpc_bs.c create mode 100644 converter/other/jpeg2000/libjasper/jpc/jpc_bs.h create mode 100644 converter/other/jpeg2000/libjasper/jpc/jpc_cod.h create mode 100644 converter/other/jpeg2000/libjasper/jpc/jpc_cs.c create mode 100644 converter/other/jpeg2000/libjasper/jpc/jpc_cs.h create mode 100644 converter/other/jpeg2000/libjasper/jpc/jpc_dec.c create mode 100644 converter/other/jpeg2000/libjasper/jpc/jpc_dec.h create mode 100644 converter/other/jpeg2000/libjasper/jpc/jpc_enc.c create mode 100644 converter/other/jpeg2000/libjasper/jpc/jpc_enc.h create mode 100644 converter/other/jpeg2000/libjasper/jpc/jpc_fix.h create mode 100644 converter/other/jpeg2000/libjasper/jpc/jpc_flt.h create mode 100644 converter/other/jpeg2000/libjasper/jpc/jpc_math.c create mode 100644 converter/other/jpeg2000/libjasper/jpc/jpc_math.h create mode 100644 converter/other/jpeg2000/libjasper/jpc/jpc_mct.c create mode 100644 converter/other/jpeg2000/libjasper/jpc/jpc_mct.h create mode 100644 converter/other/jpeg2000/libjasper/jpc/jpc_mqcod.c create mode 100644 converter/other/jpeg2000/libjasper/jpc/jpc_mqcod.h create mode 100644 converter/other/jpeg2000/libjasper/jpc/jpc_mqdec.c create mode 100644 converter/other/jpeg2000/libjasper/jpc/jpc_mqdec.h create mode 100644 converter/other/jpeg2000/libjasper/jpc/jpc_mqenc.c create mode 100644 converter/other/jpeg2000/libjasper/jpc/jpc_mqenc.h create mode 100644 converter/other/jpeg2000/libjasper/jpc/jpc_qmfb.c create mode 100644 converter/other/jpeg2000/libjasper/jpc/jpc_qmfb.h create mode 100644 converter/other/jpeg2000/libjasper/jpc/jpc_t1cod.c create mode 100644 converter/other/jpeg2000/libjasper/jpc/jpc_t1cod.h create mode 100644 converter/other/jpeg2000/libjasper/jpc/jpc_t1dec.c create mode 100644 converter/other/jpeg2000/libjasper/jpc/jpc_t1dec.h create mode 100644 converter/other/jpeg2000/libjasper/jpc/jpc_t1enc.c create mode 100644 converter/other/jpeg2000/libjasper/jpc/jpc_t1enc.h create mode 100644 converter/other/jpeg2000/libjasper/jpc/jpc_t2cod.c create mode 100644 converter/other/jpeg2000/libjasper/jpc/jpc_t2cod.h create mode 100644 converter/other/jpeg2000/libjasper/jpc/jpc_t2dec.c create mode 100644 converter/other/jpeg2000/libjasper/jpc/jpc_t2dec.h create mode 100644 converter/other/jpeg2000/libjasper/jpc/jpc_t2enc.c create mode 100644 converter/other/jpeg2000/libjasper/jpc/jpc_t2enc.h create mode 100644 converter/other/jpeg2000/libjasper/jpc/jpc_tagtree.c create mode 100644 converter/other/jpeg2000/libjasper/jpc/jpc_tagtree.h create mode 100644 converter/other/jpeg2000/libjasper/jpc/jpc_tsfb.c create mode 100644 converter/other/jpeg2000/libjasper/jpc/jpc_tsfb.h create mode 100644 converter/other/jpeg2000/libjasper/jpc/jpc_util.c create mode 100644 converter/other/jpeg2000/libjasper/jpc/jpc_util.h create mode 100644 converter/other/jpeg2000/libjasper/jpc/partlist create mode 100644 converter/other/jpeg2000/libjasper/partlist create mode 100644 converter/other/jpeg2000/libjasper_compat.h create mode 100644 converter/other/jpeg2000/pamtojpeg2k.c create mode 100644 converter/other/jpegdatasource.c create mode 100644 converter/other/jpegdatasource.h create mode 100644 converter/other/jpegtopnm.c create mode 100644 converter/other/pamrgbatopng.c create mode 100644 converter/other/pamtodjvurle.c create mode 100644 converter/other/pamtofits.c create mode 100644 converter/other/pamtohdiff.c create mode 100644 converter/other/pamtohtmltbl.c create mode 100644 converter/other/pamtopfm.c create mode 100644 converter/other/pamtopnm.c create mode 100644 converter/other/pamtosvg/Makefile create mode 100644 converter/other/pamtosvg/README create mode 100644 converter/other/pamtosvg/autotrace.c create mode 100644 converter/other/pamtosvg/autotrace.h create mode 100644 converter/other/pamtosvg/bitmap.c create mode 100644 converter/other/pamtosvg/bitmap.h create mode 100644 converter/other/pamtosvg/curve.c create mode 100644 converter/other/pamtosvg/curve.h create mode 100644 converter/other/pamtosvg/epsilon-equal.c create mode 100644 converter/other/pamtosvg/epsilon-equal.h create mode 100644 converter/other/pamtosvg/exception.c create mode 100644 converter/other/pamtosvg/exception.h create mode 100644 converter/other/pamtosvg/fit.c create mode 100644 converter/other/pamtosvg/fit.h create mode 100644 converter/other/pamtosvg/image-header.h create mode 100644 converter/other/pamtosvg/image-proc.c create mode 100644 converter/other/pamtosvg/image-proc.h create mode 100644 converter/other/pamtosvg/logreport.c create mode 100644 converter/other/pamtosvg/logreport.h create mode 100644 converter/other/pamtosvg/message.h create mode 100644 converter/other/pamtosvg/output-svg.c create mode 100644 converter/other/pamtosvg/output-svg.h create mode 100644 converter/other/pamtosvg/pamtosvg.c create mode 100644 converter/other/pamtosvg/pamtosvg.test create mode 100644 converter/other/pamtosvg/point.h create mode 100644 converter/other/pamtosvg/pxl-outline.c create mode 100644 converter/other/pamtosvg/pxl-outline.h create mode 100644 converter/other/pamtosvg/spline.c create mode 100644 converter/other/pamtosvg/spline.h create mode 100644 converter/other/pamtosvg/testgrid.svg create mode 100644 converter/other/pamtosvg/testline.svg create mode 100644 converter/other/pamtosvg/thin-image.c create mode 100644 converter/other/pamtosvg/thin-image.h create mode 100644 converter/other/pamtosvg/vector.c create mode 100644 converter/other/pamtosvg/vector.h create mode 100644 converter/other/pamtotga.c create mode 100644 converter/other/pamtotiff.c create mode 100644 converter/other/pamtouil.c create mode 100644 converter/other/pamtoxvmini.c create mode 100644 converter/other/pbmtopgm.c create mode 100644 converter/other/pclxl.h create mode 100644 converter/other/pfmtopam.c create mode 100644 converter/other/pgmtopbm.c create mode 100644 converter/other/pgmtoppm.c create mode 100644 converter/other/pm_tiff.h create mode 100644 converter/other/pngtopnm.c create mode 100644 converter/other/pngtxt.c create mode 100644 converter/other/pngtxt.h create mode 100644 converter/other/pnmtoddif.c create mode 100644 converter/other/pnmtojpeg.c create mode 100644 converter/other/pnmtopalm/LICENSE create mode 100644 converter/other/pnmtopalm/Makefile create mode 100644 converter/other/pnmtopalm/README create mode 100644 converter/other/pnmtopalm/gen_palm_colormap.c create mode 100644 converter/other/pnmtopalm/palm.h create mode 100644 converter/other/pnmtopalm/palmcolor8.map create mode 100644 converter/other/pnmtopalm/palmcolormap.c create mode 100644 converter/other/pnmtopalm/palmgray1.map create mode 100644 converter/other/pnmtopalm/palmgray2.map create mode 100644 converter/other/pnmtopalm/palmgray4.map create mode 100644 converter/other/pnmtopalm/palmtopnm.c create mode 100644 converter/other/pnmtopalm/pnmtopalm.c create mode 100644 converter/other/pnmtopclxl.c create mode 100755 converter/other/pnmtoplainpnm create mode 100644 converter/other/pnmtopng.README create mode 100644 converter/other/pnmtopng.c create mode 100644 converter/other/pnmtops.c create mode 100644 converter/other/pnmtorast.c create mode 100644 converter/other/pnmtorle.c create mode 100644 converter/other/pnmtosgi.c create mode 100644 converter/other/pnmtosir.c create mode 100644 converter/other/pnmtotiffcmyk.c create mode 100644 converter/other/pnmtoxwd.c create mode 100644 converter/other/ppmtopgm.c create mode 100644 converter/other/pstopnm.c create mode 100755 converter/other/pstopnm.csh create mode 100644 converter/other/rast.c create mode 100644 converter/other/rast.h create mode 100644 converter/other/rasttopnm.c create mode 100644 converter/other/rla.h create mode 100644 converter/other/rlatopam.c create mode 100644 converter/other/rletopnm.c create mode 100644 converter/other/sgi.h create mode 100644 converter/other/sgitopnm.c create mode 100644 converter/other/sirtopnm.c create mode 100644 converter/other/svgtopam.c create mode 100644 converter/other/tiff.c create mode 100644 converter/other/tifftopnm.c create mode 100644 converter/other/x10wd.h create mode 100644 converter/other/x11wd.h create mode 100644 converter/other/xwdtopnm.c create mode 100644 converter/other/zeisstopnm.c create mode 100644 converter/pbm/Makefile create mode 100644 converter/pbm/atktopbm.c create mode 100644 converter/pbm/brushtopbm.c create mode 100644 converter/pbm/cmuwm.h create mode 100644 converter/pbm/cmuwmtopbm.c create mode 100644 converter/pbm/ddbugtopbm.c create mode 100644 converter/pbm/escp2topbm.c create mode 100644 converter/pbm/g3.h create mode 100644 converter/pbm/g3topbm.c create mode 100644 converter/pbm/icontopbm.c create mode 100644 converter/pbm/macp.h create mode 100644 converter/pbm/macptopbm.c create mode 100644 converter/pbm/mdaspec.txt create mode 100644 converter/pbm/mdatopbm.c create mode 100644 converter/pbm/mgr.h create mode 100644 converter/pbm/mgrtopbm.c create mode 100644 converter/pbm/mrftopbm.c create mode 100644 converter/pbm/pbmto10x.c create mode 100644 converter/pbm/pbmto4425.c create mode 100644 converter/pbm/pbmtoascii.c create mode 100644 converter/pbm/pbmtoatk.c create mode 100644 converter/pbm/pbmtobbnbg.c create mode 100644 converter/pbm/pbmtocmuwm.c create mode 100644 converter/pbm/pbmtodjvurle.c create mode 100644 converter/pbm/pbmtoepsi.c create mode 100644 converter/pbm/pbmtoepson.c create mode 100644 converter/pbm/pbmtoescp2.c create mode 100644 converter/pbm/pbmtog3.c create mode 100644 converter/pbm/pbmtog3.test create mode 100644 converter/pbm/pbmtogem.c create mode 100644 converter/pbm/pbmtogo.c create mode 100644 converter/pbm/pbmtoibm23xx.c create mode 100644 converter/pbm/pbmtoicon.c create mode 100644 converter/pbm/pbmtolj.c create mode 100644 converter/pbm/pbmtoln03.c create mode 100644 converter/pbm/pbmtolps.c create mode 100644 converter/pbm/pbmtomacp.c create mode 100644 converter/pbm/pbmtomatrixorbital.c create mode 100644 converter/pbm/pbmtomda.c create mode 100644 converter/pbm/pbmtomgr.c create mode 100644 converter/pbm/pbmtomrf.c create mode 100644 converter/pbm/pbmtonokia.c create mode 100644 converter/pbm/pbmtopi3.c create mode 100644 converter/pbm/pbmtopk.c create mode 100644 converter/pbm/pbmtoplot.c create mode 100644 converter/pbm/pbmtoppa/CREDITS create mode 100644 converter/pbm/pbmtoppa/INSTALL-MORE create mode 100644 converter/pbm/pbmtoppa/LICENSE create mode 100644 converter/pbm/pbmtoppa/Makefile create mode 100644 converter/pbm/pbmtoppa/README.Netpbm create mode 100644 converter/pbm/pbmtoppa/README.REDHAT create mode 100644 converter/pbm/pbmtoppa/cutswath.c create mode 100644 converter/pbm/pbmtoppa/cutswath.h create mode 100644 converter/pbm/pbmtoppa/defaults.h create mode 100644 converter/pbm/pbmtoppa/pbm.c create mode 100644 converter/pbm/pbmtoppa/pbmtoppa.c create mode 100644 converter/pbm/pbmtoppa/pbmtoppa.conf.hp1000 create mode 100644 converter/pbm/pbmtoppa/pbmtoppa.conf.hp720 create mode 100644 converter/pbm/pbmtoppa/pbmtoppa.conf.hp820 create mode 100644 converter/pbm/pbmtoppa/ppa.c create mode 100644 converter/pbm/pbmtoppa/ppa.h create mode 100644 converter/pbm/pbmtoppa/ppapbm.h create mode 100644 converter/pbm/pbmtopsg3.c create mode 100644 converter/pbm/pbmtoptx.c create mode 100644 converter/pbm/pbmtowbmp.c create mode 100644 converter/pbm/pbmtox10bm.c create mode 100644 converter/pbm/pbmtoxbm.c create mode 100644 converter/pbm/pbmtoybm.c create mode 100644 converter/pbm/pbmtozinc.c create mode 100644 converter/pbm/pi3topbm.c create mode 100644 converter/pbm/pktopbm.c create mode 100644 converter/pbm/thinkjettopbm.c create mode 100644 converter/pbm/thinkjettopbm.l create mode 100644 converter/pbm/wbmptopbm.c create mode 100644 converter/pbm/xbmtopbm.c create mode 100644 converter/pbm/ybmtopbm.c create mode 100644 converter/pgm/Makefile create mode 100644 converter/pgm/asciitopgm.c create mode 100644 converter/pgm/bioradtopgm.c create mode 100644 converter/pgm/fstopgm.c create mode 100644 converter/pgm/hipstopgm.c create mode 100644 converter/pgm/lispmtopgm.c create mode 100644 converter/pgm/pgmtofs.c create mode 100644 converter/pgm/pgmtolispm.c create mode 100644 converter/pgm/pgmtopgm.c create mode 100644 converter/pgm/psidtopgm.c create mode 100644 converter/pgm/rawtopgm.c create mode 100644 converter/pgm/sbigtopgm.c create mode 100644 converter/pgm/spottopgm.c create mode 100644 converter/ppm/411toppm.c create mode 100644 converter/ppm/Makefile create mode 100644 converter/ppm/autocad.h create mode 100644 converter/ppm/eyuvtoppm.c create mode 100644 converter/ppm/gouldtoppm.c create mode 100644 converter/ppm/hpcdtoppm/Makefile create mode 100644 converter/ppm/hpcdtoppm/README create mode 100755 converter/ppm/hpcdtoppm/hpcdtoppm create mode 100755 converter/ppm/hpcdtoppm/pcdovtoppm create mode 100644 converter/ppm/ilbm.h create mode 100644 converter/ppm/ilbmtoppm.c create mode 100644 converter/ppm/imgtoppm.c create mode 100644 converter/ppm/leaftoppm.c create mode 100644 converter/ppm/mitsu.h create mode 100644 converter/ppm/mtvtoppm.c create mode 100644 converter/ppm/neotoppm.c create mode 100644 converter/ppm/pc1toppm.c create mode 100644 converter/ppm/pcxstd.ppm create mode 100644 converter/ppm/pcxtoppm.c create mode 100644 converter/ppm/pi1toppm.c create mode 100644 converter/ppm/picttoppm.c create mode 100644 converter/ppm/pjtoppm.c create mode 100644 converter/ppm/ppmtoacad.c create mode 100644 converter/ppm/ppmtoarbtxt.c create mode 100644 converter/ppm/ppmtobmp.c create mode 100644 converter/ppm/ppmtoeyuv.c create mode 100644 converter/ppm/ppmtogif.c create mode 100644 converter/ppm/ppmtoicr.c create mode 100644 converter/ppm/ppmtoilbm.c create mode 100644 converter/ppm/ppmtoleaf.c create mode 100644 converter/ppm/ppmtolj.c create mode 100644 converter/ppm/ppmtomitsu.c create mode 100644 converter/ppm/ppmtompeg/BUGS create mode 100644 converter/ppm/ppmtompeg/CHANGES create mode 100644 converter/ppm/ppmtompeg/COPYRIGHT create mode 100644 converter/ppm/ppmtompeg/HISTORY create mode 100644 converter/ppm/ppmtompeg/LOGIC create mode 100644 converter/ppm/ppmtompeg/Makefile create mode 100644 converter/ppm/ppmtompeg/bframe.c create mode 100644 converter/ppm/ppmtompeg/bitio.c create mode 100644 converter/ppm/ppmtompeg/block.c create mode 100644 converter/ppm/ppmtompeg/bsearch.c create mode 100644 converter/ppm/ppmtompeg/combine.c create mode 100644 converter/ppm/ppmtompeg/docs/EXTENSIONS create mode 100644 converter/ppm/ppmtompeg/docs/INPUT.FORMAT create mode 100644 converter/ppm/ppmtompeg/docs/parallel.param create mode 100644 converter/ppm/ppmtompeg/docs/param-summary create mode 100644 converter/ppm/ppmtompeg/docs/template.param create mode 100644 converter/ppm/ppmtompeg/docs/users-guide.ps create mode 100644 converter/ppm/ppmtompeg/examples/basicspeed.param create mode 100644 converter/ppm/ppmtompeg/examples/decoded.test create mode 100644 converter/ppm/ppmtompeg/examples/decoded2.test create mode 100644 converter/ppm/ppmtompeg/examples/decorig.param create mode 100644 converter/ppm/ppmtompeg/examples/default.param create mode 100644 converter/ppm/ppmtompeg/examples/fastspeed.param create mode 100644 converter/ppm/ppmtompeg/examples/foobar.param create mode 100644 converter/ppm/ppmtompeg/examples/frame.test create mode 100644 converter/ppm/ppmtompeg/examples/gop.combine create mode 100644 converter/ppm/ppmtompeg/examples/gop.test create mode 100644 converter/ppm/ppmtompeg/examples/gop1.param create mode 100644 converter/ppm/ppmtompeg/examples/hello.param create mode 100644 converter/ppm/ppmtompeg/examples/i.test create mode 100644 converter/ppm/ppmtompeg/examples/ispeed.jpeg.param create mode 100644 converter/ppm/ppmtompeg/examples/ispeed.param create mode 100644 converter/ppm/ppmtompeg/examples/jpeg.test create mode 100644 converter/ppm/ppmtompeg/examples/jpeg19.param create mode 100644 converter/ppm/ppmtompeg/examples/jpegout19.param create mode 100644 converter/ppm/ppmtompeg/examples/localdisk.param create mode 100644 converter/ppm/ppmtompeg/examples/localremote.test create mode 100644 converter/ppm/ppmtompeg/examples/luxo.param create mode 100644 converter/ppm/ppmtompeg/examples/luxo18.param create mode 100644 converter/ppm/ppmtompeg/examples/luxo19.5.param create mode 100644 converter/ppm/ppmtompeg/examples/luxo19.param create mode 100644 converter/ppm/ppmtompeg/examples/luxo2.param create mode 100644 converter/ppm/ppmtompeg/examples/luxo48.param create mode 100644 converter/ppm/ppmtompeg/examples/luxo49.param create mode 100644 converter/ppm/ppmtompeg/examples/luxo50.param create mode 100644 converter/ppm/ppmtompeg/examples/luxo52.5.param create mode 100644 converter/ppm/ppmtompeg/examples/luxo52.param create mode 100644 converter/ppm/ppmtompeg/examples/luxo53.param create mode 100644 converter/ppm/ppmtompeg/examples/luxobug.param create mode 100644 converter/ppm/ppmtompeg/examples/luxoskip.param create mode 100644 converter/ppm/ppmtompeg/examples/med.param create mode 100644 converter/ppm/ppmtompeg/examples/med18.param create mode 100644 converter/ppm/ppmtompeg/examples/medspeed.param create mode 100644 converter/ppm/ppmtompeg/examples/nametest.param create mode 100644 converter/ppm/ppmtompeg/examples/nosearch.param create mode 100644 converter/ppm/ppmtompeg/examples/par3.param create mode 100644 converter/ppm/ppmtompeg/examples/par4.param create mode 100644 converter/ppm/ppmtompeg/examples/par5.param create mode 100644 converter/ppm/ppmtompeg/examples/parallel.2 create mode 100644 converter/ppm/ppmtompeg/examples/parallel.param create mode 100644 converter/ppm/ppmtompeg/examples/parallel.test create mode 100644 converter/ppm/ppmtompeg/examples/param.template create mode 100644 converter/ppm/ppmtompeg/examples/payam.param create mode 100644 converter/ppm/ppmtompeg/examples/payam18.param create mode 100644 converter/ppm/ppmtompeg/examples/pnm.param create mode 100644 converter/ppm/ppmtompeg/examples/ppm.param create mode 100644 converter/ppm/ppmtompeg/examples/prof.b.param create mode 100644 converter/ppm/ppmtompeg/examples/prof.bhalf.param create mode 100644 converter/ppm/ppmtompeg/examples/prof.param create mode 100644 converter/ppm/ppmtompeg/examples/prof.ss.param create mode 100644 converter/ppm/ppmtompeg/examples/prof2.param create mode 100644 converter/ppm/ppmtompeg/examples/prof3.param create mode 100644 converter/ppm/ppmtompeg/examples/prof4.param create mode 100644 converter/ppm/ppmtompeg/examples/remote.test create mode 100644 converter/ppm/ppmtompeg/examples/search1.param create mode 100644 converter/ppm/ppmtompeg/examples/search10.param create mode 100644 converter/ppm/ppmtompeg/examples/search11.param create mode 100644 converter/ppm/ppmtompeg/examples/search12.param create mode 100644 converter/ppm/ppmtompeg/examples/search13.param create mode 100644 converter/ppm/ppmtompeg/examples/search14.param create mode 100644 converter/ppm/ppmtompeg/examples/search15.param create mode 100644 converter/ppm/ppmtompeg/examples/search16.param create mode 100644 converter/ppm/ppmtompeg/examples/search17.param create mode 100644 converter/ppm/ppmtompeg/examples/search18.param create mode 100644 converter/ppm/ppmtompeg/examples/search19.5.param create mode 100644 converter/ppm/ppmtompeg/examples/search19.param create mode 100644 converter/ppm/ppmtompeg/examples/search2.param create mode 100644 converter/ppm/ppmtompeg/examples/search20.param create mode 100644 converter/ppm/ppmtompeg/examples/search21.param create mode 100644 converter/ppm/ppmtompeg/examples/search22.param create mode 100644 converter/ppm/ppmtompeg/examples/search23.param create mode 100644 converter/ppm/ppmtompeg/examples/search24.param create mode 100644 converter/ppm/ppmtompeg/examples/search25.param create mode 100644 converter/ppm/ppmtompeg/examples/search26.param create mode 100644 converter/ppm/ppmtompeg/examples/search27.param create mode 100644 converter/ppm/ppmtompeg/examples/search28.param create mode 100644 converter/ppm/ppmtompeg/examples/search29.param create mode 100644 converter/ppm/ppmtompeg/examples/search3.param create mode 100644 converter/ppm/ppmtompeg/examples/search30.param create mode 100644 converter/ppm/ppmtompeg/examples/search31.param create mode 100644 converter/ppm/ppmtompeg/examples/search32.param create mode 100644 converter/ppm/ppmtompeg/examples/search33.param create mode 100644 converter/ppm/ppmtompeg/examples/search34.param create mode 100644 converter/ppm/ppmtompeg/examples/search35.param create mode 100644 converter/ppm/ppmtompeg/examples/search36.param create mode 100644 converter/ppm/ppmtompeg/examples/search37.param create mode 100644 converter/ppm/ppmtompeg/examples/search38.param create mode 100644 converter/ppm/ppmtompeg/examples/search39.param create mode 100644 converter/ppm/ppmtompeg/examples/search4.param create mode 100644 converter/ppm/ppmtompeg/examples/search40.param create mode 100644 converter/ppm/ppmtompeg/examples/search41.param create mode 100644 converter/ppm/ppmtompeg/examples/search42.param create mode 100644 converter/ppm/ppmtompeg/examples/search43.param create mode 100644 converter/ppm/ppmtompeg/examples/search44.param create mode 100644 converter/ppm/ppmtompeg/examples/search45.param create mode 100644 converter/ppm/ppmtompeg/examples/search46.param create mode 100644 converter/ppm/ppmtompeg/examples/search47.param create mode 100644 converter/ppm/ppmtompeg/examples/search48.param create mode 100644 converter/ppm/ppmtompeg/examples/search49.param create mode 100644 converter/ppm/ppmtompeg/examples/search5.param create mode 100644 converter/ppm/ppmtompeg/examples/search50.param create mode 100644 converter/ppm/ppmtompeg/examples/search51.param create mode 100644 converter/ppm/ppmtompeg/examples/search52.5.param create mode 100644 converter/ppm/ppmtompeg/examples/search52.param create mode 100644 converter/ppm/ppmtompeg/examples/search53.param create mode 100644 converter/ppm/ppmtompeg/examples/search6.param create mode 100644 converter/ppm/ppmtompeg/examples/search7.param create mode 100644 converter/ppm/ppmtompeg/examples/search8.param create mode 100644 converter/ppm/ppmtompeg/examples/search9.param create mode 100644 converter/ppm/ppmtompeg/examples/seq.param create mode 100644 converter/ppm/ppmtompeg/examples/sequoia.param create mode 100644 converter/ppm/ppmtompeg/examples/sequoia19.param create mode 100644 converter/ppm/ppmtompeg/examples/sequoia2.param create mode 100644 converter/ppm/ppmtompeg/examples/simple.param create mode 100644 converter/ppm/ppmtompeg/examples/slice.param create mode 100644 converter/ppm/ppmtompeg/examples/slimed.param create mode 100644 converter/ppm/ppmtompeg/examples/slowspeed.param create mode 100644 converter/ppm/ppmtompeg/examples/stanford.param create mode 100644 converter/ppm/ppmtompeg/examples/subtest.param create mode 100644 converter/ppm/ppmtompeg/examples/temp.param create mode 100644 converter/ppm/ppmtompeg/examples/template.param create mode 100644 converter/ppm/ppmtompeg/examples/tennis.param create mode 100644 converter/ppm/ppmtompeg/examples/tennis18.param create mode 100644 converter/ppm/ppmtompeg/examples/tennis19.5.param create mode 100644 converter/ppm/ppmtompeg/examples/tennis19.param create mode 100644 converter/ppm/ppmtompeg/examples/tennis48.param create mode 100644 converter/ppm/ppmtompeg/examples/tennis49.param create mode 100644 converter/ppm/ppmtompeg/examples/tennis50.param create mode 100644 converter/ppm/ppmtompeg/examples/tennis52.5.param create mode 100644 converter/ppm/ppmtompeg/examples/tennis52.param create mode 100644 converter/ppm/ppmtompeg/examples/tennis53.param create mode 100644 converter/ppm/ppmtompeg/examples/tennisbug.param create mode 100644 converter/ppm/ppmtompeg/examples/testp.param create mode 100644 converter/ppm/ppmtompeg/examples/walk.param create mode 100644 converter/ppm/ppmtompeg/examples/walk1.param create mode 100644 converter/ppm/ppmtompeg/examples/walk18.param create mode 100644 converter/ppm/ppmtompeg/examples/walk19.5.param create mode 100644 converter/ppm/ppmtompeg/examples/walk19.param create mode 100644 converter/ppm/ppmtompeg/examples/walk2.param create mode 100644 converter/ppm/ppmtompeg/examples/walk3.param create mode 100644 converter/ppm/ppmtompeg/examples/walk4.param create mode 100644 converter/ppm/ppmtompeg/examples/walk48.param create mode 100644 converter/ppm/ppmtompeg/examples/walk49.param create mode 100644 converter/ppm/ppmtompeg/examples/walk5.param create mode 100644 converter/ppm/ppmtompeg/examples/walk50.param create mode 100644 converter/ppm/ppmtompeg/examples/walk52.5.param create mode 100644 converter/ppm/ppmtompeg/examples/walk52.param create mode 100644 converter/ppm/ppmtompeg/examples/walk53.param create mode 100644 converter/ppm/ppmtompeg/examples/walk93.param create mode 100644 converter/ppm/ppmtompeg/file.c create mode 100644 converter/ppm/ppmtompeg/frame.c create mode 100644 converter/ppm/ppmtompeg/frametype.c create mode 100644 converter/ppm/ppmtompeg/fsize.c create mode 100644 converter/ppm/ppmtompeg/gethostname.c create mode 100644 converter/ppm/ppmtompeg/gethostname.h create mode 100644 converter/ppm/ppmtompeg/headers/all.h create mode 100644 converter/ppm/ppmtompeg/headers/ansi.h create mode 100644 converter/ppm/ppmtompeg/headers/bitio.h create mode 100644 converter/ppm/ppmtompeg/headers/block.h create mode 100644 converter/ppm/ppmtompeg/headers/byteorder.h create mode 100644 converter/ppm/ppmtompeg/headers/combine.h create mode 100644 converter/ppm/ppmtompeg/headers/dct.h create mode 100644 converter/ppm/ppmtompeg/headers/frame.h create mode 100644 converter/ppm/ppmtompeg/headers/frames.h create mode 100644 converter/ppm/ppmtompeg/headers/frametype.h create mode 100644 converter/ppm/ppmtompeg/headers/fsize.h create mode 100644 converter/ppm/ppmtompeg/headers/general.h create mode 100644 converter/ppm/ppmtompeg/headers/huff.h create mode 100644 converter/ppm/ppmtompeg/headers/input.h create mode 100644 converter/ppm/ppmtompeg/headers/jpeg.h create mode 100644 converter/ppm/ppmtompeg/headers/mheaders.h create mode 100644 converter/ppm/ppmtompeg/headers/motion_search.h create mode 100644 converter/ppm/ppmtompeg/headers/mpeg.h create mode 100644 converter/ppm/ppmtompeg/headers/mproto.h create mode 100644 converter/ppm/ppmtompeg/headers/mtypes.h create mode 100644 converter/ppm/ppmtompeg/headers/opts.h create mode 100644 converter/ppm/ppmtompeg/headers/parallel.h create mode 100644 converter/ppm/ppmtompeg/headers/param.h create mode 100644 converter/ppm/ppmtompeg/headers/postdct.h create mode 100644 converter/ppm/ppmtompeg/headers/prototypes.h create mode 100644 converter/ppm/ppmtompeg/headers/psocket.h create mode 100644 converter/ppm/ppmtompeg/headers/rate.h create mode 100644 converter/ppm/ppmtompeg/headers/readframe.h create mode 100644 converter/ppm/ppmtompeg/headers/rgbtoycc.h create mode 100644 converter/ppm/ppmtompeg/headers/specifics.h create mode 100644 converter/ppm/ppmtompeg/huff.c create mode 100644 converter/ppm/ppmtompeg/huff.h create mode 100644 converter/ppm/ppmtompeg/huff.table create mode 100644 converter/ppm/ppmtompeg/iframe.c create mode 100644 converter/ppm/ppmtompeg/input.c create mode 100644 converter/ppm/ppmtompeg/jpeg.c create mode 100644 converter/ppm/ppmtompeg/jrevdct.c create mode 100644 converter/ppm/ppmtompeg/memory.c create mode 100644 converter/ppm/ppmtompeg/mfwddct.c create mode 100644 converter/ppm/ppmtompeg/mheaders.c create mode 100644 converter/ppm/ppmtompeg/moutput.c create mode 100644 converter/ppm/ppmtompeg/mpeg.c create mode 100644 converter/ppm/ppmtompeg/mquant.c create mode 100644 converter/ppm/ppmtompeg/nojpeg.c create mode 100644 converter/ppm/ppmtompeg/noparallel.c create mode 100644 converter/ppm/ppmtompeg/opts.c create mode 100644 converter/ppm/ppmtompeg/parallel.c create mode 100644 converter/ppm/ppmtompeg/param.c create mode 100644 converter/ppm/ppmtompeg/parse_huff.pl create mode 100644 converter/ppm/ppmtompeg/pframe.c create mode 100644 converter/ppm/ppmtompeg/postdct.c create mode 100644 converter/ppm/ppmtompeg/ppmtompeg.c create mode 100644 converter/ppm/ppmtompeg/psearch.c create mode 100644 converter/ppm/ppmtompeg/psocket.c create mode 100644 converter/ppm/ppmtompeg/qtest.c create mode 100644 converter/ppm/ppmtompeg/rate.c create mode 100644 converter/ppm/ppmtompeg/readframe.c create mode 100644 converter/ppm/ppmtompeg/rgbtoycc.c create mode 100644 converter/ppm/ppmtompeg/specifics.c create mode 100644 converter/ppm/ppmtompeg/subsample.c create mode 100644 converter/ppm/ppmtompeg/tst/README create mode 100644 converter/ppm/ppmtompeg/tst/gop.param create mode 100644 converter/ppm/ppmtompeg/tst/par3.param create mode 100644 converter/ppm/ppmtompeg/tst/short.param create mode 100755 converter/ppm/ppmtompeg/tst/test_all create mode 100644 converter/ppm/ppmtompeg/tst/ts.mpg create mode 100644 converter/ppm/ppmtompeg/tst/ts.param create mode 100644 converter/ppm/ppmtompeg/tst/ts.stat create mode 100644 converter/ppm/ppmtompeg/tst/ts/stennis.30.jpg create mode 100644 converter/ppm/ppmtompeg/tst/ts/stennis.31.jpg create mode 100644 converter/ppm/ppmtompeg/tst/ts/stennis.32.jpg create mode 100644 converter/ppm/ppmtompeg/tst/ts/stennis.33.jpg create mode 100644 converter/ppm/ppmtompeg/tst/ts/stennis.34.jpg create mode 100644 converter/ppm/ppmtompeg/tst/ts/stennis.35.jpg create mode 100644 converter/ppm/ppmtompeg/tst/ts/stennis.36.jpg create mode 100644 converter/ppm/ppmtompeg/tst/ts/stennis.37.jpg create mode 100644 converter/ppm/ppmtompeg/tst/ts/stennis.38.jpg create mode 100644 converter/ppm/ppmtompeg/tst/ts/stennis.39.jpg create mode 100644 converter/ppm/ppmtompeg/tst/ts2.param create mode 100644 converter/ppm/ppmtompeg/tst/ts2.stat create mode 100644 converter/ppm/ppmtompeg/tst/ts3.param create mode 100644 converter/ppm/ppmtompeg/tst/ts4.param create mode 100644 converter/ppm/ppmtompeg/tst/tsd.param create mode 100644 converter/ppm/ppmtompeg/tst/tsd.stat create mode 100644 converter/ppm/ppmtompeg/tst/tstl.param create mode 100644 converter/ppm/ppmtoneo.c create mode 100644 converter/ppm/ppmtopcx.c create mode 100644 converter/ppm/ppmtopi1.c create mode 100644 converter/ppm/ppmtopict.c create mode 100644 converter/ppm/ppmtopj.c create mode 100644 converter/ppm/ppmtopjxl.c create mode 100644 converter/ppm/ppmtoppm.c create mode 100644 converter/ppm/ppmtopuzz.c create mode 100644 converter/ppm/ppmtorgb3.c create mode 100644 converter/ppm/ppmtosixel.c create mode 100644 converter/ppm/ppmtoterm.c create mode 100644 converter/ppm/ppmtowinicon.c create mode 100644 converter/ppm/ppmtoxpm.c create mode 100644 converter/ppm/ppmtoyuv.c create mode 100644 converter/ppm/ppmtoyuvsplit.c create mode 100644 converter/ppm/qrttoppm.c create mode 100644 converter/ppm/rawtoppm.c create mode 100644 converter/ppm/rgb3toppm.c create mode 100644 converter/ppm/sldtoppm.c create mode 100644 converter/ppm/spctoppm.c create mode 100644 converter/ppm/sputoppm.c create mode 100644 converter/ppm/tgatoppm.c create mode 100644 converter/ppm/vidtoppm.c create mode 100644 converter/ppm/winico.h create mode 100644 converter/ppm/winico.html create mode 100644 converter/ppm/winicontoppm.c create mode 100644 converter/ppm/xim.h create mode 100644 converter/ppm/ximtoppm.c create mode 100644 converter/ppm/xpmtoppm.README create mode 100644 converter/ppm/xpmtoppm.c create mode 100644 converter/ppm/xvminitoppm.c create mode 100644 converter/ppm/yuvsplittoppm.c create mode 100644 converter/ppm/yuvtoppm.c create mode 100644 converter/tga.h create mode 100644 doc/COPYRIGHT.PATENT create mode 100644 doc/GPL_LICENSE.txt create mode 100644 doc/HISTORY create mode 100644 doc/INSTALL create mode 100644 doc/Netpbm.programming create mode 100644 doc/README.CYGWIN create mode 100644 doc/README.DJGPP create mode 100644 doc/USERDOC create mode 100644 doc/copyright_summary create mode 100644 doc/lgpl_v21.txt create mode 100644 doc/netpbm.1 create mode 100644 doc/netpbm.html create mode 100644 editor/Makefile create mode 100644 editor/dithers.h create mode 100644 editor/pamaddnoise.c create mode 100644 editor/pamcomp.c create mode 100644 editor/pamcut.c create mode 100644 editor/pamcut.test create mode 100644 editor/pamdeinterlace.c create mode 100644 editor/pamdice.c create mode 100644 editor/pamdither.c create mode 100644 editor/pamditherbw.c create mode 100644 editor/pamedge.c create mode 100644 editor/pamenlarge.c create mode 100644 editor/pamenlarge.test create mode 100644 editor/pamflip.c create mode 100644 editor/pamflip.test create mode 100644 editor/pamfunc.c create mode 100644 editor/pammasksharpen.c create mode 100644 editor/pammixinterlace.c create mode 100644 editor/pamoil.c create mode 100644 editor/pamperspective.c create mode 100644 editor/pampop9.c create mode 100644 editor/pamscale.c create mode 100755 editor/pamstretch-gen create mode 100644 editor/pamstretch.c create mode 100644 editor/pamthreshold.c create mode 100644 editor/pbmclean.c create mode 100644 editor/pbmlife.c create mode 100644 editor/pbmmask.c create mode 100644 editor/pbmpscale.c create mode 100644 editor/pbmreduce.c create mode 100644 editor/pgmabel.c create mode 100644 editor/pgmbentley.c create mode 100644 editor/pgmdeshadow.c create mode 100644 editor/pgmenhance.c create mode 100644 editor/pgmmedian.c create mode 100644 editor/pgmmorphconv.c create mode 100644 editor/pnmalias.c create mode 100644 editor/pnmcat.c create mode 100644 editor/pnmcomp.c create mode 100644 editor/pnmconvol.c create mode 100644 editor/pnmcrop.c create mode 100644 editor/pnmcut.c create mode 100755 editor/pnmflip create mode 100644 editor/pnmgamma.c create mode 100644 editor/pnmhisteq.c create mode 100644 editor/pnmindex.c create mode 100755 editor/pnmindex.csh create mode 100755 editor/pnmindex.sh create mode 100644 editor/pnminvert.c create mode 100644 editor/pnminvert.test create mode 100755 editor/pnmmargin create mode 100644 editor/pnmmontage.c create mode 100644 editor/pnmnlfilt.c create mode 100644 editor/pnmnorm.c create mode 100644 editor/pnmpad.c create mode 100644 editor/pnmpaste.c create mode 100755 editor/pnmquant create mode 100644 editor/pnmremap.c create mode 100644 editor/pnmrotate.c create mode 100644 editor/pnmscale.c create mode 100644 editor/pnmscalefixed.c create mode 100644 editor/pnmshear.c create mode 100644 editor/pnmsmooth.README create mode 100644 editor/pnmsmooth.c create mode 100644 editor/pnmstitch.c create mode 100644 editor/pnmtile.c create mode 100644 editor/ppm3d.c create mode 100644 editor/ppmbrighten.c create mode 100644 editor/ppmchange.c create mode 100644 editor/ppmcolormask.c create mode 100644 editor/ppmdim.c create mode 100644 editor/ppmdist.c create mode 100644 editor/ppmdither.c create mode 100644 editor/ppmdraw.c create mode 100755 editor/ppmfade create mode 100644 editor/ppmflash.c create mode 100644 editor/ppmglobe.c create mode 100644 editor/ppmlabel.c create mode 100644 editor/ppmmix.c create mode 100644 editor/ppmntsc.c create mode 100755 editor/ppmquant create mode 100755 editor/ppmquantall create mode 100644 editor/ppmquantall.csh create mode 100644 editor/ppmrelief.c create mode 100755 editor/ppmshadow create mode 100644 editor/ppmshadow.doc create mode 100644 editor/ppmshift.c create mode 100644 editor/ppmspread.c create mode 100644 editor/ppmtv.c create mode 100644 generator/Makefile create mode 100644 generator/pamgauss.c create mode 100644 generator/pamgradient.c create mode 100644 generator/pamseq.c create mode 100644 generator/pamstereogram.c create mode 100644 generator/pamstereogram.test create mode 100644 generator/pbmmake.c create mode 100644 generator/pbmmake.test create mode 100644 generator/pbmpage.c create mode 100644 generator/pbmtext.c create mode 100644 generator/pbmtextps.c create mode 100644 generator/pbmupc.c create mode 100644 generator/pgmcrater.c create mode 100644 generator/pgmkernel.c create mode 100644 generator/pgmmake.c create mode 100644 generator/pgmnoise.c create mode 100644 generator/pgmramp.c create mode 100644 generator/ppmcie.c create mode 100644 generator/ppmcolors.c create mode 100644 generator/ppmforge.c create mode 100644 generator/ppmmake.c create mode 100644 generator/ppmpat.c create mode 100755 generator/ppmrainbow create mode 100644 generator/ppmrough.c create mode 100644 generator/ppmwheel.c create mode 100755 installnetpbm create mode 100644 inttypes_netpbm.h create mode 100644 lib/Makefile create mode 100644 lib/bitio.c create mode 100644 lib/bitio.h create mode 100644 lib/colorname.c create mode 100644 lib/colorname.h create mode 100644 lib/compile.h create mode 100644 lib/fileio.c create mode 100644 lib/fileio.h create mode 100644 lib/libpam.c create mode 100644 lib/libpam.h create mode 100644 lib/libpamcolor.c create mode 100644 lib/libpammap.c create mode 100644 lib/libpamn.c create mode 100644 lib/libpamread.c create mode 100644 lib/libpamwrite.c create mode 100644 lib/libpbm.h create mode 100644 lib/libpbm1.c create mode 100644 lib/libpbm2.c create mode 100644 lib/libpbm3.c create mode 100644 lib/libpbmfont.c create mode 100644 lib/libpbmvms.c create mode 100644 lib/libpgm.h create mode 100644 lib/libpgm1.c create mode 100644 lib/libpgm2.c create mode 100644 lib/libpm.c create mode 100644 lib/libpnm1.c create mode 100644 lib/libpnm2.c create mode 100644 lib/libpnm3.c create mode 100644 lib/libppm.h create mode 100644 lib/libppm1.c create mode 100644 lib/libppm2.c create mode 100644 lib/libppmcmap.c create mode 100644 lib/libppmcolor.c create mode 100644 lib/libppmd.c create mode 100644 lib/libppmfloyd.c create mode 100644 lib/libppmfuzzy.c create mode 100644 lib/libsystem.c create mode 100644 lib/libsystem_dummy.c create mode 100644 lib/lum.h create mode 100644 lib/mkstemp.c create mode 100644 lib/pam.h create mode 100644 lib/pammap.h create mode 100644 lib/path.c create mode 100644 lib/pbm.h create mode 100644 lib/pbmfont.h create mode 100644 lib/pgm.h create mode 100644 lib/pm.h create mode 100644 lib/pm_gamma.h create mode 100644 lib/pm_system.h create mode 100644 lib/pnm.h create mode 100644 lib/ppm.h create mode 100644 lib/ppmcmap.h create mode 100644 lib/ppmdfont.c create mode 100644 lib/ppmdfont.h create mode 100644 lib/ppmdraw.h create mode 100644 lib/ppmfloyd.h create mode 100644 lib/rgb.txt create mode 100644 lib/standard.ppmdfont create mode 100644 lib/standardppmdfont.c create mode 100644 lib/util/LICENSE.txt create mode 100644 lib/util/Makefile create mode 100644 lib/util/bitreverse.h create mode 100644 lib/util/filename.c create mode 100644 lib/util/filename.h create mode 100644 lib/util/intcode.h create mode 100644 lib/util/lexheader create mode 100644 lib/util/mallocvar.h create mode 100644 lib/util/nstring.c create mode 100644 lib/util/nstring.h create mode 100644 lib/util/pm_c_util.h create mode 100644 lib/util/shhopt-1.1.6.lsm create mode 100644 lib/util/shhopt.README create mode 100644 lib/util/shhopt.c create mode 100644 lib/util/shhopt.h create mode 100644 lib/util/testnstring.c create mode 100644 lib/util/wordaccess.h create mode 100644 lib/util/wordaccess_64_le.h create mode 100644 lib/util/wordaccess_gcc3_be.h create mode 100644 lib/util/wordaccess_gcc3_le.h create mode 100644 lib/util/wordaccess_generic.h create mode 100755 manweb create mode 100644 netpbm.c create mode 100644 other/Makefile create mode 100644 other/pamarith.c create mode 100644 other/pambayer.c create mode 100644 other/pamchannel.c create mode 100644 other/pamdepth.c create mode 100644 other/pamendian.c create mode 100644 other/pamlookup.c create mode 100644 other/pampick.c create mode 100644 other/pamsplit.c create mode 100644 other/pamstack.c create mode 100644 other/pamsummcol.c create mode 100644 other/pamx/COPYRIGHT create mode 100644 other/pamx/Makefile create mode 100644 other/pamx/Makefile2 create mode 100644 other/pamx/fill.c create mode 100644 other/pamx/fill.h create mode 100644 other/pamx/image.c create mode 100644 other/pamx/image.h create mode 100644 other/pamx/pamx.c create mode 100644 other/pamx/send.c create mode 100644 other/pamx/send.h create mode 100644 other/pamx/valtomem.h create mode 100644 other/pamx/window.c create mode 100644 other/pamx/window.h create mode 100644 other/pamx/ximageinfo.h create mode 100644 other/pnmcolormap.c create mode 100644 other/ppmdcfont.c create mode 100644 other/ppmddumpfont.c create mode 100644 other/ppmdmkfont.c create mode 100644 other/ppmsvgalib.c create mode 100755 other/ppmtomap create mode 100644 pm_config.h create mode 100644 pm_config.in.h create mode 100644 testgrid.pbm create mode 100644 testimg.ppm create mode 100644 urt/Makefile create mode 100644 urt/README create mode 100644 urt/Runput.c create mode 100644 urt/Runput.h create mode 100644 urt/cmd_name.c create mode 100644 urt/rle.h create mode 100644 urt/rle_addhist.c create mode 100644 urt/rle_code.h create mode 100644 urt/rle_config.h create mode 100644 urt/rle_error.c create mode 100644 urt/rle_getcom.c create mode 100644 urt/rle_getrow.c create mode 100644 urt/rle_getskip.c create mode 100644 urt/rle_global.c create mode 100644 urt/rle_hdr.c create mode 100644 urt/rle_open_f.c create mode 100644 urt/rle_put.h create mode 100644 urt/rle_putcom.c create mode 100644 urt/rle_putrow.c create mode 100644 urt/rle_row_alc.c create mode 100644 urt/scanargs.c create mode 100644 urt/vaxshort.c create mode 100644 urt/vaxshort.h create mode 100644 version.h create mode 100755 vms/Add_List.com create mode 100755 vms/Make_PBMplus.com create mode 100755 vms/Make_PBMplusShr.com create mode 100644 vms/NetPBM.TeX create mode 100644 vms/PBMplus.hlp create mode 100644 vms/RGB.txt create mode 100755 vms/SetUp.com create mode 100755 vms/stamp-date.com diff --git a/GNUmakefile b/GNUmakefile new file mode 100644 index 00000000..d26ddf50 --- /dev/null +++ b/GNUmakefile @@ -0,0 +1,393 @@ +# Makefile for Netpbm + +# Configuration should normally be done in the included file Makefile.config. + +# Targets in this file: +# +# nonmerge: Build everything, in the source directory. +# merge: Build everything as merged executables, in the source dir +# package: Make a package of Netpbm files ready to install +# +# The default target is either "merge" or "nonmerge", as determined by +# the DEFAULT_TARGET variable set by Makefile.config. + +# About the "merge" target: Normally the Makefiles build separate +# executables for each program. However, on some systems (especially +# those without shared libraries) this can mean a lot of space. In +# this case you might try building a "merge" instead. The idea here +# is to link all the programs together into one huge executable, along +# with a tiny dispatch program that runs one of the programs based on +# the command name with which it was invoked. You install the merged +# executable with a file system link for the name of each program it +# includes. This is much more important when you're statically +# linking than when you're using shared libraries. On a Sun3 under +# SunOS 3.5, where shared libraries are not available, the space for +# executables went from 2970K to 370K in an older Netpbm. On a +# GNU/Linux IA32 system with shared libraries in 2002, it went from +# 2949K to 1663K. + +# To build a "merge" system, just set DEFAULT_TARGET to "merge" instead +# of "nomerge" in Makefile.config. In that case, you should probably also +# set NETPBMLIBTYPE to "unixstatic", since a shared library doesn't do you +# much good. + +# The CURDIR variable presents a problem because it was introduced in +# GNU Make 3.77. We need the CURDIR variable in order for our 'make +# -C xxx -f xxx' commands to work. If we used the obvious alternative +# ".", that wouldn't work because it would refer to the directory +# named in -C, not the directory the make file you are reading is +# running in. The -f option is necessary in order to have separate +# source and object directories. + +ifeq ($(CURDIR)x,x) +all package install: + @echo "YOU NEED AT LEAST VERSION 3.77 OF GNU MAKE TO BUILD NETPBM." + @echo "Netpbm's makefiles need the CURDIR variable that was " + @echo "introduced in 3.77. Your version does not have CURDIR." + @echo + @echo "You can get a current GNU Make via http://www.gnu.org/software" + @echo + @echo "If upgrading is impossible, try modifying GNUMakefile and " + @echo "Makefile.common to replace \$(CURDIR) with \$(shell /bin/pwd) " +else + + +include Makefile.srcdir +BUILDDIR = $(CURDIR) +SUBDIR = +VPATH=.:$(SRCDIR) + +include $(BUILDDIR)/Makefile.config + +PRODUCT_SUBDIRS = lib converter analyzer editor generator other +SUPPORT_SUBDIRS = urt buildtools + +SUBDIRS = $(PRODUCT_SUBDIRS) $(SUPPORT_SUBDIRS) + +SCRIPTS = manweb +MANUALS1 = netpbm +NOMERGEBINARIES = netpbm + +OBJECTS = netpbm.o + +default: $(DEFAULT_TARGET) + echo "EXISTENCE OF THIS FILE MEANS NETPBM HAS BEEN BUILT." \ + >build_complete + @echo "" + @echo "Netpbm is built. The next step is normally to package it " + @echo "for installation by running " + @echo "" + @echo " make package pkgdir=DIR" + @echo "" + @echo "to copy all the Netpbm files you need to install into the " + @echo "directory DIR. Then you can proceed to install." + +all: nonmerge + +.PHONY: nonmerge +nonmerge: $(PRODUCT_SUBDIRS:%=%/all) + +OMIT_CONFIG_RULE = 1 +OMIT_VERSION_H_RULE = 1 +OMIT_INTTYPES_RULE = 1 +include $(SRCDIR)/Makefile.common + +$(BUILDDIR)/Makefile.config: $(SRCDIR)/Makefile.config.in + $(SRCDIR)/configure $(SRCDIR)/Makefile.config.in + + +# typegen is a utility program used by the make file below. +TYPEGEN = $(BUILDDIR)/buildtools/typegen + +# endiangen is a utility program used by the make file below. +ENDIANGEN = $(BUILDDIR)/buildtools/endiangen + +$(TYPEGEN): $(BUILDDIR)/buildtools + $(MAKE) -C $(dir $@) -f $(SRCDIR)/buildtools/Makefile \ + SRCDIR=$(SRCDIR) BUILDDIR=$(BUILDDIR) $(notdir $@) + +DELETEIT = (rm -f $@ || false) + +$(BUILDDIR)/inttypes_netpbm.h: $(TYPEGEN) + $(TYPEGEN) >$@ || $(DELETEIT) + +# We run a couple of programs on the build machine in computing the +# contents of pm_config.h. We need to give the user a way not to do +# that or to override the results, because it doesn't work if he's +# cross compiling. + +$(BUILDDIR)/pm_config.h: \ + $(SRCDIR)/pm_config.in.h Makefile.config inttypes_netpbm.h $(ENDIANGEN) + echo '/* pm_config.h GENERATED BY A MAKE RULE */' >$@ || $(DELETEIT) + echo '#ifndef PM_CONFIG_H' >>$@ || $(DELETEIT) + echo '#define PM_CONFIG_H' >>$@ || $(DELETEIT) +ifeq ($(INTTYPES_H)x,x) + echo '/* Don't need to #include any inttypes.h-type thing */ +else + ifeq ($(INTTYPES_H),"inttypes_netpbm.h") + cat inttypes_netpbm.h >>$@ || $(DELETEIT) + else + echo '#include $(INTTYPES_H)' >>$@ || $(DELETEIT) + endif +endif +ifeq ($(HAVE_INT64),Y) + echo "#define HAVE_INT64 1" >>$@ || $(DELETEIT) +else + echo "#define HAVE_INT64 0" >>$@ || $(DELETEIT) +endif + echo '/* pm_config.h.in FOLLOWS ... */' >>$@ || $(DELETEIT) + cat $(SRCDIR)/pm_config.in.h >>$@ || $(DELETEIT) + $(ENDIANGEN) >>$@ || $(DELETEIT) + echo '#endif' >>$@ || $(DELETEIT) + + +MAJOR := $(NETPBM_MAJOR_RELEASE) +MINOR := $(NETPBM_MINOR_RELEASE) +POINT := $(NETPBM_POINT_RELEASE) +$(BUILDDIR)/version.h: + @rm -f $@ + @echo "/* Generated by make file rule */" >$@ + @echo "#define NETPBM_VERSION" \ + \"Netpbm $(MAJOR).$(MINOR).$(POINT)"\"" >$@ + + +.PHONY: install +install: + @echo "After doing a 'make', do " + @echo "" + @echo " make package pkgdir=DIR" + @echo "" + @echo "to copy all the Netpbm files you need to install into the " + @echo "directory DIR." + @echo "" + @echo "Then, do " + @echo "" + @echo " ./installnetpbm" + @echo + @echo "to install from there to your system via an interactive. " + @echo "dialog. Or do it manually using simple copy commands and " + @echo "following instructions in the file DIR/README" + +.PHONY: package package_build init_package advise_installnetpbm +package: build_complete package_build advise_installnetpbm + +build_complete: +# The regular build creates this file as its last act, so if it doesn't exist, +# that means either the user skipping the build step, or the build failed. + @echo "You must build Netpbm before you can package Netpbm. " + @echo "The usual way to do this is to type 'make' with no arguments." + @echo "If you did that, then the build apparently failed. There " + @echo "should have been error messages indicating why. If you " + @echo "can't fix the build problem, you can do 'make --keep-going' " + @echo "to force the build to continue with other parts that " + @echo "it may be able to build successfully, then do " + @echo "'make package --keep-going' to package whatever was " + @echo "successfully built." + @echo + @false; + +package_build: init_package install-run install-dev + +MAJOR=$(NETPBM_MAJOR_RELEASE) +MINOR=$(NETPBM_MINOR_RELEASE) +POINT=$(NETPBM_POINT_RELEASE) + +init_package: + @if [ -d $(PKGDIR) ]; then \ + echo "Directory $(PKGDIR) already exists. Please specify a "; \ + echo "directory that can be created fresh, like this: "; \ + echo " make package PKGDIR=/tmp/newnetpbm "; \ + false; \ + fi + mkdir $(PKGDIR) + echo "Netpbm install package made by 'make package'" \ + >$(PKGDIR)/pkginfo + date >>$(PKGDIR)/pkginfo + echo Netpbm $(MAJOR).$(MINOR).$(POINT) >$(PKGDIR)/VERSION + $(INSTALL) -c -m 664 $(SRCDIR)/buildtools/README.pkg $(PKGDIR)/README + $(INSTALL) -c -m 664 $(SRCDIR)/buildtools/config_template \ + $(PKGDIR)/config_template + +advise_installnetpbm: + @echo + @echo "Netpbm has been successfully packaged under directory" + @echo "$(PKGDIR). Run 'installnetpbm' to install it on your system." + +.PHONY: install-run +ifeq ($(DEFAULT_TARGET),merge) +install-run: install-merge +else +install-run: install-nonmerge +endif + +.PHONY: install-merge install-nonmerge +install-merge: install.merge install.lib install.data \ + install.manweb install.man + +install-nonmerge: install.bin install.lib install.data \ + install.manweb install.man + +.PHONY: merge +merge: lib/all netpbm + +MERGELIBS = +ifneq ($(ZLIB),NONE) + MERGELIBS += $(ZLIB) +endif +ifneq ($(JPEGLIB),NONE) + MERGELIBS += $(JPEGLIB) +endif +ifneq ($(TIFFLIB),NONE) + MERGELIBS += $(TIFFLIB) +endif +ifneq ($(URTLIB),NONE) + MERGELIBS += $(URTLIB) +endif +ifneq ($(LINUXSVGALIB),NONE) + MERGELIBS += $(LINUXSVGALIB) +endif +ifneq ($(X11LIB),NONE) + MERGELIBS += $(X11LIB) +endif + +ifeq ($(shell libpng-config --version),) + PNGLD = $(shell $(LIBOPT) $(LIBOPTR) $(PNGLIB) $(ZLIB)) +else + PNGLD = $(shell libpng-config --ldflags) +endif + +ifeq ($(shell xml2-config --version),) + XML2LD= +else + XML2LD=$(shell xml2-config --libs) +endif + + +# If URTLIB is BUNDLED_URTLIB, then we're responsible for building it, which +# means it needs to be a dependency: +ifeq ($(URTLIB),$(BUNDLED_URTLIB)) + URTLIBDEP = $(URTLIB) +endif + +# We have two different ways to do the merge build: +# +# 1) Each directory produces an object file merge.o containing all the code +# in that directory and its descendants that needs to go into the 'netpbm' +# program. The make files do this recursively, via a link command that +# combines multiple relocateable object files into one. All we do here +# at the top level is make merge.o and link it with netpbm.o and the +# libraries. +# +# This is the clean way, and we use it whenever we can. But we don't +# know how to do the link on every platform. +# +# 2) Each directory produces a list of all the object files in that +# directory and its descendants that need to go into the 'netpbm' +# program. This list is in a file called 'mergelist'. The make files +# do this recursively. Here at the top level, we make mergelist and +# then do one large link of everything listed in it, plus netpbm.o and +# the libraries. +# +# This doesn't require any special link command like (1), but is +# not very clean. The dependencies don't work right. And at least +# one linker (on DJGPP) can't handle that many input files. + +ifeq ($(LDRELOC),NONE) + OBJECT_DEP = mergelist + OBJECT_LIST = `cat mergelist` +else + OBJECT_DEP = merge.o + OBJECT_LIST = merge.o +endif + +netpbm:%:%.o $(OBJECT_DEP) $(NETPBMLIB) $(URTLIBDEP) $(LIBOPT) +# Note that LDFLAGS might contain -L options, so order is important. + $(LD) -o $@ $< $(OBJECT_LIST) \ + $(LDFLAGS) $(shell $(LIBOPT) $(NETPBMLIB) $(MERGELIBS)) \ + $(PNGLD) $(XML2LD) $(MATHLIB) $(NETWORKLD) $(LADD) + +netpbm.o: mergetrylist + +install.merge: local.install.merge +.PHONY: local.install.merge +local.install.merge: + cd $(PKGDIR)/bin; $(SYMLINKEXE) netpbm pnmnoraw + cd $(PKGDIR)/bin; $(SYMLINKEXE) netpbm gemtopbm + cd $(PKGDIR)/bin; $(SYMLINKEXE) netpbm pnminterp + cd $(PKGDIR)/bin; $(SYMLINKEXE) netpbm pgmoil + cd $(PKGDIR)/bin; $(SYMLINKEXE) netpbm ppmtojpeg + cd $(PKGDIR)/bin; $(SYMLINKEXE) netpbm bmptoppm + cd $(PKGDIR)/bin; $(SYMLINKEXE) netpbm pgmnorm + cd $(PKGDIR)/bin; $(SYMLINKEXE) netpbm pnmfile + +ifneq ($(NETPBMLIBTYPE),unixstatic) +install.lib: lib/install.lib +else +install.lib: +endif + +.PHONY: install.manweb +install.manweb: $(PKGDIR)/man/web/netpbm.url $(PKGDIR)/bin/doc.url + +$(PKGDIR)/man/web/netpbm.url: $(PKGDIR)/man/web + echo "$(NETPBM_DOCURL)" > $@ + chmod $(INSTALL_PERM_MAN) $@ + +$(PKGDIR)/bin/doc.url: $(PKGDIR)/bin + echo "$(NETPBM_DOCURL)" > $@ + chmod $(INSTALL_PERM_MAN) $@ + +.PHONY: install-dev +# Note that you might install the development package and NOT the runtime +# package. If you have a special system for building stuff, maybe for +# multiple platforms, that's what you'd do. Ergo, install.lib is here even +# though it is also part of the runtime install. +install-dev: install.hdr install.staticlib install.lib install.sharedlibstub + +.PHONY: install.hdr +install.hdr: $(PKGDIR)/include + $(MAKE) -C lib -f $(SRCDIR)/lib/Makefile \ + SRCDIR=$(SRCDIR) BUILDDIR=$(BUILDDIR) install.hdr + $(INSTALL) -c -m $(INSTALL_PERM_HDR) \ + $(SRCDIR)/pm_config.h $(PKGDIR)/include + +ifeq ($(STATICLIB_TOO),y) +BUILD_STATIC = y +else + ifeq ($(NETPBMLIBTYPE),unixstatic) + BUILD_STATIC = y + else + BUILD_STATIC = n + endif +endif + +.PHONY: install.staticlib +install.staticlib: +ifeq ($(BUILD_STATIC),y) + $(MAKE) -C lib -f $(SRCDIR)/lib/Makefile \ + SRCDIR=$(SRCDIR) BUILDDIR=$(BUILDDIR) install.staticlib +endif + +.PHONY: install.sharedlibstub +install.sharedlibstub: + $(MAKE) -C lib -f $(SRCDIR)/lib/Makefile \ + SRCDIR=$(SRCDIR) BUILDDIR=$(BUILDDIR) install.sharedlibstub + +clean: localclean + +.PHONY: localclean +localclean: + rm -f netpbm build_started build_complete + rm -f pm_config.h inttypes_netpbm.h version.h + +# Note that removing Makefile.config must be the last thing we do, +# because no other makes will work after that is done. +distclean: localdistclean +.PHONY: localdistclean +localdistclean: + -rm -f `find -type l` + -rm -f Makefile.config + +# The following endif is for the else block that contains virtually the +# whole file, for the test of the existence of CURDIR. +endif diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..2227eb5c --- /dev/null +++ b/Makefile @@ -0,0 +1,14 @@ +# The Netpbm make files exploit features of GNU Make that other Makes +# do not have. Because it is a common mistake for users to try to build +# Netpbm with a different Make, we have this make file that does nothing +# but tell the user to use GNU Make. + +# If the user were using GNU Make now, this file would not get used because +# GNU Make uses a make file named "GNUmakefile" in preference to "Makefile" +# if it exists. Netpbm is shipped with a "GNUmakefile". + +all merge install clean dep: + @echo "You must use GNU Make to build Netpbm. You are running some " + @echo "other Make. GNU Make may be installed on your system with " + @echo "the name 'gmake'. If not, see http://www.gnu.org/software ." + @echo diff --git a/Makefile.common b/Makefile.common new file mode 100644 index 00000000..a6b6952e --- /dev/null +++ b/Makefile.common @@ -0,0 +1,545 @@ +# -*-makefile-*- <-- an Emacs control +# This is a make file inclusion, to be included in all the +# Netpbm make files. + +# This file is meant to contain rules that are substantially the same +# in each of the pbm, pgm, ppm, and pnm subdirectory makes, to avoid +# duplication of effort. + +# The following variables must be set in any make file that uses these +# rules: +# +# SRCDIR: The top level directory of Netpbm source code. +# BUILDDIR: The top level directory into which Netpbm is built (built, +# not installed). +# SUBDIR: The directory, relative to BUILDDIR, of the current directory. +# It is also the directory, relative to SRCDIR, of source directory that +# corresponds to the current directory. Note that you build in the +# current directory, using files from the source directory. +# SUBDIRS: list of subdirectories in which certain targets (e.g. 'clean') +# should be made recursively. +# PKGDIR_DEFAULT: The place to put the packaged stuff for 'make package' +# if the user doesn't put "pkgdir=" on the Make command line. +# PKGMANDIR: The subdirectory (e.g. "man" or "share/man" of the package +# directory root in which man pages should be packaged. +# OBJECTS: .o files to be built from .c files with the standard rule. +# PORTBINARIES: list of conventional executables to be built with the standard +# rule +# MATHBINARIES: obsolete. +# DATAFILES: list of files that should be installed in the "data" directory. +# NETPBMLIBSUFFIX: the suffix, e.g. "so" for the main libraries we build, +# whatever type they may be. +# STATICLIBSUFFIX: the suffix, e.g. "a" on a static library. This need +# not be defined if the user doesn't want to build a static libraries in +# addition to the main libraries. +# BINARIES: list of all the executables that need to be installed. +# INSTALL: command to use to copy files to where they belong +# INSTALL_PERM_BIN: file permissions for installed binaries +# INSTALL_PERM_LIB: ...same for libraries +# INSTALL_PERM_HDR: ...same for headers +# INSTALL_PERM_MAN: ...same for man pages +# MERGE_OBJECTS: list of object files that go into the merged executable +# from the current directory (not subdirectories). All of these are to +# be built with the standard rule for merged objects. These names are +# relative to the current make directory (must not start with / ). +# MERGEBINARIES: list of the programs that, in a merge build, are invoked +# via the merged Netpbm program +# CC: C compiler command +# CPPFLAGS: C preprocessor options +# CFLAGS: C compiler general options +# LD: linker command +# LINKERISCOMPILER: 'Y' if the linker invoked by LD is actually a compiler +# front end, so takes linker options in a different format +# LDFLAGS: linker options +# LIBS or LOADLIBES: names of libraries to be added to all links +# INCLUDES: Compiler option string to establish the search path for include +# files when compiling things or computing dependencies (make dep). +# current directory, corresponding source tree directory, and ./importinc +# are implied, so should not be in here. + +# In addition, there is CADD, which is extra C compilation flags and +# is intended to be set on a make command line (e.g. 'make CADD=-g') +# for flags that apply just to a particular build. + +# In addition, there is CFLAGS_PERSONAL, which is extra C +# compilation flags and is expected to be set via environment variable +# for flags that are particular to the person doing the build and not +# specific to Netpbm. + +NETPBM_MAJOR_RELEASE = 10 +NETPBM_MINOR_RELEASE = 35 +NETPBM_POINT_RELEASE = 0 + +INCLUDES2 := $(INCLUDES) -I$(SRCDIR)/$(SUBDIR) -I. -I importinc + +ifeq ($(NETPBMLIBTYPE),unixstatic) + NETPBMLIBFNAME = libnetpbm.$(STATICLIBSUFFIX) +else + NETPBMLIBFNAME = $(NETPBMSHLIBPREFIX)netpbm$(DLLVER).$(NETPBMLIBSUFFIX) +endif +NETPBMLIB = $(BUILDDIR)/lib/$(NETPBMLIBFNAME) + +BUNDLED_URTLIB = $(BUILDDIR)/urt/librle.a + +# LIBS and LOADLIBES are commonly set as environment variables. +# LOADLIBES is used by GNU Make's implicit .c->.o rule. LIBS is used by +# GNU Autoconf. + +LDLIBS = $(LOADLIBES) $(LIBS) + +# 'pkgdir' is meant to be set on the make command line. Results are +# disastrous if PKGDIR is a relative directory, and I don't know any +# way to detect that case and fail, so I just add a '/' to the front +# if it isn't already there. +ifneq ($(pkgdir)x,x) + PKGDIR = $(patsubst //%, /%, /$(pkgdir)) +else + PKGDIR = $(PKGDIR_DEFAULT) +endif + +#=========================================================================== +# We build a directory full of symbolic links to the intra-Netpbm public +# header files just so the compile commands don't have to be littered +# with long -I's. +#=========================================================================== + +# Note that the "root" headers are in the root of the build tree, not +# the source tree. All generated headers are in the root directory and +# all root directory headers are generated. +IMPORTINC_ROOT_HEADERS := pm_config.h inttypes_netpbm.h version.h + +IMPORTINC_LIB_HEADERS := \ + pm.h pbm.h pgm.h ppm.h pnm.h pam.h bitio.h pbmfont.h ppmcmap.h \ + pammap.h colorname.h ppmfloyd.h ppmdraw.h pm_system.h ppmdfont.h \ + pm_gamma.h lum.h + +IMPORTINC_LIB_UTIL_HEADERS := \ + bitreverse.h mallocvar.h nstring.h filename.h pm_c_util.h shhopt.h \ + wordaccess.h wordaccess_64_le.h wordaccess_gcc3_be.h wordaccess_gcc3_le.h \ + wordaccess_generic.h intcode.h \ + +IMPORTINC_HEADERS := \ + $(IMPORTINC_ROOT_HEADERS) \ + $(IMPORTINC_LIB_HEADERS) \ + $(IMPORTINC_LIB_UTIL_HEADERS) + +IMPORTINC_ROOT_FILES := $(IMPORTINC_ROOT_HEADERS:%=importinc/%) +IMPORTINC_LIB_FILES := $(IMPORTINC_LIB_HEADERS:%=importinc/%) +IMPORTINC_LIB_UTIL_FILES := $(IMPORTINC_LIB_UTIL_HEADERS:%=importinc/%) + +importinc: \ + $(IMPORTINC_ROOT_FILES) \ + $(IMPORTINC_LIB_FILES) \ + $(IMPORTINC_LIB_UTIL_FILES) \ + +$(IMPORTINC_ROOT_FILES):importinc/%:$(BUILDDIR)/% + mkdir -p importinc + rm -f $@ + $(SYMLINK) $< $@ + +$(IMPORTINC_LIB_FILES):importinc/%:$(SRCDIR)/lib/% + mkdir -p importinc + rm -f $@ + $(SYMLINK) $< $@ + +$(IMPORTINC_LIB_UTIL_FILES):importinc/%:$(SRCDIR)/lib/util/% + mkdir -p importinc + rm -f $@ + $(SYMLINK) $< $@ + + +# We build the symbolic links to header files in the current directory +# just so the compile commands don't have to be littered with -I's. + +bmp.h tga.h:%:$(SRCDIR)/converter/% + rm -f $@ + $(SYMLINK) $< $@ + +ifneq ($(OMIT_VERSION_H_RULE),1) + +$(BUILDDIR)/version.h: + $(MAKE) -C $(dir $@) $(notdir $@) +endif + +ifneq ($(OMIT_CONFIG_RULE),1) +$(BUILDDIR)/Makefile.config: $(SRCDIR)/Makefile.config.in + $(MAKE) -C $(dir $@) $(notdir $@) + +$(BUILDDIR)/pm_config.h: + $(MAKE) -C $(dir $@) $(notdir $@) +endif + +ifneq ($(OMIT_INTTYPES_RULE),1) +$(BUILDDIR)/inttypes_netpbm.h: + $(MAKE) -C $(dir $@) -f $(SRCDIR)/GNUmakefile $(notdir $@) +endif + +# Note that any time you do a make on a fresh Netpbm source tree, +# Make notices that 'Makefile.config', which the make files include, does not +# exist and runs the "Makefile.config" target, which runs Configure. +# If the "config" target were to run Configure as well, it would get run +# twice in a row if you did a 'make config' on a fresh Netpbm source tree. +# But we don't want to make "config" just a no-op, because someone might +# try it after Makefile.config already exists, in order to make a new +# Makefile.config. Issuing a message as follows seems to make sense in +# both cases. +.PHONY: config +config: + @echo "To reconfigure the build, run 'configure'" + +# Rule to make C source from lex source. +%.c:%.l + $(LEX) -t $< >$(notdir $@) + +# Rule to make regular object files, e.g. pnmtojpeg.o. + +$(OBJECTS): %.o: %.c importinc +############################################################################# +# Note that the user may have configured -I options into CFLAGS or CPPFLAGS. +# -I. is needed when builddir != srcdir +# Note about -o: There used to be systems that couldn't handle a space +# between flag and value. But we found a Solaris gcc on 2003.09.02 that +# actually fails _without_ the space (it invokes Solaris 'as' with the +# following command, which generates a "no input filename" error: +# '/usr/ccs/bin/as -V -Qy -s -o/tmp/hello.o /var/tmp/ccpiNnia.s') +# This rule has had the space since way before that, so it looks like +# the space is no longer a problem for anyone. +############################################################################# +# +# The NDEBUG macro says not to build code that assumes there are no bugs. +# This makes the code go faster. The main thing it does is tell the C library +# to make assert() a no-op as opposed to generating code to check the +# assertion and crash the program if it isn't really true. You can add +# -UNDEBUG (in any of various ways) to override this. +# + $(CC) -c $(INCLUDES2) -DNDEBUG \ + $(CPPFLAGS) $(CFLAGS) $(CFLAGS_PERSONAL) $(CADD) -o $@ $< + +# libopt is a utility program used in the make file below. +LIBOPT = $(BUILDDIR)/buildtools/libopt + +ifneq ($(OMIT_BUILDTOOL_RULE),1) +$(LIBOPT) $(TYPEGEN): $(BUILDDIR)/buildtools + $(MAKE) -C $(dir $@) -f $(SRCDIR)/buildtools/Makefile \ + SRCDIR=$(SRCDIR) BUILDDIR=$(BUILDDIR) $(notdir $@) +endif + +ifneq ($(OMIT_LIBRARY_RULE),1) +$(NETPBMLIB): $(BUILDDIR)/lib + $(MAKE) -C $(dir $@) -f $(SRCDIR)/lib/Makefile \ + SRCDIR=$(SRCDIR) BUILDDIR=$(BUILDDIR) $(notdir $@) +endif + +ifneq ($(OMIT_URT_RULE),1) +$(BUNDLED_URTLIB): $(BUILDDIR)/urt + $(MAKE) -C $(dir $@) -f $(SRCDIR)/urt/Makefile \ + SRCDIR=$(SRCDIR) BUILDDIR=$(BUILDDIR) $(notdir $@) +endif + +# Here are some notes from Nelson H. F. Beebe on April 16, 2002: +# +# There are at least three incompatible kinds of command-line options +# that tell the compiler to instruct the linker to save library paths in +# the executable: +# +# -Wl,-rpath,/path/to/dir gcc, g++, FreeBSD, SGI, Sun compilers +# -rpath /path/to/dir Compaq/DEC, SGI compilers +# -Rdir:dir:dir Portland Group, Sun compilers +# +# Notice that SGI and Sun support two such flavors. +# +# Plus, Scott Schwartz observed on March 25, 2003 that while his +# compiler understands -Wl, his linker does not understand -rpath. +# His compiler is "Sun WorkShop 6 update 2 C 5.3 2001/05/15". +# +# Plus, Mike Saunders found in December 2003 that his Solaris 8 system +# (uname -a says 'SunOS cannonball.method.cx 5.8 Generic_108528-14 +# sun4u sparc SUNW,Ultra-1') with Gcc 2.95.3 requires the syntax +# +# -Wl,-R,/path/to/dir +# +# This is apparently because Gcc invokes this linker for Saunders: +# +# ld: Software Generation Utilities - Solaris Link Editors: 5.8-1.273 +# +# I'd say there are also Solaris systems where Gcc invokes the GNU linker +# and then the option would be -Wl,-rpath... +# +# On IA32 Linux, at least, GNU ld takes -rpath. It also has a -R option, +# but it is something else. + +ifneq ($(NETPBMLIB_RUNTIME_PATH)x,x) + ifeq ($(LINKERISCOMPILER),Y) + # Before Netpbm 10.14 (March 2003), it looks like we used -R + # instead of -Wl,-rpath on all but a few selected platforms as configured + # by Configure. But that doesn't make sense, because we also used + # LD=$(CC) always. Beebe's notes and Saunders' observation above + # above indicate that we need + # -Wl,... everywhere that a compiler is used, whether native or GNU, + # to link. + RPATH = -Wl,$(RPATHOPTNAME),$(NETPBMLIB_RUNTIME_PATH) + else + RPATH = $(RPATHOPTNAME)$(NETPBMLIB_RUNTIME_PATH) + endif +else + RPATH = +endif + +# Rules for conventional single-object file executables + +# Before Netpbm 10.21 (March 2004), we kept separate lists of binaries +# that require the math library and those that don't, so the binaries +# that don't need it wouldn't have to link it. But now libnetpbm +# contains gamma correction routines, so it needs the math library, +# and that means every Netpbm binary needs the math library, whether +# it calls those routines or not. So we will phase out the separate +# lists, and for now we treat them identically. + +# Note that GNU C library sometimes defines math functions as inline +# functions, so linking the math library isn't really necessary. Late +# model GNU C libraries do this only if you specify the -ffast-math +# Gcc option (as told by the __FAST_MATH__ preprocessor macro). +# Earlier ones do it regardless of __FAST_MATH__. + +MATHLIB ?= -lm +$(PORTBINARIES) $(MATHBINARIES): %: %.o $(NETPBMLIB) $(LIBOPT) +# Note that LDFLAGS might contain -L options, so order is important. +# LDFLAGS is commonly set as an environment variable. + $(LD) -o $@ $@.o $(MATHLIB) $(shell $(LIBOPT) $(NETPBMLIB)) \ + $(LDFLAGS) $(LDLIBS) $(RPATH) $(LADD) + + +# MERGE STUFF + +# .o2 is our suffix for an object file that has had it's main() changed +# to e.g. main_pamcut(). We use them for the merge build. + +%.o2: %.c importinc +# Note that the user may have configured -I options into CFLAGS. + $(CC) -c $(INCLUDES2) -DNDEBUG $(CFLAGS) \ + "-Dmain=main_$*" \ + $(CFLAGS_MERGE) $(CFLAGS_PERSONAL) $(CADD) -o $@ $< + +# The "merge try list" is a file full of TRY macro invocations, one for +# each Netpbm program in this directory or any subdirectory that can be +# invoked via the merged Netpbm program. You will find it #included in +# netpbm.c. + +mergetrylist: $(SUBDIRS:%=%/mergetrylist) + cat /dev/null $(SUBDIRS:%=%/mergetrylist) >$@ + $(SRCDIR)/buildtools/make_merge.sh $(MERGEBINARIES) >>$@ + +# The "merge list" is a list of all the object files from this directory and +# any subdirectories that have to be linked into the merged Netpbm program. +# They are absolute paths. + +mergelist: $(SUBDIRS:%=%/mergelist) $(MERGE_OBJECTS) + cat /dev/null $(SUBDIRS:%=%/mergelist) >$@ + echo $(MERGE_OBJECTS:%=$(CURDIR)/%) >>$@ + +# merge.o is the object file that contains all the code in this directory +# that needs to be linked into the merged Netpbm program. This is not used +# today, but some day it will be used instead of mergelist (above). + +ifeq ($(MERGE_OBJECTS),) + MERGE_O_OBJECTS = empty.o +else + MERGE_O_OBJECTS = $(MERGE_OBJECTS) +endif + +merge.o: $(SUBDIRS:%=%/merge.o) $(MERGE_O_OBJECTS) + $(LDRELOC) -o $@ $^ + +# empty.o is useful in doing a merge build. Every directory must be able to +# produce a merge.o file, but not every directory has anything to contribute +# to the merge. +empty.o: %.o: %.c + $(CC) -c $(CFLAGS_PERSONAL) $(CADD) $< -o $@ +empty.c: + cat /dev/null >empty.c + +########################################################################### +# PACKAGING / INSTALLING +########################################################################### + +# Some maintenance notes about $(INSTALL): Some install programs can +# install multiple files in one shot; others can take only one file at +# a time. Some have a -c option; others ignore -c. Some can take +# permissions in mnemonic form (u=rwx,go=rx); others can't, but all +# take the encoded form (755). Some have a -d option to install +# directories and never install them implicitly. Others create +# directories only implicitly. Installbsd and OSF1 Install need a +# space in "-m 755". Others don't care. 2000.05.17. OSF1 Install +# takes only one parameter: the source file. It picks a destination +# directory by default, or you can specify it with a -f option. +# 2000.06.15 + +# DJGPP can do SYMKINKs for programs but not for ordinary files, so +# it define SYMLINKEXE, other system don't need it +ifeq ($(SYMLINKEXE)x,x) + SYMLINKEXE := $(SYMLINK) +endif + +$(PKGDIR)/%: + $(SRCDIR)/buildtools/mkinstalldirs $@ + +.PHONY: install.merge +install.merge: $(NOMERGEBINARIES:%=%_installbin) $(SCRIPTS:%=%_installscript) \ + $(MERGEBINARIES:%=%_installmerge) $(SUBDIRS:%=%/install.merge) + +%_installmerge: $(PKGDIR)/bin + cd $(PKGDIR)/bin ; rm -f $(@:%_installmerge=%) + cd $(PKGDIR)/bin ; $(SYMLINKEXE) netpbm$(EXE) $(@:%_installmerge=%) + +.PHONY: install.bin +install.bin: $(BINARIES:%=%_installbin) $(SCRIPTS:%=%_installscript) \ + $(SUBDIRS:%=%/install.bin) +# Note that on Cygwin, the executables are actually pbmmake.exe, etc. +# Make and Install know that pbmmake.exe counts as pbmmake. + +INSTALLBIN_TARGETS = $(BINARIES:%=%_installbin) netpbm_installbin +.PHONY: $(INSTALLBIN_TARGETS) +$(INSTALLBIN_TARGETS): $(PKGDIR)/bin + $(INSTALL) -c $(STRIPFLAG) -m $(INSTALL_PERM_BIN) \ + $(@:%_installbin=%) $< + +$(SCRIPTS:%=%_installscript): $(PKGDIR)/bin + $(INSTALL) -c -m $(INSTALL_PERM_BIN) \ + $(SRCDIR)/$(SUBDIR)/$(@:%_installscript=%) $< + +.PHONY: install.data +install.data: $(DATAFILES:%=%_installdata) $(SUBDIRS:%=%/install.data) + +.PHONY: $(DATAFILES:%=%_installdata) +$(DATAFILES:%=%_installdata): $(PKGDIR)/misc + $(INSTALL) -c -m $(INSTALL_PERM_DATA) \ + $(SRCDIR)/$(SUBDIR)/$(@:%_installdata=%) $< + + +.PHONY: install.man install.man1 install.man3 install.man5 +install.man: install.man1 install.man3 install.man5 \ + $(SUBDIRS:%=%/install.man) + +MANUALS1 = $(BINARIES) $(SCRIPTS) + +PKGMANDIR = man + +install.man1: $(PKGDIR)/$(PKGMANDIR)/man1 $(MANUALS1:%=%_installman1) + +install.man3: $(PKGDIR)/$(PKGMANDIR)/man3 $(MANUALS3:%=%_installman3) + +install.man5: $(PKGDIR)/$(PKGMANDIR)/man5 $(MANUALS5:%=%_installman5) + +%_installman1: $(PKGDIR)/$(PKGMANDIR)/man1 + perl -w $(SRCDIR)/buildtools/makepointerman $(@:%_installman1=%) \ + $(NETPBM_DOCURL) $< 1 $(MANPAGE_FORMAT) $(INSTALL_PERM_MAN) + +%_installman3: $(PKGDIR)/$(PKGMANDIR)/man3 + perl -w $(SRCDIR)/buildtools/makepointerman $(@:%_installman3=%) \ + $(NETPBM_DOCURL) $< 3 $(MANPAGE_FORMAT) $(INSTALL_PERM_MAN) + +%_installman5: $(PKGDIR)/$(PKGMANDIR)/man5 + perl -w $(SRCDIR)/buildtools/makepointerman $(@:%_installman5=%) \ + $(NETPBM_DOCURL) $< 5 $(MANPAGE_FORMAT) $(INSTALL_PERM_MAN) + +.PHONY: clean + +ifneq ($(EXE)x,x) +EXEPATTERN = *$(EXE) +else +EXEPATTERN = +endif +clean: $(SUBDIRS:%=%/clean) thisdirclean-common + +.PHONY: thisdirclean-common +thisdirclean-common: + -rm -f *.o *.o2 *.a *.so *.so.* *.dll *.dylib *.cat *~ *.i *.s \ + $(EXEPATTERN) *.def *.lnk \ + core *.core mergelist mergetrylist *.c1 empty.c \ + $(BINARIES) pm_types.h + -rm -rf importinc + +.PHONY: distclean +distclean: $(SUBDIRS:%=%/distclean) thisdirclean-common + rm -f Makefile.depend + +DEP_SOURCES = $(wildcard *.c *.cpp *.cc) + +.PHONY: dep +dep: $(SUBDIRS:%=%/dep) importinc +# We use -MG here because of compile.h and version.h. They need not exist +# before the first make after a clean. + +ifneq ($(DEP_SOURCES)x,x) + $(CC) -MM -MG $(INCLUDES2) $(DEP_SOURCES) >Makefile.depend +endif + +# Note: if I stack all these subdirectory targets into one rule, I get +# weird behavior where e.g. make install-nonmerge causes all the +# %/install.bin makes to happen recursively, but then lib/install.lib +# is considered up to date and doesn't get rebuilt. +%/install.bin: + $(MAKE) -C $(dir $@) -f $(SRCDIR)/$(SUBDIR)/$(dir $@)Makefile \ + SRCDIR=$(SRCDIR) BUILDDIR=$(BUILDDIR) $(notdir $@) +%/install.lib: + $(MAKE) -C $(dir $@) -f $(SRCDIR)/$(SUBDIR)/$(dir $@)Makefile \ + SRCDIR=$(SRCDIR) BUILDDIR=$(BUILDDIR) $(notdir $@) +%/install.man: + $(MAKE) -C $(dir $@) -f $(SRCDIR)/$(SUBDIR)/$(dir $@)Makefile \ + SRCDIR=$(SRCDIR) BUILDDIR=$(BUILDDIR) $(notdir $@) +%/install.data: + $(MAKE) -C $(dir $@) -f $(SRCDIR)/$(SUBDIR)/$(dir $@)Makefile \ + SRCDIR=$(SRCDIR) BUILDDIR=$(BUILDDIR) $(notdir $@) +%/install.merge: + $(MAKE) -C $(dir $@) -f $(SRCDIR)/$(SUBDIR)/$(dir $@)Makefile \ + SRCDIR=$(SRCDIR) BUILDDIR=$(BUILDDIR) $(notdir $@) +$(SUBDIRS:%=%/all): %/all: $(CURDIR)/% + $(MAKE) -C $(dir $@) -f $(SRCDIR)/$(SUBDIR)/$(dir $@)Makefile \ + SRCDIR=$(SRCDIR) BUILDDIR=$(BUILDDIR) $(notdir $@) +$(SUBDIRS:%=%/mergetrylist): %/mergetrylist: $(CURDIR)/% FORCE + $(MAKE) -C $(dir $@) -f $(SRCDIR)/$(SUBDIR)/$(dir $@)Makefile \ + SRCDIR=$(SRCDIR) BUILDDIR=$(BUILDDIR) $(notdir $@) +$(SUBDIRS:%=%/mergelist): %/mergelist: $(CURDIR)/% FORCE + $(MAKE) -C $(dir $@) -f $(SRCDIR)/$(SUBDIR)/$(dir $@)Makefile \ + SRCDIR=$(SRCDIR) BUILDDIR=$(BUILDDIR) $(notdir $@) +$(SUBDIRS:%=%/merge.o): %/merge.o: $(CURDIR)/% FORCE + $(MAKE) -C $(dir $@) -f $(SRCDIR)/$(SUBDIR)/$(dir $@)Makefile \ + SRCDIR=$(SRCDIR) BUILDDIR=$(BUILDDIR) $(notdir $@) +$(SUBDIRS:%=%/clean): %/clean: $(CURDIR)/% + $(MAKE) -C $(dir $@) -f $(SRCDIR)/$(SUBDIR)/$(dir $@)Makefile \ + SRCDIR=$(SRCDIR) BUILDDIR=$(BUILDDIR) $(notdir $@) +$(SUBDIRS:%=%/distclean): %/distclean: $(CURDIR)/% + $(MAKE) -C $(dir $@) -f $(SRCDIR)/$(SUBDIR)/$(dir $@)Makefile \ + SRCDIR=$(SRCDIR) BUILDDIR=$(BUILDDIR) $(notdir $@) +$(SUBDIRS:%=%/dep): %/dep: $(CURDIR)/% + $(MAKE) -C $(dir $@) -f $(SRCDIR)/$(SUBDIR)/$(dir $@)Makefile \ + SRCDIR=$(SRCDIR) BUILDDIR=$(BUILDDIR) $(notdir $@) + +#Here is the rule to create the subdirectories. If you're building in the +#source tree, they already exist, but in a separate build directory, they may +#not. + +ifneq ($(SUBDIR)x,x) +# This hack stops us from having a warning due to the same target twice +# when we're in the top level directory (because buildtools, etc are in +# SUBDIRS). + DIRS2 = $(BUILDDIR)/buildtools $(BUILDDIR)/lib $(BUILDDIR)/urt +endif + +$(SUBDIRS:%=$(CURDIR)/%) $(DIRS2): + mkdir $@ + + +# The automatic dependency generation is a pain in the butt and +# totally unnecessary for people just installing the distributed code, +# so to avoid needless failures in the field and a complex build, the +# rule to generate Makefile.depend automatically simply creates an +# empty file. A developer may do 'make dep' to create a +# Makefile.depend full of real dependencies. + +Makefile.depend: + cat /dev/null >Makefile.depend + +include Makefile.depend + +FORCE: diff --git a/Makefile.config.in b/Makefile.config.in new file mode 100644 index 00000000..84666cb1 --- /dev/null +++ b/Makefile.config.in @@ -0,0 +1,624 @@ +# This is a make file inclusion, to be included in all the Netpbm make +# files. + +# This file is meant to contain variable settings that customize the +# build for a particular target system configuration. + +# The distribution contains the file Makefile.config.in. You edit +# Makefile.config.in in ways relevant to your particular environment +# to create Makefile.config. The "configure" program will do this +# for you in simple cases. + +# Some of the variables that the including make file must set for this +# file to work: +# +# SRCDIR: The directory at the top of the Netpbm source tree. Note that +# this is typically a relative directory, and it must be relative to the +# make file that includes this file. + +DEFAULT_TARGET = nonmerge +#DEFAULT_TARGET = merge + +# Fiasco has some special requirements that make it fail to compile on +# some systems, and since it isn't very important, just set this to "N" +# and skip it on those systems unless you want to debug it and fix it. +# OpenBSD: +#BUILD_FIASCO = N +BUILD_FIASCO = Y + +# The following are commands for the build process to use. These values +# do not get built into anything. + +# The C compiler (including macro preprocessor) +#CC = gcc +# Note that 'cc' is usually an alias for whatever is the main compiler +# on a system, e.g. the GNU Compiler on Linux. +CC = cc + +# The linker. +LD = $(CC) +#LD = ld +#Tru64: +#LD = cc +#LD = gcc + +#If the linker identified above is a compiler that invokes a linker +#(as in 'cc foo.o -o foo'), set LINKERISCOMPILER. The main difference is +#that we expect a compiler to take linker options in the '-Wl,-opt1,val1' +#syntax whereas the actual linker would take '-opt1 val1'. +LINKERISCOMPILER=Y +#If $(LD) is 'ld': +#LINKERISCOMPILER=N + +#LINKER_CAN_DO_EXPLICIT_LIBRARY means the linker specified above can +#take a library as just another link object argument, as in 'ld +#pnmtojpeg.o /usr/local/lib/libjpeg.so ...' as opposed to requiring a +#-l option as in 'ld pnmtojpeg.o -L/usr/local/lib -l jpeg'. +#This variable controls how 'libopt' gets built. Note that with some +#linkers, you can specify a shared library explicitly, but then it has +#to live in that exact place at run time. That's not good enough for us. + +LINKER_CAN_DO_EXPLICIT_LIBRARY=N +#GNU: +#LINKER_CAN_DO_EXPLICIT_LIBRARY=Y + +# This is the name of the header file that declares the types +# uint32_t, etc. This name is used as #include $(INTTYPES_H) . +# Set to null if the types come automatically without including anything. + +# We have a report (2005.09.17) that on IRIX 5.3 with the native IDO +# cc, inttypes.h and sys/types.h conflict (and Netpbm programs include +# sys/types for other things), so for that environment, +# won't work, but "inttypes_netpbm.h" might. + +INTTYPES_H = +# Linux libc5: +#INTTYPES_H = +# Solaris: +# Solaris has , but it doesn't define int_fast2_t, etc. +#INTTYPES_H = "inttypes_netpbm.h" +# Others: +#INTTYPES_H = +#INTTYPES_H = +# The automatically generated Netpbm version: +#INTTYPES_H = "inttypes_netpbm.h" + +# HAVE_INT64 tells whether, assuming you include the header indicated by +# INTTYPES_H, you have the int64_t type and related stuff. (If you don't +# the build will omit certain code that does 64 bit computations). +HAVE_INT64 = Y +#HAVE_INT64 = N + +# CC and LD are for building the Netpbm programs, which are not necessarily +# intended to run on the same system on which Make is running. But when we +# build a build tool such as Libopt, it is meant to run only on the same +# system on which the Make is running. The variables below define programs +# to use to compile and link build tools. +CC_FOR_BUILD = $(CC) +LD_FOR_BUILD = $(LD) +CFLAGS_FOR_BUILD = $(CFLAGS) + +# MAKE is set automatically by Make to what was used to invoke Make. + +INSTALL = $(SRCDIR)/buildtools/install.sh +#Solaris: +#INSTALL = /usr/ucb/install +#Tru64: +#INSTALL = installbsd +#OSF1: +#INSTALL = $(SRCDIR)/buildtools/installosf +#Red Hat Linux: +#INSTALL = install + +# STRIPFLAG is the option you pass to the above install program to make it +# strip unnecessary information out of binaries. +STRIPFLAG = -s +# If you don't want to strip the binaries, just leave it null: +#STRIPFLAG = + +SYMLINK = ln -s +# At least some Windows environments don't have any concept of symbolic +# links, but direct copies are usually a passable alternative. +#SYMLINK = cp + +#MANPAGE_FORMAT is "nroff" or "cat". It determines in what format the +#pointer man pages are installed (ready to nroff, or ready to cat). +#A pointer man pages is just a single-paragraph pages that tells you there is +#no man page for the program, to look at the HTML documentation instead. +MANPAGE_FORMAT = nroff +#MANPAGE_FORMAT = cat + +AR = ar +RANLIB = ranlib +# IRIX, SCO don't have Ranlib: +#RANLIB = true + +# LEX is the beginning of a shell command that runs a Lex-like +# pattern matcher generator. Null string means there isn't any such +# command. That means the build will skip parts that need one. + +LEX = flex +# Solaris: +# LEX = flex -e +# Windows Mingw: +# LEX = +# +# LEX = lex + +# C compiler options + +# gcc: +# -ansi and -Werror should work too, but are not included +# by default because there's no point in daring the build to fail. +# -pedantic isn't a problem because it causes at worst a warning. +#CFLAGS = -O3 -ffast-math -pedantic -fno-common \ +# -Wall -Wno-uninitialized -Wmissing-declarations -Wimplicit \ +# -Wwrite-string -Wmissing-prototypes -Wundef +# The merged programs have a main_XXX subroutine instead of main(), +# which would cause a warning with -Wmissing-declarations or +# -Wmissing-prototypes. +#CFLAGS_MERGE = -Wno-missing-declarations -Wno-missing-prototypes +# A user of DEC Tru64 4.0F in May 2000 needed -DLONG_32 for ppmtompeg, +# but word size-sensitive code was removed from parallel.c in September 2004. +# A user of Tru64 5.1A in July 2003 needed NOT to have -DLONG_32. In +# theory, you need this if on your system, long is 32 bits and int is not. +# But it may be completely irrelevant today. +#Tru64: +#CFLAGS = -O2 -std1 -DLONG_32 +#CFLAGS = -O2 -std1 +#AIX: +#CFLAGS= -O3 +#HP-UX: +#CFLAGS= -O3 -fPIC +#IRIX: +#CFLAGS= -n32 -O3 +#Amiga with GNU compiler: +#CFLAGS= -m68020-60 -ffast-math -mstackextend +# You can add -noixemul for Amiga and successfully compile most of the +# programs. (Of the remaining ones, if you can supply your own strtod() +# function, most of them will build with -noixemul). So try building +# with 'make --keep-going CADD=-noixemul' first, then just 'make' to build +# everything that failed for lack of the ixemul library in the first step. +# That way, the parts that don't required the ixemul library won't indicate +# a dependency on it. +#OpenBSD: +#CFLAGS = -I/usr/local/include + +# EXE is a suffix that the linker puts on any executable it generates. +# In cygwin, this is .exe and most programs deal with its existence without +# us having to know about it. Some don't though, so set this: + +EXE = +#Cygwin, DJGPP/Windows: +#EXE = .exe + +# linker options. + +# LDFLAGS is often set as an environment variable; A setting here overrides +# it. So either make sure you want to override it, or do a "LDFLAGS +=" here. + +# LDFLAGS is usually not the right place for a -L option, because we put +# LDFLAGS _before_ our own -L options, so it would cancel out our +# specific selection of libraries. For example, if you say +# LDFLAGS=/usr/local/lib and an old copy of the libnetpbm is in +# /usr/local/lib, then you'd be linking against that old copy instead of +# the copy you just built, which is located by a -L option later on the +# link command. LIBS is the right variable for adding -L options. LIBS +# goes after any of our make files' own -L options. + +# Eunice users may want to use -noshare so that the executables can +# run standalone: +#LDFLAGS += -noshare +#Tru64: +# Russ Allberry says on 2001.06.09 that -oldstyle_liblookup may be necessary +# to keep from finding an ancient system libjpeg.so that isn't compatible with +# NetPBM. Michael Long found that /usr/local/lib is not in the default +# search path, or not soon enough, and he was getting an old libjpeg that +# caused all the jpeg symbol references to be unresolved. He had installed +# a new libjpeg in /usr/local/lib. +#LDFLAGS += -call_shared -oldstyle_liblookup -L/usr/local/lib +#AIX: +#LDFLAGS += -L /usr/pubsw/lib +#HP-UX: +#LDFLAGS += -Wl,+b,/usr/pubsw/lib +#IRIX: +#LDFLAGS += -n32 + +# Linker options for created Netpbm shared libraries. + +# Here, $(SONAME) resolves to the soname for the shared library being created. +# The following are gcc options. This works on GNU libc systems. +LDSHLIB = -shared -Wl,-soname,$(SONAME) +# You need -nostart instead of -shared on BeOS. Though the BeOS compiler is +# ostensibly gcc, it has the -nostart option, which is not mentioned in gcc +# documentation and doesn't exist in at least one non-BeOS installation. +# BeOS doesn't have sonames built in. +#LDSHLIB = -nostart +#LDSHLIB = -G +# Solaris, SunOS with GNU Ld, SCO: +# These systems have no soname option. +#LDSHLIB = -shared +# Solaris with Sun Ld: +#LDSHLIB = -Wl,-Bdynamic,-G,-h,$(SONAME) +#Tru64: +#LDSHLIB = -shared -expect_unresolved "*" +#IRIX: +#LDSHLIB = -shared -n32 +#AIX GNU compiler/linker: +#LDSHLIB = -shared +#AIX Visual Age C: +#LDSHLIB = -qmkshrobj + +# LDRELOC is the command to combine two .o files (relocateable object files) +# into a single .o file that can later be linked into something else. NONE +# means no such command is available. + +LDRELOC = NONE +# GNU Ld: +# Older GNU Ld misspells the option as --relocateable. Newer GNU Ld +# correctly spells it --relocatable. The abbreviation --reloc works on +# both. +#LDRELOC = ld --reloc +#LDRELOC = ld -r + + +# On older systems, you have to make shared libraries out of position +# independent code, so you need -fpic or fPIC here. (The rule is: if +# -fpic works, use it. If it bombs, go to fPIC). On newer systems, +# it isn't necessary, but can save real memory at the expense of +# execution speed. Without position independent code, the library +# loader may have to patch addresses into the executable text. On an +# older system, this would cause a program crash because the loader +# would be writing into read-only shared memory. But on newer +# systems, the system silently creates a private mapping of the page +# or segment being modified (the "copy on write" phenomenon). So it +# needs its own private real page frame. In one experiment, A second +# copy of Pbmtext used 16K less real memory when built with -fpic than +# when built without. 2001.06.02. + +# We have seen -fPIC required on IA64 and AMD64 machines (GNU +# compiler/linker). Build-time linking fails without it. I don't +# know why -- history seems to be repeating itself. 2005.02.23. + +CFLAGS_SHLIB = +# Solaris or SunOS with gcc, and NetBSD: +#CFLAGS_SHLIB = -fpic +#CFLAGS_SHLIB = -fPIC +# Sun compiler: +#CFLAGS_SHLIB = -Kpic +#CFLAGS_SHLIB = -KPIC + +# SHLIB_CLIB is the link option to include the C library in a shared library, +# normally "-lc". On typical systems, this serves no purpose. On some, +# though, it causes information about which C library to use to be recorded +# in the shared library and thus choose the correct library among several or +# avoid using an incompatible one. But on some systems, the link fails. +# On 2002.09.30, "John H. DuBois III" reports that on +# SCO OpenServer, he gets the following error message with -lc: +# +# -lc; relocations referenced ; from file(s) /usr/ccs/lib/libc.so(random.o); +# fatal error: relocations remain against allocatable but non-writable +# section: ; .text + +SHLIB_CLIB = -lc +# SCO: +SHLIB_CLIB = + +# On some systems you have to build into an executable the list of +# directories where its dynamically linked libraries can be found at +# run time. This is typically done with a -R or -rpath linker +# option. Even on systems that don't require it, you might prefer to do +# that rather than set up environment variables or configuration files +# to tell the system where the libraries are. A "Y" here means to put +# the directory information in the executable at link time. + +NEED_RUNTIME_PATH = N +# Solaris, SunOS, NetBSD, AIX: +#NEED_RUNTIME_PATH = Y + +# RPATHOPTNAME is the option you use on the link command to specify +# a runtime search path for a shared library. It is meaningless unless +# NEED_RUNTIME_PATH is Y. +RPATHOPTNAME = -rpath + +# The following variables tell where your various libraries on which +# Netpbm depends live. The LIBxxx variable is a full file +# specification of the link library (not necessarily the library used +# at run time). e.g. "/usr/local/lib/graphics/libjpeg.so". It usually +# doesn't matter if the library prefix and suffix are right -- you can +# use "lib" and ".so" or ".a" regardless of what your system actually +# uses because these just turn into "-L" and "-l" linker options +# anyway. ".a" implies a static library for some purposes, though. +# If you don't have the library in question, use a value of NONE for +# LIBxxx and the build will simply skip the programs that require that +# library. If the library is in your linker's (or the Netpbm build's) +# default search path, leave off the directory part, e.g. "libjpeg.so". + +# The xxxHDR_DIR variable is the directory in which the interface +# headers for the library live (e.g. /usr/include). If they are in your +# compiler's default search path, set this variable to null. + +# This is where the Netpbm shared libraries will reside when Netpbm is +# fully installed. In some configurations, the Netpbm builder builds +# this information into the Netpbm executables. This does NOT affect +# where the Netpbm installer installs the libraries. A null value +# means the libraries are in a default search path used by the runtime +# library loader. +NETPBMLIB_RUNTIME_PATH = +#NETPBMLIB_RUNTIME_PATH = /usr/lib/netpbm + +# The TIFF library. See above. If you want to build the tiff +# converters, you must have the tiff library already installed. + +TIFFLIB = NONE +TIFFHDR_DIR = + +#TIFFLIB = libtiff.so +#TIFFHDR_DIR = /usr/include/libtiff +#NetBSD: +#TIFFLIB = $(LOCALBASE)/lib/libtiff.so +#TIFFHDR_DIR = $(LOCALBASE)/include +# OSF, Tru64: +#TIFFLIB = /usr/local1/DEC/lib/libtiff.so +#TIFFHDR_DIR = /usr/local1/DEC/include + +# Some TIFF libraries do Jpeg and/or Z (flate) compression and thus any +# program linked with the TIFF library needs a Jpeg and/or Z library. +# Some TIFF libraries have such library statically linked in, but others +# need it to be dynamically linked at program load time. +# Make this 'N' if youf TIFF library doesn't need such dynamic linking. +# As of 2005.01, the most usual build of the TIFF library appears to require +# both. +TIFFLIB_NEEDS_JPEG = Y +TIFFLIB_NEEDS_Z = Y + +# The JPEG library. See above. If you want to build the jpeg +# converters you must have the jpeg library already installed. + +# Tiff files can use JPEG compression, so the Tiff library can reference +# the JPEG library. If your Tiff library references a dynamic JPEG +# library, you must specify at least JPEGLIB here, or the Tiff +# converters will not build. Note that your Tiff library may have the +# JPEG stuff statically linked in, in which case you won't need +# JPEGLIB in order to build the Tiff converters. + +JPEGLIB = NONE +JPEGHDR_DIR = +#JPEGLIB = libjpeg.so +#JPEGHDR_DIR = /usr/include/jpeg +# Netbsd: +#JPEGLIB = ${LOCALBASE}/lib/libjpeg.so +#JPEGHDR_DIR = ${LOCALBASE}/include +# OSF, Tru64: +#JPEGLIB = /usr/local1/DEC/libjpeg.so +#JPEGHDR_DIR = /usr/local1/DEC/include +# Typical: +#JPEGLIB = /usr/local/lib/libjpeg.so +#JPEGHDR_DIR = /usr/local/include +# Don't build JPEG stuff: +#JPEGLIB = NONE + + +# The PNG library. See above. If you want to build the PNG +# converters you must have the PNG library already installed. + +# The PNG library, by convention starting around April 2002, gets installed +# with names that include a version number, such as libpng10.a and header +# files in /usr/include/libpng10. But there is conventionally an unnumbered +# alias (e.g. libpng.a, /usr/include/libpng) for the preferred version. +# +# Recent versions of the library (since some time in the 2002-2006 period) +# have an associated 'libpng-config' that tells how to link it. The make +# files will use that program if it exists (must be in the PATH). In that +# case, PNGLIB and PNGHDR_DIR are irrelevant, but PNGVER is still meaningful, +# because the make file runs 'libpng$(PNGVER)-config'. + +PNGLIB = NONE +PNGHDR_DIR = +PNGVER = +#PNGLIB = libpng$(PNGVER).so +#PNGHDR_DIR = /usr/include/libpng$(PNGVER) +# NetBSD: +#PNGLIB = $(LOCALBASE)/lib/libpng$(PNGVER).so +#PNGHDR_DIR = $(LOCALBASE)/include +# OSF/Tru64: +#PNGLIB = /usr/local1/DEC/lib/libpng$(PNGVER).so +#PNGHDR_DIR = /usr/local1/DEC/include + +# The zlib compression library. See above. You need it to build +# anything that needs the PNG library (see above). If you selected +# NONE for the PNG library, it doesn't matter what you specify here -- +# it won't get used. +# +# If you have 'libpng-config' (see above), these are irrelevant. + +ZLIB = NONE +ZHDR_DIR = +#ZLIB = libz.so + +# The JBIG lossless image compression library (aka JBIG-KIT): + +JBIGLIB = $(BUILDDIR)/converter/other/jbig/libjbig.a +JBIGHDR_DIR = $(SRCDIR)/converter/other/jbig + +# The Jasper JPEG-2000 image compression library (aka JasPer): +JASPERLIB = $(INTERNAL_JASPERLIB) +JASPERHDR_DIR = $(INTERNAL_JASPERHDR_DIR) +# JASPERDEPLIBS is the libraries (-l options or file names) on which +# The Jasper library depends -- i.e. what you have to link into any +# executable that links in the Jasper library. +JASPERDEPLIBS = +#JASPERDEPLIBS = -ljpeg + +# And the Utah Raster Toolkit (aka URT aka RLE) library: + +URTLIB = $(BUILDDIR)/urt/librle.a +URTHDR_DIR = $(SRCDIR)/urt + +# The X11 library has facilities for talking to an X Window System +# server. It is required by Pamx. + +X11LIB = NONE +X11HDR_DIR = + +#X11LIB = /usr/lib/libX11.so +#X11HDR_DIR = + +# The Linux SVGA library (Svgalib) is a facility for displaying graphics +# on the Linux console. It is required by Ppmsvgalib. + +LINUXSVGALIB = NONE +LINUXSVGAHDR_DIR = + +#LINUXSVGALIB = /usr/lib/libvga.so +#LINUXSVGAHDR_DIR = /usr/include/vgalib + +# If you don't want any network functions, set OMIT_NETWORK to "y". +# The only thing that requires network functions is the option in +# ppmtompeg to run it on multiple computers simultaneously. On some +# systems network functions don't work or we haven't figured out how to +# make them work, or they just aren't worth the effort. +OMIT_NETWORK = +#DJGPP/Windows, Tru64: +# (there's some minor header problem that prevents network functions from +# building on Tru64 2000.10.06) +#OMIT_NETWORK = y + +# These are -l options to link in the network libraries. Often, these are +# built into the standard C library, so this can be null. This is irrelevant +# if OMIT_NETWORK is "y". + +NETWORKLD = +# Solaris, SunOS: +#NETWORKLD = -lsocket -lnsl +# SCO: +#NETWORKLD = -lsocket, -lresolv + +VMS = +#VMS: +#VMS = yes + +# DONT_HAVE_PROCESS_MGMT is Y if this system doesn't have the usual +# Unix process management stuff - fork, wait, etc. N for a regular Unix +# system. +DONT_HAVE_PROCESS_MGMT = N + +# The following variables are used only by 'make install' (and the +# variants of it). Paths here don't, for example, get built into any +# programs. + +# This is where everything goes when you do 'make package', unless you +# override it by setting 'pkgdir' on the Make command line. +PKGDIR_DEFAULT = /tmp/netpbm + +# Subdirectory of the package directory ($(pkgdir)) in which man pages +# go. +PKGMANDIR = man + +# File permissions for installed files. +# Note that on some systems (e.g. Solaris), 'install' can't use the +# mnemonic permissions - you have to use octal. + +# binaries (pbmmake, etc) +INSTALL_PERM_BIN = 755 # u=rwx,go=rx +# shared libraries (libpbm.so, etc) +INSTALL_PERM_LIBD = 755 # u=rwx,go=rx +# static libraries (libpbm.a, etc) +INSTALL_PERM_LIBS = 644 # u=rw,go=r +# header files (pbm.h, etc) +INSTALL_PERM_HDR = 644 # u=rw,go=r +# man pages (pbmmake.1, etc) +INSTALL_PERM_MAN = 644 # u=rw,go=r +# data files (pnmtopalm color maps, etc) +INSTALL_PERM_DATA = 644 # u=rw,go=r + +# Specify the suffix that want the man pages to have. + +SUFFIXMANUALS1 = 1 +SUFFIXMANUALS3 = 3 +SUFFIXMANUALS5 = 5 + +#NETPBMLIBTYPE tells the kind of libraries that will get built to hold the +#Netpbm library functions. The value is used only in make file tests. +# "unixshared" means a unix-style shared library, typically named like +# libxyz.so.2.3 +NETPBMLIBTYPE = unixshared +# "unixstatic" means a unix-style static library, (like libxyz.a) +#NETPBMLIBTYPE = unixstatic +# "dll" means a Windows DLL shared library +#NETPBMLIBTYPE = dll +# "dylib" means a Darwin/Mac OS shared library +#NETPBMLIBTYPE = dylib + +#NETPBMLIBSUFFIX is the suffix used on whatever kind of library is +#selected above. All this is used for is to construct library names. +#The make files never examine the actual value. +NETPBMLIBSUFFIX = so + +# "a" is the suffix for unix-style static libraries. It is also +# traditionally used for shared libraries on AIX. The Visual Age C +# manual says sometimes .so works on AIX, and GNU software for AIX +# 5.1.0 does indeed use it. In our experiments, it works fine if you +# name the library file explicitly on the link, but isn't in the -l +# search order. If you name the library explicitly on the link, the +# library must live in exactly the same position at run time, so we +# can't use that. Therefore, you cannot build both static and shared +# libraries with AIX. You have to choose. +#NETPBMLIBSUFFIX = a +# For HP-UX shared libraries: +#NETPBMLIBSUFFIX = sl +# Darwin/Mac OS shared library: +#NETPBMLIBSUFFIX = dylib +# Windows shared library: +#NETPBMLIBSUFFIX = dll + +#STATICLIB_TOO is "y" to signify that you want a static library built +#and installed in addition to whatever library type you specified by +#NETPBMLIBTYPE. If NETPBMLIBTYPE specified a static library, +#STATICLIB_TOO simply has no effect. +STATICLIB_TOO = y +#STATICLIB_TOO = n + +#STATICLIBSUFFIX is the suffix that static libraries have. It's +#meaningless if you aren't building static libraries. +STATICLIBSUFFIX = a + +#SHLIBPREFIXLIST is a blank-delimited list of prefixes that a filename +#of a shared library may have on this system. Traditionally, it's +#just "lib", as in libc or libnetpbm. On Windows, though, varying +#prefixes are used when multiple alternative forms of a library are +#available. The first prefix in this list is what we use to name the +#Netpbm shared libraries. +# +# This variable controls how 'libopt' gets built. +# +SHLIBPREFIXLIST = lib +#Cygwin: +#SHLIBPREFIXLIST = cyg lib + +NETPBMSHLIBPREFIX = $(firstword $(SHLIBPREFIXLIST)) + +#DLLVER is used to version the DLLs built on cygwin or other +#windowsish platforms. We can't add this to LIBROOT, or we'd +#version the static libs (which is bad). We can't add this +#at the end of the name (like unix does with so numbers) because +#windows will only load dlls whose name ends in "dll". So, +#we have this variable, which becomes the end of the library "root" name +#for DLLs only. +# +# This variable controls how 'libopt' gets built. +# +DLLVER = +#Cygwin +#DLLVER = $(NETPBM_MAJOR_RELEASE) + +#NETPBM_DOCURL is the URL of the main documentation page for Netpbm. +#This is a directory which contains a file for each Netpbm program, +#library, and file type. E.g. The documentation for jpegtopnm might be in +#http://netpbm.sourceforge.net/doc/jpegtopnm.html . This value gets +#installed in the man pages (which say no more than to read the webpage) +#and in the Webman netpbm.url file. +NETPBM_DOCURL = http://netpbm.sourceforge.net/doc/ +#For a system with no web access, but a local copy of the doc: +#NETPBM_DOCURL = file:/usr/doc/netpbm/ + diff --git a/Makefile.srcdir b/Makefile.srcdir new file mode 100644 index 00000000..6a21d9db --- /dev/null +++ b/Makefile.srcdir @@ -0,0 +1 @@ +SRCDIR = $(CURDIR) diff --git a/README b/README new file mode 100644 index 00000000..ece3a32d --- /dev/null +++ b/README @@ -0,0 +1,213 @@ + + NETPBM + + +THIS IS THE PRIMARY DOCUMENTATION DISTRIBUTED WITH NETPBM. SEE THE doc +DIRECTORY IN THE SOURCE TREE FOR OTHER INFORMATION, SUCH AS INSTALLATION +INSTRUCTIONS, AND SEE . + +Netpbm is a toolkit for manipulation of graphic images, including +conversion of images between a variety of different formats. There +are over 300 separate tools in the package including converters for +about 100 graphics formats. Examples of the sort of image +manipulation we're talking about are: Shrinking an image by 10%; +Cutting the top half off of an image; Making a mirror image; Creating +a sequence of images that fade from one image to another; + +For more information on what the package does, see +. + +The package is intended to be portable to many platforms. It has, at +least at one time, been tested under various Unix-based systems, +Windows, Mac OS X, VMS and Amiga OS. The maintainer uses and builds +it on a platform that consists (in relevant part) mainly of GNU +software (you probably know this kind of system by the name "Linux"). + +The goal of Netpbm is to be a single source for all the primitive +graphics utilities, especially converters, one might need. So if you +know of some freely redistributable software in this vein which is not +in the package yet, you should bring it to the attention of the Netpbm +maintainer so it can be included in the next release. + +Netpbm does not contain interactive tools and doesn't have a graphical +interface. + +Netpbm replaces the widely spread Pbmplus package (last released +December 10, 1991). A lot of improvements and additions have been +made. After the latest release of Pbmplus, a lot of additional +filters began circulating on the net, which was a fairly novel state +of affairs at the time. The aim of Netpbm was to collect these and to +turn them into a package, hence the name "Netpbm." This work has been +performed by programmers all over the world. If _you_ have some code +to add, please contact the Netpbm maintainer. + + +USING NETPBM IN A WEBSITE +------------------------- + +Many people use Netpbm to perform graphics functions in a web site. They +have CGI scripts that invoke Netpbm programs to process images for display +on a web page. Gallery and 4Images are two web site software packages +that rely on Netpbm for graphics manipulation. + +Installing Netpbm requires different skills and system access than +installing most other web site software. You must be able to compile +C code for the web server machine and have a basic understanding of +how files are organized and programs run on the web server. Diagnosing +inevitable problems usually requires shell access to the web server. + +Netpbm is basic graphics software that ought to be supplied by any +web hosting service. If it isn't on your web server already, you should +request that the system administrator add it. + +The Gallery project provides an easy install package for the parts of +Netpbm that Gallery needs, and provides technical support at: + + http://gallery.sourceforge.net/forums.php + + +DISTRIBUTION +------------ + +You'll find the latest release of Netpbm source code at +. + +The user manual is not in the source code package. It is available online +at and you can download it from there. +See the file doc/USERDOC for details. + +A list of prebuilt Netpbm distributions is on the Netpbm +website, . + + +PREREQUISITES +------------- + +Don't sweat the prerequisites too much. In most cases, if you're +missing something, the build of the programs that depend on it will +bomb, but the rest of the Netpbm programs will build just fine. And +you may not need the more demanding programs. + +If you have trouble getting, building, or installing the +prerequisites, the Netpbm maintainer wants to know. Since he uses +them himself, he can help you. And if there is a problem with a +prerequisite package that its own maintainer cannot fix, it may be +possible to ship a fix with Netpbm. + +To build and install Netpbm, you need GNU Make and a Perl interpreter. +You can get GNU Make from http://www.gnu.org/software and Perl from +http://www.cpan.org. It's possible to get around the Perl requirement +by running some of the steps on a different machine that has Perl and +doing others manually. There is no practical substitute for GNU Make. + +To build pnmtotiff or tifftopnm or pnmtotiffcmyk, you need the Tiff +library. You can get it from http://www.libtiff.org. + +To build ppmtojpeg or jpegtopnm, you need the JPEG/JFIF library from +the Independent JPEG Group (IJG). You can get it at +ftp://ftp.uu.net/graphics/jpeg. See http://www.ijg.org for more +information. You need Release 6b or better. With earlier releases, Netpbm +build fails with undefined jpeg symbols. The basic JPEG library installation +procedure installs only the runtime part of the package -- you nee the +development part as well, so run 'make install-lib'. The JPEG library +documentation erroneously calls this installing "the library itself." +This apparently was written before shared libraries. With shared libraries, +"the library itself" is part of the runtime installation, but install-lib +still installs the compile-time stuff you need. + +You may also need the JPEG library to build the Tiff converters. If +your Tiff library references a shared JPEG library, then you do. The +Tiff library may also include a static copy of the JPEG library, in +which case you won't need a separate JPEG library. Or it may have +been built without any JPEG compression capability, in which case you +won't need a separate JPEG library, but the Tiff converters won't be +able to handle Tiff with JPEG compression. + +The same goes for Ppmtompeg. You need the jpeg library if you want to +create MPEGs from JPEGs (without the loss of quality that comes with +converting from JPEG to PPM first), and if you don't have the JPEG +library and don't say so in Makefile.config, you won't be able to +build Ppmtompeg at all. + +To build or use Pnmtopng and Pngtopnm, you need the Zlib compression +library and the PNG library (libpng). You can get Zlib from +ftp://quest.jpl.nasa.gov/pub/zlib or +ftp://metalab.unc.edu/pub/Linux/libs. You can get libpng from +http://www.libpng.org/pub/png/libpng.html or +http://libpng.sourceforge.net. Older libpng won't work -- you get +unresolved external references to png_sig_cmp and png_set_sig_bytes. + +You may also need the Zlib library to build the Tiff converters, in +the same way as the Tiff converters require the JPEG libraries, as +explained above. + +Pstopnm (the Postscript to PNM image converter) requires Ghostscript +(installed with the name 'gs' in your command search path). And it +requires in particular that Ghostscript be built with the relevant +PNM device drivers. See http://www.ghostscript.com/doc/GPL/ . + +The Utah Raster Toolkit is not a prerequisite because Netpbm includes +a subset of it that meets the needs of Pnmtorle and Rletopnm. +However, you can also substitute the real package by properly +configuring Makefile.config. You can get it from +ftp://ftp.cs.utah.edu/pub/dept/OLD/pub/urt-3.1b.tar.Z. There's a +patch at ftp://ptolemy.berkeley.edu/pub/misc/urt/urt-3.1b-3.1b1.patch + +You generally need a compiler other than Gcc 2.96. Gcc 2.96 has a bug +in its inlining optimization. It generates incorrect code. Netpbm +source code takes advantage of inlining and you normally build Netpbm +with inlining enabled. Therefore, if you use Gcc 2.96 you will get +broken Netpbm programs. The usual symptom is bogus syntax error +messages when you run the program. You can avoid this compiler bug by +using a -O0 compile option instead of the usual -O3. The automatic +configuration program will usually detect that you need this and set +it up for you. This will make some programs noticeably slower, +though. + +Netpbm requires about 3.5 MiB of disk space, not including documentation. +The documentation is 1.1 MiB, but you don't necessarily have to install +it; you can just access the public copy. + + +INSTALLATION +------------ + +See doc/INSTALL. + + +SUPPORT +------- + +The maintainer of Netpbm, since September 1999, is Bryan Henderson: + + bryanh@giraffe-data.com. + +If for some reason that email address doesn't work, you can reach +Bryan at giraffedata@yahoo.com as a backup. Please don't mail to +both at the same time. Bryan doesn't need two copies of your email. + +Bryan actively maintains the package and wants to know about any bugs +or problems people have with Netpbm or suggestions for improvement. + +There is no bug reporting database or mailing list. These would not +be very useful with Netpbm because Bryan personally responds to all +bug reports and requests for help immediately. All known bugs in the +"latest" release are listed in its release notes on Sourceforge +(updated as the bugs are reported) and the "stable" release is +generally maintained so as not to have known bugs for more than a few +days. The doc/HISTORY file in the package may be useful if you want +to find out whether upgrading to the current release would solve your +problem. The information in that file, on a per-release basis, is +also in the change histories on Sourceforge. + + + +MORE INFORMATION, DOCUMENTATION +------------------------------- + +For more information about Netpbm, see . + +The 'doc' directory in the source tree has more information. + +A good place to start for information about the wide world of computer +graphics is http://www.faqs.org/faqs/graphics/ . diff --git a/analyzer/Makefile b/analyzer/Makefile new file mode 100644 index 00000000..6a447ea7 --- /dev/null +++ b/analyzer/Makefile @@ -0,0 +1,48 @@ +ifeq ($(SRCDIR)x,x) + SRCDIR = $(CURDIR)/.. + BUILDDIR = $(SRCDIR) +endif +SUBDIR = analyzer +VPATH=.:$(SRCDIR)/$(SUBDIR) + +include $(BUILDDIR)/Makefile.config + +# We tend to separate out the build targets so that we don't have +# any more dependencies for a given target than it really needs. +# That way, if there is a problem with a dependency, we can still +# successfully build all the stuff that doesn't depend upon it. +# This package is so big, it's useful even when some parts won't +# build. + +PORTBINARIES = pamfile pamslice pamsumm pamtilt \ + pgmhist pnmhistmap ppmhist pgmminkowski +MATHBINARIES = pamsharpmap pamsharpness pgmtexture pnmpsnr + +BINARIES = $(PORTBINARIES) $(MATHBINARIES) +SCRIPT = + +OBJECTS = $(BINARIES:%=%.o) + +# We don't include programs that have special library dependencies in the +# merge scheme, because we don't want those dependencies to prevent us +# from building all the other programs. + +MERGEBINARIES = $(BINARIES) +MERGE_OBJECTS = $(MERGEBINARIES:%=%.o2) + +.PHONY: all +all: $(BINARIES) + +include $(SRCDIR)/Makefile.common + +install.bin: install.bin.local +.PHONY: install.bin.local +install.bin.local: $(PKGDIR)/bin +# Remember that $(SYMLINK) might just be a copy command. + cd $(PKGDIR)/bin ; \ + $(SYMLINK) pamslice$(EXE) pgmslice + cd $(PKGDIR)/bin ; \ + $(SYMLINK) pamfile$(EXE) pnmfile + +FORCE: + diff --git a/analyzer/pamfile.c b/analyzer/pamfile.c new file mode 100644 index 00000000..efb2cbee --- /dev/null +++ b/analyzer/pamfile.c @@ -0,0 +1,243 @@ +/* pamfile.c - describe a portable anymap +** +** Copyright (C) 1991 by Jef Poskanzer. +** +** Permission to use, copy, modify, and distribute this software and its +** documentation for any purpose and without fee is hereby granted, provided +** that the above copyright notice appear in all copies and that both that +** copyright notice and this permission notice appear in supporting +** documentation. This software is provided "as is" without express or +** implied warranty. +*/ + +#include "mallocvar.h" +#include "nstring.h" +#include "shhopt.h" +#include "pam.h" + +struct cmdlineInfo { + /* All the information the user supplied in the command line, + in a form easy for the program to use. + */ + int inputFileCount; /* Number of input files */ + const char ** inputFilespec; /* Filespecs of input files */ + unsigned int allimages; /* -allimages or -count */ + unsigned int count; /* -count */ + unsigned int comments; /* -comments */ +}; + + + +static void +parseCommandLine(int argc, char ** argv, + struct cmdlineInfo * const cmdlineP) { +/*---------------------------------------------------------------------------- + Note that the file spec array we return is stored in the storage that + was passed to as as the argv array. +-----------------------------------------------------------------------------*/ + optEntry * option_def; + /* Instructions to optParseOptions3 on how to parse our options. + */ + optStruct3 opt; + + unsigned int option_def_index; + + MALLOCARRAY_NOFAIL(option_def, 100); + + option_def_index = 0; /* incremented by OPTENT3 */ + OPTENT3(0, "allimages", OPT_FLAG, NULL, &cmdlineP->allimages, 0); + OPTENT3(0, "count", OPT_FLAG, NULL, &cmdlineP->count, 0); + OPTENT3(0, "comments", OPT_FLAG, NULL, &cmdlineP->comments, 0); + + opt.opt_table = option_def; + opt.short_allowed = FALSE; /* We have no short (old-fashioned) options */ + opt.allowNegNum = FALSE; /* We have no parms that are negative numbers */ + + optParseOptions3(&argc, argv, opt, sizeof(opt), 0); + /* Uses and sets argc, argv, and some of *cmdlineP and others */ + + cmdlineP->inputFilespec = (const char **)&argv[1]; + cmdlineP->inputFileCount = argc - 1; +} + + + +static void +dumpHeader(struct pam const pam) { + + switch (pam.format) { + case PAM_FORMAT: + printf("PAM, %d by %d by %d maxval %ld\n", + pam.width, pam.height, pam.depth, pam.maxval); + printf(" Tuple type: %s\n", pam.tuple_type); + break; + + case PBM_FORMAT: + printf("PBM plain, %d by %d\n", pam.width, pam.height ); + break; + + case RPBM_FORMAT: + printf("PBM raw, %d by %d\n", pam.width, pam.height); + break; + + case PGM_FORMAT: + printf("PGM plain, %d by %d maxval %ld\n", + pam.width, pam.height, pam.maxval); + break; + + case RPGM_FORMAT: + printf("PGM raw, %d by %d maxval %ld\n", + pam.width, pam.height, pam.maxval); + break; + + case PPM_FORMAT: + printf("PPM plain, %d by %d maxval %ld\n", + pam.width, pam.height, pam.maxval); + break; + + case RPPM_FORMAT: + printf("PPM raw, %d by %d maxval %ld\n", + pam.width, pam.height, pam.maxval); + break; + } +} + + + +static void +dumpComments(const char * const comments) { + + const char * p; + bool startOfLine; + + printf("Comments:\n"); + + for (p = &comments[0], startOfLine = TRUE; *p; ++p) { + if (startOfLine) + printf(" #"); + + fputc(*p, stdout); + + if (*p == '\n') + startOfLine = TRUE; + else + startOfLine = FALSE; + } + if (!startOfLine) + fputc('\n', stdout); +} + + + +static void +doOneImage(const char * const name, + unsigned int const imageDoneCount, + FILE * const fileP, + bool const allimages, + bool const justCount, + bool const wantComments, + bool * const eofP) { + + struct pam pam; + const char * comments; + enum pm_check_code checkRetval; + + pam.comment_p = &comments; + + pnm_readpaminit(fileP, &pam, PAM_STRUCT_SIZE(comment_p)); + + if (!justCount) { + if (allimages) + printf("%s:\tImage %d:\t", name, imageDoneCount); + else + printf("%s:\t", name); + + dumpHeader(pam); + if (wantComments) + dumpComments(comments); + } + strfree(comments); + + pnm_checkpam(&pam, PM_CHECK_BASIC, &checkRetval); + if (allimages) { + tuple * tuplerow; + unsigned int row; + + tuplerow = pnm_allocpamrow(&pam); + + for (row = 0; row < pam.height; ++row) + pnm_readpamrow(&pam, tuplerow); + + pnm_freepamrow(tuplerow); + + pnm_nextimage(fileP, eofP); + } +} + + + +static void +describeOneFile(const char * const name, + FILE * const fileP, + bool const allimages, + bool const justCount, + bool const wantComments) { +/*---------------------------------------------------------------------------- + Describe one image stream (file). Its name, for purposes of display, + is 'name'. The file is open as *fileP and positioned to the beginning. + + 'allimages' means report on every image in the stream and read all of + every image from it, as opposed to reading just the header of the first + image and reporting just on that. + + 'justCount' means don't tell anything about the stream except how + many images are in it. Pretty useless without 'allimages'. + + 'wantComments' means to show the comments from the image header. + Meaningless with 'justCount'. +-----------------------------------------------------------------------------*/ + unsigned int imageDoneCount; + /* Number of images we've processed so far */ + bool eof; + + eof = FALSE; + imageDoneCount = 0; + + while (!eof && (imageDoneCount < 1 || allimages)) { + doOneImage(name, imageDoneCount, fileP, + allimages, justCount, wantComments, + &eof); + ++imageDoneCount; + } + if (justCount) + printf("%s:\t%u images\n", name, imageDoneCount); +} + + + +int +main(int argc, char *argv[]) { + + struct cmdlineInfo cmdline; + + pnm_init(&argc, argv); + + parseCommandLine(argc, argv, &cmdline); + + if (cmdline.inputFileCount == 0) + describeOneFile("stdin", stdin, cmdline.allimages || cmdline.count, + cmdline.count, cmdline.comments); + else { + unsigned int i; + for (i = 0; i < cmdline.inputFileCount; ++i) { + FILE * ifP; + ifP = pm_openr(cmdline.inputFilespec[i]); + describeOneFile(cmdline.inputFilespec[i], ifP, + cmdline.allimages || cmdline.count, + cmdline.count, cmdline.comments); + pm_close(ifP); + } + } + + return 0; +} diff --git a/analyzer/pamsharpmap.c b/analyzer/pamsharpmap.c new file mode 100644 index 00000000..73923ab9 --- /dev/null +++ b/analyzer/pamsharpmap.c @@ -0,0 +1,188 @@ +/*---------------------------------------------------------------------------- + Pnmsharpness +------------------------------------------------------------------------------ + + Bryan Henderson derived this (January 2004) from the program Pnmsharp + by B.W. van Schooten and distributed to Bryan under the Perl + Artistic License, as part of the Photopnmtools package. Bryan placed + his modifications in the public domain. + + This is the copyright/license notice from the original: + + Copyright (c) 2002, 2003 by B.W. van Schooten. All rights reserved. + This software is distributed under the Perl Artistic License. + No warranty. See file 'artistic.license' for more details. + + boris@13thmonkey.org + www.13thmonkey.org/~boris/photopnmtools/ +-----------------------------------------------------------------------------*/ + +#include +#include + +#include "pam.h" +#include "shhopt.h" +#include "mallocvar.h" + +struct cmdlineInfo { + /* All the information the user supplied in the command line, + in a form easy for the program to use. + */ + const char *inputFilespec; /* '-' if stdin */ + unsigned int context; +}; + + + +static void +parseCommandLine ( int argc, char ** argv, + struct cmdlineInfo *cmdlineP ) { +/*---------------------------------------------------------------------------- + parse program command line described in Unix standard form by argc + and argv. Return the information in the options as *cmdlineP. + + If command line is internally inconsistent (invalid options, etc.), + issue error message to stderr and abort program. + + Note that the strings we return are stored in the storage that + was passed to us as the argv array. We also trash *argv. +-----------------------------------------------------------------------------*/ + optEntry *option_def = malloc(100*sizeof(optEntry)); + /* Instructions to optParseOptions3 on how to parse our options. + */ + optStruct3 opt; + + unsigned int option_def_index; + + unsigned int contextSpec; + + option_def_index = 0; /* incremented by OPTENT3 */ + OPTENT3(0, "context", OPT_UINT, &cmdlineP->context, + &contextSpec, 0 ); + + opt.opt_table = option_def; + opt.short_allowed = FALSE; /* We have no short (old-fashioned) options */ + opt.allowNegNum = FALSE; /* We have no parms that are negative numbers */ + + optParseOptions3( &argc, argv, opt, sizeof(opt), 0); + /* Uses and sets argc, argv, and some of *cmdlineP and others. */ + + if (!contextSpec) + cmdlineP->context = 1; + + if (cmdlineP->context < 1) + pm_error("-context must be at least 1"); + + + if (argc-1 > 1) + pm_error("The only argument is the input file name"); + else if (argc-1 < 1) + cmdlineP->inputFilespec = "-"; + else + cmdlineP->inputFilespec = argv[1]; +} + + + +static void +makeSharpnessPixel(struct pam * const pamP, + float * const sharpness, + tuple const sharpnessTuple) { + + unsigned int plane; + for (plane = 0; plane < pamP->depth; ++plane) + sharpnessTuple[plane] = + (sample)(sharpness[plane] * pamP->maxval + 0.5); +} + + + +static void +makeBlackTuplen(struct pam * const pamP, + tuplen const tuplen) { + + unsigned int plane; + for (plane = 0; plane < pamP->depth; ++plane) + tuplen[plane] = 0.0; +} + + + +static void +makeBlackRown(struct pam * const pamP, + tuplen * const tuplenrow) { + + unsigned int col; + for (col = 0; col < pamP->width; ++col) + makeBlackTuplen(pamP, tuplenrow[col]); +} + + + +int +main(int argc, char **argv) { + + struct cmdlineInfo cmdline; + FILE * ifP; + tuplen ** tuplenarray; + struct pam inpam; + struct pam mappam; + tuple ** map; + int row; + float * sharpness; + + pnm_init(&argc, argv); + + parseCommandLine(argc, argv, &cmdline); + + ifP = pm_openr(cmdline.inputFilespec); + + tuplenarray = pnm_readpamn(ifP, &inpam, sizeof(inpam)); + + mappam = inpam; + mappam.file = stdout; + mappam.maxval = 255; + + MALLOCARRAY_NOFAIL(sharpness, inpam.depth); + + map = pnm_allocpamarray(&mappam); + makeBlackRown(&inpam, tuplenarray[0]); + for (row = 1; row < inpam.height-1; ++row) { + int col; + makeBlackTuplen(&inpam, tuplenarray[row][0]); + for (col = 1; col < inpam.width-1; ++col) { + int dy; + unsigned int plane; + + for (plane = 0; plane < inpam.depth; ++plane) + sharpness[plane] = 0.0; + + for (dy = -1; dy <= 1; ++dy) { + int dx; + for (dx = -1; dx <= 1; ++dx) { + if (dx != 0 || dy != 0) { + unsigned int plane; + for (plane = 0; plane < inpam.depth; ++plane) { + samplen const sampleval = + tuplenarray[row][col][plane]; + samplen const sampleval2 = + tuplenarray[row+dy][col+dx][plane]; + sharpness[plane] += fabs(sampleval - sampleval2); + } + } + } + } + makeSharpnessPixel(&mappam, sharpness, map[row][col]); + } + makeBlackTuplen(&inpam, tuplenarray[row][inpam.width-1]); + } + makeBlackRown(&inpam, tuplenarray[inpam.height-1]); + free(sharpness); + + pnm_writepam(&mappam, map); + + pnm_freepamarray(map, &mappam); + pnm_freepamarrayn(tuplenarray, &inpam); + + return 0; +} diff --git a/analyzer/pamsharpness.c b/analyzer/pamsharpness.c new file mode 100644 index 00000000..7e52a9ba --- /dev/null +++ b/analyzer/pamsharpness.c @@ -0,0 +1,153 @@ +/*---------------------------------------------------------------------------- + Pnmsharpness +------------------------------------------------------------------------------ + + Bryan Henderson derived this (January 2004) from the program of the + same name by B.W. van Schooten and distributed to Bryan under the Perl + Artistic License, as part of the Photopnmtools package. Bryan placed + his modifications in the public domain. + + This is the copyright/license notice from the original: + + Copyright (c) 2002, 2003 by B.W. van Schooten. All rights reserved. + This software is distributed under the Perl Artistic License. + No warranty. See file 'artistic.license' for more details. + + boris@13thmonkey.org + www.13thmonkey.org/~boris/photopnmtools/ +-----------------------------------------------------------------------------*/ + +#include +#include + +#include "pam.h" +#include "shhopt.h" + +struct cmdlineInfo { + /* All the information the user supplied in the command line, + in a form easy for the program to use. + */ + const char *inputFilespec; /* '-' if stdin */ + unsigned int context; +}; + + + +static void +parseCommandLine ( int argc, char ** argv, + struct cmdlineInfo *cmdlineP ) { +/*---------------------------------------------------------------------------- + parse program command line described in Unix standard form by argc + and argv. Return the information in the options as *cmdlineP. + + If command line is internally inconsistent (invalid options, etc.), + issue error message to stderr and abort program. + + Note that the strings we return are stored in the storage that + was passed to us as the argv array. We also trash *argv. +-----------------------------------------------------------------------------*/ + optEntry *option_def = malloc(100*sizeof(optEntry)); + /* Instructions to optParseOptions3 on how to parse our options. + */ + optStruct3 opt; + + unsigned int option_def_index; + + unsigned int contextSpec; + + option_def_index = 0; /* incremented by OPTENT3 */ + OPTENT3(0, "context", OPT_UINT, &cmdlineP->context, + &contextSpec, 0 ); + + opt.opt_table = option_def; + opt.short_allowed = FALSE; /* We have no short (old-fashioned) options */ + opt.allowNegNum = FALSE; /* We have no parms that are negative numbers */ + + optParseOptions3( &argc, argv, opt, sizeof(opt), 0); + /* Uses and sets argc, argv, and some of *cmdlineP and others. */ + + if (!contextSpec) + cmdlineP->context = 1; + + if (cmdlineP->context < 1) + pm_error("-context must be at least 1"); + + + if (argc-1 > 1) + pm_error("The only argument is the input file name"); + else if (argc-1 < 1) + cmdlineP->inputFilespec = "-"; + else + cmdlineP->inputFilespec = argv[1]; +} + + + +static void +computeSharpness(struct pam * const inpamP, + tuplen ** const tuplenarray, + double * const sharpnessP) { + + int row; + double totsharp; + + totsharp = 0.0; + + for (row = 1; row < inpamP->height-1; ++row) { + int col; + for (col = 1; col < inpamP->width-1; ++col) { + int dy; + for (dy = -1; dy <= 1; ++dy) { + int dx; + for (dx = -1; dx <= 1; ++dx) { + if (dx != 0 || dy != 0) { + unsigned int plane; + for (plane = 0; plane < inpamP->depth; ++plane) { + samplen const sampleval = + tuplenarray[row][col][plane]; + samplen const sampleval2 = + tuplenarray[row+dy][col+dx][plane]; + totsharp += fabs(sampleval - sampleval2); + } + } + } + } + } + } + *sharpnessP = + totsharp / (inpamP->width * inpamP->height * inpamP->depth * 8); + /* The 8 above is for the 8 neighbors to which we compare each pixel */ +} + + + +int +main(int argc, char **argv) { + + struct cmdlineInfo cmdline; + FILE * ifP; + tuplen ** tuplenarray; + struct pam inpam; + double sharpness; + + pnm_init(&argc, argv); + + parseCommandLine(argc, argv, &cmdline); + + ifP = pm_openr(cmdline.inputFilespec); + + tuplenarray = pnm_readpamn(ifP, &inpam, sizeof(inpam)); + + if (inpam.height < 3 || inpam.width < 3) + pm_error("sharpness is undefined for an image less than 3 pixels " + "in all directions. This image is %d x %d", + inpam.width, inpam.height); + + computeSharpness(&inpam, tuplenarray, &sharpness); + + pm_message("Sharpness = %f\n", sharpness); + + pnm_freepamarrayn(tuplenarray, &inpam); + pm_close(ifP); + return 0; +} diff --git a/analyzer/pamslice.c b/analyzer/pamslice.c new file mode 100644 index 00000000..fc63a2cc --- /dev/null +++ b/analyzer/pamslice.c @@ -0,0 +1,199 @@ +/* + * + * This program (Pamslice) was derived by Bryan Henderson in July 2002 + * from Pgmslice by Jos Dingjan. Pgmslice did the same thing, but + * only on PGM images. Pamslice is a total rewrite. + * + * Copyright (C) 2000 Jos Dingjan + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +enum orientation {ROW, COLUMN}; + +#include "pam.h" +#include "shhopt.h" + +struct cmdlineInfo { + /* All the information the user supplied in the command line, + in a form easy for the program to use. + */ + const char *inputFilespec; /* Filespec of input file */ + enum orientation orientation; + union { + unsigned int row; + unsigned int col; + } u; + unsigned int onePlane; + unsigned int plane; + unsigned int xmgr; +}; + + +static void +parseCommandLine(int argc, char ** const argv, + struct cmdlineInfo * const cmdlineP) { +/*---------------------------------------------------------------------------- + Note that the file spec array we return is stored in the storage that + was passed to us as the argv array. +-----------------------------------------------------------------------------*/ + optEntry *option_def = malloc(100*sizeof(optEntry)); + /* Instructions to OptParseOptions2 on how to parse our options. + */ + optStruct3 opt; + + unsigned int option_def_index; + + unsigned int rowSpec, colSpec; + + option_def_index = 0; /* incremented by OPTENTRY */ + OPTENT3(0, "row", OPT_UINT, &cmdlineP->u.row, &rowSpec, 0); + OPTENT3(0, "column", OPT_UINT, &cmdlineP->u.col, &colSpec, 0); + OPTENT3(0, "plane", OPT_UINT, &cmdlineP->plane, &cmdlineP->onePlane, 0); + OPTENT3(0, "xmgr", OPT_FLAG, NULL, &cmdlineP->xmgr, 0); + + opt.opt_table = option_def; + opt.short_allowed = FALSE; /* We have no short (old-fashioned) options */ + opt.allowNegNum = FALSE; /* We have no parms that are negative numbers */ + + optParseOptions3(&argc, argv, opt, sizeof(opt), 0); + /* Uses and sets argc, argv, and some of *cmdlineP and others. */ + + if (rowSpec && colSpec) + pm_error("You cannot specify both -row and -col"); + + if (argc-1 > 1) + pm_error("Too many arguments (%d). Only argument is filename.", + argc-1); + else if (argc-1 == 1) + cmdlineP->inputFilespec = argv[1]; + else + cmdlineP->inputFilespec = "-"; + + if (rowSpec) + cmdlineP->orientation = ROW; + else if (colSpec) + cmdlineP->orientation = COLUMN; + else + pm_error("You must specify either -column or -row"); +} + + + +static void +printSlice(FILE * const outfile, + tuple ** const tuples, + unsigned int const rowstart, + unsigned int const rowend, + unsigned int const colstart, + unsigned int const colend, + unsigned int const planestart, + unsigned int const planeend, + bool const xmgr) { + + unsigned int count; + unsigned int row; + + + if (xmgr) { + fprintf(outfile,"@ title \"Graylevel\"\n"); + fprintf(outfile,"@ subtitle \"from (%d,%d) to (%d,%d)\"\n", + colstart, rowstart, colend, rowend); + if (colend - colstart == 1) + fprintf(outfile,"@ xaxis label \"row\"\n"); + else + fprintf(outfile,"@ xaxis label \"column\"\n"); + fprintf(outfile,"@ yaxis label \"grayvalue\"\n"); + if (planeend - planestart == 1) + fprintf(stdout,"@ type xy\n"); + else + fprintf(stdout,"@ type nxy\n"); + } + + count = 0; + for (row = rowstart; row < rowend; ++row) { + unsigned int col; + for (col = colstart; col < colend; ++col) { + unsigned int plane; + fprintf(outfile, "%d ", count++); + for (plane = planestart; plane < planeend; ++plane) + fprintf(outfile, "%lu ", tuples[row][col][plane]); + fprintf(outfile, "\n"); + } + } +} + + + +int +main(int argc, char *argv[]) { + + struct cmdlineInfo cmdline; + FILE *ifP; + struct pam inpam; + tuple **tuples; + unsigned int colstart, colend, rowstart, rowend, planestart, planeend; + + pgm_init( &argc, argv ); + + parseCommandLine(argc, argv, &cmdline); + + ifP = pm_openr(cmdline.inputFilespec); + + tuples = pnm_readpam(ifP, &inpam, PAM_STRUCT_SIZE(tuple_type)); + + switch (cmdline.orientation) { + case COLUMN: + if (cmdline.u.col >= inpam.width) + pm_error("You specified column %u, but there are only %u columns " + "in the image.", cmdline.u.col, inpam.width); + + colstart = cmdline.u.col; + colend = colstart + 1; + rowstart = 0; + rowend = inpam.height; + + break; + case ROW: + if (cmdline.u.row >= inpam.height) + pm_error("You specified row %u, but there are only %u rows " + "in the image.", cmdline.u.row, inpam.height); + colstart = 0; + colend = inpam.width; + rowstart = cmdline.u.row; + rowend = rowstart + 1; + + break; + } + + if (cmdline.onePlane) { + if (cmdline.plane >= inpam.depth) + pm_error("You specified plane %u, but there are only %u planes " + "in the image.", cmdline.plane, inpam.depth); + planestart = cmdline.plane; + planeend = planestart + 1; + } else { + planestart = 0; + planeend = inpam.depth; + } + + printSlice(stdout, tuples, + rowstart, rowend, colstart, colend, planestart, planeend, + cmdline.xmgr); + + pm_close(ifP); + pm_close(stdout); + + exit(0); +} diff --git a/analyzer/pamsumm.c b/analyzer/pamsumm.c new file mode 100644 index 00000000..390b8ebb --- /dev/null +++ b/analyzer/pamsumm.c @@ -0,0 +1,231 @@ +/****************************************************************************** + pamsumm +******************************************************************************* + Summarize all the samples of a PAM image with various functions. + + By Bryan Henderson, San Jose CA 2004.02.07. + + Contributed to the public domain + + +******************************************************************************/ + +#include "pam.h" +#include "shhopt.h" +#include "mallocvar.h" + +enum function {FN_ADD, FN_MEAN, FN_MIN, FN_MAX}; + +struct cmdlineInfo { + /* All the information the user supplied in the command line, + in a form easy for the program to use. + */ + const char *inputFilespec; /* Filespec of input file */ + enum function function; + unsigned int normalize; + unsigned int brief; + unsigned int verbose; +}; + + +static void +parseCommandLine(int argc, char ** const argv, + struct cmdlineInfo * const cmdlineP) { +/*---------------------------------------------------------------------------- + Note that the file spec array we return is stored in the storage that + was passed to us as the argv array. +-----------------------------------------------------------------------------*/ + optEntry *option_def = malloc(100*sizeof(optEntry)); + /* Instructions to OptParseOptions2 on how to parse our options. + */ + optStruct3 opt; + + unsigned int option_def_index; + + unsigned int sumSpec, meanSpec, minSpec, maxSpec; + + option_def_index = 0; /* incremented by OPTENTRY */ + OPTENT3(0, "sum", OPT_FLAG, NULL, &sumSpec, 0); + OPTENT3(0, "mean", OPT_FLAG, NULL, &meanSpec, 0); + OPTENT3(0, "min", OPT_FLAG, NULL, &minSpec, 0); + OPTENT3(0, "max", OPT_FLAG, NULL, &maxSpec, 0); + OPTENT3(0, "normalize", OPT_FLAG, NULL, &cmdlineP->normalize, 0); + OPTENT3(0, "brief", OPT_FLAG, NULL, &cmdlineP->brief, 0); + OPTENT3(0, "verbose", OPT_FLAG, NULL, &cmdlineP->verbose, 0); + + opt.opt_table = option_def; + opt.short_allowed = FALSE; /* We have no short (old-fashioned) options */ + opt.allowNegNum = FALSE; /* We have no parms that are negative numbers */ + + optParseOptions3(&argc, argv, opt, sizeof(opt), 0); + /* Uses and sets argc, argv, and some of *cmdlineP and others. */ + + if (sumSpec + minSpec + maxSpec > 1) + pm_error("You may specify at most one of -sum, -min, and -max"); + + if (sumSpec) { + cmdlineP->function = FN_ADD; + } else if (meanSpec) { + cmdlineP->function = FN_MEAN; + } else if (minSpec) { + cmdlineP->function = FN_MIN; + } else if (maxSpec) { + cmdlineP->function = FN_MAX; + } else + pm_error("You must specify one of -sum, -min, or -max"); + + if (argc-1 > 1) + pm_error("Too many arguments (%d). File spec is the only argument.", + argc-1); + + if (argc-1 < 1) + cmdlineP->inputFilespec = "-"; + else + cmdlineP->inputFilespec = argv[1]; + +} + + +struct accum { + union { + double sum; + unsigned int min; + unsigned int max; + } u; +}; + + + +static void +initAccumulator(struct accum * const accumulatorP, + enum function const function) { + + switch(function) { + case FN_ADD: accumulatorP->u.sum = 0.0; break; + case FN_MEAN: accumulatorP->u.sum = 0.0; break; + case FN_MIN: accumulatorP->u.min = UINT_MAX; break; + case FN_MAX: accumulatorP->u.max = 0; break; + } +} + + + +static void +aggregate(struct pam * const inpamP, + tuple * const tupleRow, + enum function const function, + struct accum * const accumulatorP) { + + unsigned int col; + + for (col = 0; col < inpamP->width; ++col) { + unsigned int plane; + for (plane = 0; plane < inpamP->depth; ++plane) { + switch(function) { + case FN_ADD: + case FN_MEAN: + accumulatorP->u.sum += tupleRow[col][plane]; + break; + case FN_MIN: + if (tupleRow[col][plane] < accumulatorP->u.min) + accumulatorP->u.min = tupleRow[col][plane]; + break; + case FN_MAX: + if (tupleRow[col][plane] > accumulatorP->u.min) + accumulatorP->u.min = tupleRow[col][plane]; + break; + } + } + } +} + + + +static void +printSummary(struct accum const accumulator, + unsigned int const scale, + unsigned int const count, + enum function const function, + bool const normalize, + bool const brief) { + + switch(function) { + case FN_ADD: { + const char * const intro = brief ? "" : "the sum of all samples is "; + + if (normalize) + printf("%s%f\n", intro, accumulator.u.sum/scale); + else + printf("%s%u\n", intro, (unsigned int)accumulator.u.sum); + } + break; + case FN_MEAN: { + const char * const intro = brief ? "" : "the mean of all samples is "; + + if (normalize) + printf("%s%f\n", intro, accumulator.u.sum/count/scale); + else + printf("%s%f\n", intro, accumulator.u.sum/count); + } + break; + case FN_MIN: { + const char * const intro = + brief ? "" : "the minimum of all samples is "; + + if (normalize) + printf("%s%f\n", intro, (double)accumulator.u.min/scale); + else + printf("%s%u\n", intro, accumulator.u.min); + } + break; + case FN_MAX: { + const char * const intro = + brief ? "" : "the maximum of all samples is "; + + if (normalize) + printf("%s%f\n", intro, (double)accumulator.u.max/scale); + else + printf("%s%u\n", intro, accumulator.u.max); + } + break; + } +} + + + +int +main(int argc, char *argv[]) { + + FILE* ifP; + tuple* inputRow; /* Row from input image */ + int row; + struct cmdlineInfo cmdline; + struct pam inpam; /* Input PAM image */ + struct accum accumulator; + + pnm_init(&argc, argv); + + parseCommandLine(argc, argv, &cmdline); + + ifP = pm_openr(cmdline.inputFilespec); + + pnm_readpaminit(ifP, &inpam, PAM_STRUCT_SIZE(tuple_type)); + + inputRow = pnm_allocpamrow(&inpam); + + initAccumulator(&accumulator, cmdline.function); + + for (row = 0; row < inpam.height; row++) { + pnm_readpamrow(&inpam, inputRow); + + aggregate(&inpam, inputRow, cmdline.function, &accumulator); + } + printSummary(accumulator, (unsigned)inpam.maxval, + inpam.height * inpam.width * inpam.depth, + cmdline.function, cmdline.normalize, cmdline.brief); + + pnm_freepamrow(inputRow); + pm_close(inpam.file); + + return 0; +} diff --git a/analyzer/pamtilt.c b/analyzer/pamtilt.c new file mode 100644 index 00000000..3753955b --- /dev/null +++ b/analyzer/pamtilt.c @@ -0,0 +1,437 @@ +/*============================================================================= + pgmtilt +=============================================================================== + Print the tilt angle of a PGM file + + Based on pgmskew by Gregg Townsend, August 2005. + + Adapted to Netpbm by Bryan Henderson, August 2005. + + All work has been contributed to the public domain by its authors. +=============================================================================*/ + +#include + +#include "pam.h" +#include "mallocvar.h" +#include "shhopt.h" + +/* program constants */ +#define DIFFMAX 255 /* maximum scaling for differences */ +#define BARLENGTH 60 /* length of bars printed with -v */ + +struct cmdlineInfo { + /* command parameters */ + const char * inputFilename; + float maxangle; /* maximum angle attempted */ + float astep; /* initial angle increment */ + float qmin; /* minimum quality of solution */ + unsigned int hstep; /* horizontal step size */ + unsigned int vstep; /* vertical step size */ + unsigned int dstep; /* difference distance */ + unsigned int fast; /* skip third iteration */ + unsigned int verbose; /* generate commentary */ +}; + +static void +abandon(void) { + + printf("00.00\n"); + exit(0); +} + + + +static void +parseCommandLine(int argc, char *argv[], + struct cmdlineInfo * const cmdlineP) { + + static optEntry option_def[50]; + static optStruct3 opt; + unsigned int option_def_index; + + /* set defaults */ + cmdlineP->hstep = 11; /* read only every 11th column */ + cmdlineP->vstep = 5; /* calc differences every 5th row */ + cmdlineP->dstep = 2; /* check for differences two rows down */ + cmdlineP->maxangle = 10.0; /* assume skew is less than +/- ten degrees */ + cmdlineP->astep = 1.0; /* initially check by one-degree increments */ + cmdlineP->qmin = 1.0; /* don't require S/N better than 1.0 */ + + /* initialize option table */ + option_def_index = 0; /* incremented by OPTENT3 */ + OPTENT3(0, "fast", OPT_FLAG, NULL, &cmdlineP->fast, 0); + OPTENT3(0, "verbose", OPT_FLAG, NULL, &cmdlineP->verbose, 0); + OPTENT3(0, "angle", OPT_FLOAT, &cmdlineP->maxangle, NULL, 0); + OPTENT3(0, "quality", OPT_FLOAT, &cmdlineP->qmin, NULL, 0); + OPTENT3(0, "astep", OPT_FLOAT, &cmdlineP->astep, NULL, 0); + OPTENT3(0, "hstep", OPT_UINT, &cmdlineP->hstep, NULL, 0); + OPTENT3(0, "vstep", OPT_UINT, &cmdlineP->vstep, NULL, 0); + OPTENT3(0, "dstep", OPT_UINT, &cmdlineP->dstep, NULL, 0); + + opt.opt_table = option_def; + opt.short_allowed = FALSE; /* no short options used */ + opt.allowNegNum = FALSE; /* don't allow negative values */ + optParseOptions3(&argc, argv, opt, sizeof(opt), 0); + + if (cmdlineP->hstep < 1) + pm_error("-hstep must be at least 1 column."); + if (cmdlineP->vstep < 1) + pm_error("-vstep must be at least 1 row."); + if (cmdlineP->dstep < 1) + pm_error("-dstep must be at least 1 row."); + if (cmdlineP->maxangle < 1 || cmdlineP->maxangle > 45) + pm_error("-maxangle must be between 1 and 45 degrees."); + + if (argc-1 < 1) /* if input file name given */ + cmdlineP->inputFilename = "-"; + else { + cmdlineP->inputFilename = argv[1]; + + if (argc-1 > 1) + pm_error("There is at most one argument. You specified %d", + argc-1); + } +} + + + +static void +computeSteps(const struct pam * const pamP, + unsigned int const hstepReq, + unsigned int const vstepReq, + unsigned int * const hstepP, + unsigned int * const vstepP) { +/*---------------------------------------------------------------------------- + Adjust parameters if necessary now that we have the image size +-----------------------------------------------------------------------------*/ + if (pamP->width < 10 || pamP->height < 10) + abandon(); + + if (pamP->width < 10 * hstepReq) + *hstepP = pamP->width / 10; + else + *hstepP = hstepReq; + + if (pamP->height < 10 * vstepReq) + *vstepP = pamP->height / 10; + else + *vstepP = vstepReq; +} + + + +static void +load(const struct pam * const pamP, + unsigned int const hstep, + sample *** const pixelsP, + unsigned int * const hsamplesP) { +/*---------------------------------------------------------------------------- + read file into memory, returning array of rows +-----------------------------------------------------------------------------*/ + unsigned int const hsamples = 1 + (pamP->width - 1) / hstep; + /* use only this many cols */ + + unsigned int row; + tuple * tuplerow; + sample ** pixels; + + tuplerow = pnm_allocpamrow(pamP); + + MALLOCARRAY(pixels, pamP->height); + if (pixels == NULL) + pm_error("Unable to allocate array of %u pixel rows", + pamP->height); + + if (pixels == NULL) + pm_error("Unable to allocate array of %u rows", pamP->height); + + for (row = 0; row < pamP->height; ++row) { + unsigned int i; + unsigned int col; + + pnm_readpamrow(pamP, tuplerow); + + MALLOCARRAY(pixels[row], hsamples); + if (pixels[row] == NULL) + pm_error("Unable to allocate %u-sample array for Row %u", + hsamples, row); + + /* save every hstep'th column */ + for (i = col = 0; i < hsamples; ++i, col += hstep) + pixels[row][i] = tuplerow[col][0]; + } + + pnm_freepamrow(tuplerow); + + *hsamplesP = hsamples; + *pixelsP = pixels; +} + + + +static void +freePixels(sample ** const samples, + unsigned int const rows) { + + unsigned int row; + + for (row = 0; row < rows; ++row) + free(samples[row]); + + free(samples); +} + + + +static void +replacePixelValuesWithScaledDiffs( + const struct pam * const pamP, + sample ** const pixels, + unsigned int const hsamples, + unsigned int const dstep) { +/*---------------------------------------------------------------------------- + Replace pixel values with scaled differences used for all + calculations +-----------------------------------------------------------------------------*/ + float const m = DIFFMAX / (float) pamP->maxval; /* scale multiplier */ + + unsigned int row; + + for (row = dstep; row < pamP->height; ++row) { + unsigned int col; + for (col = 0; col < hsamples; ++col) { + int const d = pixels[row - dstep][col] - pixels[row][col]; + unsigned int const absd = d < 0 ? -d : d; + pixels[row - dstep][col] = m * absd; /* scale the difference */ + } + } +} + + + +static void +scoreAngle(const struct pam * const pamP, + sample ** const pixels, + unsigned int const hstep, + unsigned int const vstep, + unsigned int const hsamples, + float const deg, + float * const scoreP) { +/*---------------------------------------------------------------------------- + calculate score for a given angle +-----------------------------------------------------------------------------*/ + float const radians = (float)deg/360 * 2 * M_PI; + float const dy = hstep * tan(radians); + int const dtotal = pamP->width * tan(radians); + double const tscale = 1.0 / hsamples; + + double total; + int first; + int last; + + unsigned int row; + + total = 0.0; /* initial value */ + + if (dtotal > 0) { + first = 0; + last = pamP->height - 1 - (dtotal + 1); + } else { + first = -(dtotal - 1); + last = pamP->height - 1; + } + for (row = first; row < last; row += vstep) { + float o; + long t; + double dt; + + unsigned int i; + + for (i = 0, t = 0, o = 0.5; + i < hsamples; + ++i, t += pixels[(int)(row + o)][i], o += dy) { + } + dt = tscale * t; + total += dt * dt; + } + *scoreP = total / (last - first); +} + + + +static void +getBestAngleLocal( + const struct pam * const pamP, + sample ** const pixels, + unsigned int const hstep, + unsigned int const vstep, + unsigned int const hsamples, + float const minangle, + float const maxangle, + float const incr, + bool const verbose, + float * const bestAngleP, + float * const qualityP) { +/*---------------------------------------------------------------------------- + find angle of highest score within a range +-----------------------------------------------------------------------------*/ + int const nsamples = ((maxangle - minangle) / incr + 1.5); + + float score; + float quality; /* signal/noise ratio of the best angle */ + float angle; + float bestangle; + float bestscore; + float total; + float others; + float * results; + int i; + + MALLOCARRAY_NOFAIL(results, nsamples); /* allocate array of results */ + + /* try all angles within the given range, stepping by incr */ + bestangle = minangle; + bestscore = 0; + total = 0; + for (i = 0; i < nsamples; i++) { + angle = minangle + i * incr; + scoreAngle(pamP, pixels, hstep, vstep, hsamples, angle, &score); + results[i] = score; + if (score > bestscore || + (score == bestscore && fabs(angle) < fabs(bestangle))) { + bestscore = score; + bestangle = angle; + } + total += score; + } + + others = (total-bestscore) / (nsamples-1); /* get mean of other scores */ + quality = bestscore / others; + + if (verbose) { + fprintf(stderr, + "\n%2d angles from %6.2f to %5.2f by %4.2f: " + "best = %6.2f, S:N = %4.2f\n", + nsamples, minangle, maxangle, incr, bestangle, quality); + for (i = 0; i < nsamples; ++i) { + float const angle = minangle + i * incr; + int const n = (int) (BARLENGTH * results[i] / bestscore + 0.5); + fprintf(stderr, "%6.2f: %8.2f %0*d\n", angle, results[i], n, 0); + } + } + free(results); + + *qualityP = quality; + *bestAngleP = bestangle; +} + + + +static void +readRelevantPixels(const char * const inputFilename, + unsigned int const hstepReq, + unsigned int const vstepReq, + unsigned int * const hstepP, + unsigned int * const vstepP, + sample *** const pixelsP, + struct pam * const pamP, + unsigned int * const hsamplesP) { +/*---------------------------------------------------------------------------- + load the image, saving only the pixels we might actually inspect +-----------------------------------------------------------------------------*/ + FILE * ifP; + unsigned int hstep; + unsigned int vstep; + + ifP = pm_openr(inputFilename); + pnm_readpaminit(ifP, pamP, PAM_STRUCT_SIZE(tuple_type)); + computeSteps(pamP, hstepReq, vstepReq, &hstep, &vstep); + + load(pamP, hstep, pixelsP, hsamplesP); + + *hstepP = hstep; + *vstepP = vstep; + + pm_close(ifP); +} + + + +static void +getAngle(const struct pam * const pamP, + sample ** const pixels, + unsigned int const hstep, + unsigned int const vstep, + unsigned int const hsamples, + float const maxangle, + float const astep, + float const qmin, + bool const fast, + bool const verbose, + float * const angleP) { + + float a; + float da; + float lastq; /* quality (s/n ratio) of last measurement */ + + getBestAngleLocal(pamP, pixels, hstep, vstep, hsamples, + -maxangle, maxangle, astep, verbose, + &a, &lastq); + + if ((a < -maxangle + astep / 2) || (a > maxangle - astep / 2)) + /* extreme val almost certainly wrong */ + abandon(); + if (lastq < qmin) + /* insufficient s/n ratio */ + abandon(); + + /* make a finer search in the neighborhood */ + da = astep / 10; + getBestAngleLocal(pamP, pixels, hstep, vstep, hsamples, + a - 9 * da, a + 9 * da, da, verbose, + &a, &lastq); + + /* iterate once more unless we don't need that much accuracy */ + if (!fast) { + da /= 10; + getBestAngleLocal(pamP, pixels, hstep, vstep, hsamples, + a - 9 * da, a + 9 * da, da, verbose, + &a, &lastq); + } + *angleP = a; +} + + + +int +main(int argc, char *argv[]) { + + struct cmdlineInfo cmdline; + struct pam pam; + sample ** pixels; /* pixel data */ + unsigned int hsamples; /* horizontal samples used */ + unsigned int hstep; /* horizontal step size */ + unsigned int vstep; /* vertical step size */ + float angle; + + pgm_init(&argc, argv); /* initialize netpbm system */ + + parseCommandLine(argc, argv, &cmdline); + + readRelevantPixels(cmdline.inputFilename, cmdline.hstep, cmdline.vstep, + &hstep, &vstep, &pixels, &pam, &hsamples); + + replacePixelValuesWithScaledDiffs(&pam, pixels, hsamples, cmdline.dstep); + + getAngle(&pam, pixels, hstep, vstep, hsamples, + cmdline.maxangle, cmdline.astep, cmdline.qmin, + cmdline.fast, cmdline.verbose, &angle); + + /* report the result on stdout */ + printf("%.2f\n", angle); + + freePixels(pixels, pam.height); + + return 0; +} diff --git a/analyzer/pbmminkowski.c b/analyzer/pbmminkowski.c new file mode 100644 index 00000000..5edce506 --- /dev/null +++ b/analyzer/pbmminkowski.c @@ -0,0 +1,168 @@ +/* pbmminkowsky.c - read a portable bitmap and calculate the Minkowski Integrals +** +** Copyright (C) 2000 by Luuk van Dijk/Mind over Matter +** +** Based on pbmlife.c, +** Copyright (C) 1988,1 1991 by Jef Poskanzer. +** +** Permission to use, copy, modify, and distribute this software and its +** documentation for any purpose and without fee is hereby granted, provided +** that the above copyright notice appear in all copies and that both that +** copyright notice and this permission notice appear in supporting +** documentation. This software is provided "as is" without express or +** implied warranty. +*/ + +#include "pbm.h" + +#define ISWHITE(x) ( (x) == PBM_WHITE ) + + +int main( int argc, char** argv ){ + + FILE* ifp; + + bit* prevrow; + bit* thisrow; + bit* tmprow; + + int row; + int col; + + int countTile=0; + int countEdgeX=0; + int countEdgeY=0; + int countVertex=0; + + int rows; + int cols; + int format; + + int area, perimeter, eulerchi; + + + /* + * parse arg and initialize + */ + + pbm_init( &argc, argv ); + + if ( argc > 2 ) + pm_usage( "[pbmfile]" ); + + if ( argc == 2 ) + ifp = pm_openr( argv[1] ); + else + ifp = stdin; + + pbm_readpbminit( ifp, &cols, &rows, &format ); + + prevrow = pbm_allocrow( cols ); + thisrow = pbm_allocrow( cols ); + + + /* first row */ + + pbm_readpbmrow( ifp, thisrow, cols, format ); + + /* tiles */ + + for ( col = 0; col < cols; ++col ) + if( ISWHITE(thisrow[col]) ) ++countTile; + + /* shortcut: for the first row, edgeY == countTile */ + countEdgeY = countTile; + + /* x-edges */ + + if( ISWHITE(thisrow[0]) ) ++countEdgeX; + + for ( col = 0; col < cols-1; ++col ) + if( ISWHITE(thisrow[col]) || ISWHITE(thisrow[col+1]) ) ++countEdgeX; + + if( ISWHITE(thisrow[cols-1]) ) ++countEdgeX; + + /* shortcut: for the first row, countVertex == countEdgeX */ + + countVertex = countEdgeX; + + + for ( row = 1; row < rows; ++row ){ + + tmprow = prevrow; + prevrow = thisrow; + thisrow = tmprow; + + pbm_readpbmrow( ifp, thisrow, cols, format ); + + /* tiles */ + + for ( col = 0; col < cols; ++col ) + if( ISWHITE(thisrow[col]) ) ++countTile; + + /* y-edges */ + + for ( col = 0; col < cols; ++col ) + if( ISWHITE(thisrow[col]) || ISWHITE( prevrow[col] )) ++countEdgeY; + + /* x-edges */ + + if( ISWHITE(thisrow[0]) ) ++countEdgeX; + + for ( col = 0; col < cols-1; ++col ) + if( ISWHITE(thisrow[col]) || ISWHITE(thisrow[col+1]) ) ++countEdgeX; + + if( ISWHITE(thisrow[cols-1]) ) ++countEdgeX; + + /* vertices */ + + if( ISWHITE(thisrow[0]) || ISWHITE(prevrow[0]) ) ++countVertex; + + for ( col = 0; col < cols-1; ++col ) + if( ISWHITE(thisrow[col]) || ISWHITE(thisrow[col+1]) + || ISWHITE(prevrow[col]) || ISWHITE(prevrow[col+1]) ) ++countVertex; + + if( ISWHITE(thisrow[cols-1]) || ISWHITE(prevrow[cols-1]) ) ++countVertex; + + + } /* for row */ + + /* now thisrow contains the top row*/ + /* tiles and x-edges have been counted, now y-edges and top vertices remain */ + + + /* y-edges */ + + for ( col = 0; col < cols; ++col ) + if( ISWHITE(thisrow[col]) ) ++countEdgeY; + + /* vertices */ + + if( ISWHITE(thisrow[0]) ) ++countVertex; + + for ( col = 0; col < cols-1; ++col ) + if( ISWHITE(thisrow[col]) || ISWHITE(thisrow[col+1]) ) ++countVertex; + + if( ISWHITE(thisrow[cols-1]) ) ++countVertex; + + + /* cleanup */ + + pm_close( ifp ); + + /* print results */ + + printf( " tiles:\t%d\n x-edges:\t%d\n y-edges:\t%d\nvertices:\t%d\n", + countTile, countEdgeX, countEdgeY,countVertex ); + + area = countTile; + perimeter = 2*countEdgeX + 2*countEdgeY - 4*countTile; + eulerchi = countTile - countEdgeX - countEdgeY + countVertex; + + printf( " area:\t%d\nperimeter:\t%d\n eulerchi:\t%d\n", + area, perimeter, eulerchi ); + + exit( 0 ); + +} /* main */ + diff --git a/analyzer/pgmhist.c b/analyzer/pgmhist.c new file mode 100644 index 00000000..8f4e512e --- /dev/null +++ b/analyzer/pgmhist.c @@ -0,0 +1,87 @@ +/* pgmhist.c - print a histogram of the values in a portable graymap +** +** Copyright (C) 1989 by Jef Poskanzer. +** +** Permission to use, copy, modify, and distribute this software and its +** documentation for any purpose and without fee is hereby granted, provided +** that the above copyright notice appear in all copies and that both that +** copyright notice and this permission notice appear in supporting +** documentation. This software is provided "as is" without express or +** implied warranty. +*/ + +#include "pgm.h" +#include "mallocvar.h" + +int +main( argc, argv ) + int argc; + char *argv[]; +{ + FILE *ifp; + gray maxval, *grayrow; + register gray *gP; + int argn, rows, cols, format, row; + int i, *hist, *rcount, count, size; + register int col; + const char * const usage = "[pgmfile]"; + + pgm_init( &argc, argv ); + + argn = 1; + + if ( argn < argc ) + { + ifp = pm_openr( argv[argn] ); + argn++; + } + else + ifp = stdin; + + if ( argn != argc ) + pm_usage( usage ); + + pgm_readpgminit( ifp, &cols, &rows, &maxval, &format ); + grayrow = pgm_allocrow( cols ); + + /* Build histogram. */ + MALLOCARRAY(hist, maxval + 1); + MALLOCARRAY(rcount, maxval + 1); + if ( hist == NULL || rcount == NULL ) + pm_error( "out of memory" ); + for ( i = 0; i <= maxval; i++ ) + hist[i] = 0; + for ( row = 0; row < rows; row++ ) + { + pgm_readpgmrow( ifp, grayrow, cols, maxval, format ); + for ( col = 0, gP = grayrow; col < cols; col++, gP++ ) + hist[(int) *gP]++; + } + + pm_close( ifp ); + + /* Compute count-down */ + count = 0; + for ( i = maxval; i >= 0; i-- ) + { + count += hist[i]; + rcount[i] = count; + } + + /* And print it. */ + printf( "value\tcount\tb%%\tw%%\n" ); + printf( "-----\t-----\t--\t--\n" ); + count = 0; + size = rows * cols; + for ( i = 0; i <= maxval; i++ ) + if ( hist[i] > 0 ) + { + count += hist[i]; + printf( + "%d\t%d\t%5.3g%%\t%5.3g%%\n", i, hist[i], + (float) count * 100.0 / size, + (float) rcount[i] * 100.0 / size ); + } + + exit( 0 ); +} diff --git a/analyzer/pgmminkowski.c b/analyzer/pgmminkowski.c new file mode 100644 index 00000000..dfb08429 --- /dev/null +++ b/analyzer/pgmminkowski.c @@ -0,0 +1,222 @@ +/* pgmminkowsky.c - read a portable graymap and calculate the Minkowski +** Integrals as a function of the threshold. +** +** Copyright (C) 2000 by Luuk van Dijk/Mind over Matter +** +** Based on pgmhist.c, +** Copyright (C) 1989 by Jef Poskanzer. +** +** Permission to use, copy, modify, and distribute this software and its +** documentation for any purpose and without fee is hereby granted, provided +** that the above copyright notice appear in all copies and that both that +** copyright notice and this permission notice appear in supporting +** documentation. This software is provided "as is" without express or +** implied warranty. +*/ + +#include "pgm.h" +#include "mallocvar.h" + + +#define MAX2(a,b) ( ( (a)>(b) ) ? (a) : (b) ) +#define MAX4(a,b,c,d) MAX2( MAX2((a),(b)), MAX2((c),(d)) ) + +int main( int argc, char** argv ){ + + FILE *ifp; + + gray maxval; + int cols, rows, format; + + gray* prevrow; + gray* thisrow; + gray* tmprow; + + int* countTile; + int* countEdgeX; + int* countEdgeY; + int* countVertex; + + int i, col, row; + + int maxtiles, maxedgex, maxedgey, maxvertex; + int area, perimeter, eulerchi; + + double l2inv, linv; + + /* + * parse arg and initialize + */ + + pgm_init( &argc, argv ); + + if ( argc > 2 ) pm_usage( "[pgmfile]" ); + + if ( argc == 2 ) + ifp = pm_openr( argv[1] ); + else + ifp = stdin; + + /* + * initialize + */ + + pgm_readpgminit( ifp, &cols, &rows, &maxval, &format ); + + prevrow = pgm_allocrow( cols ); + thisrow = pgm_allocrow( cols ); + + MALLOCARRAY(countTile , maxval + 1 ); + MALLOCARRAY(countEdgeX , maxval + 1 ); + MALLOCARRAY(countEdgeY , maxval + 1 ); + MALLOCARRAY(countVertex , maxval + 1 ); + + if (countTile == NULL || countEdgeX == NULL || countEdgeY == NULL || + countVertex == NULL) + pm_error( "out of memory" ); + + for ( i = 0; i <= maxval; i++ ) countTile[i] = 0; + for ( i = 0; i <= maxval; i++ ) countEdgeX[i] = 0; + for ( i = 0; i <= maxval; i++ ) countEdgeY[i] = 0; + for ( i = 0; i <= maxval; i++ ) countVertex[i] = 0; + + + + + /* first row */ + + pgm_readpgmrow( ifp, thisrow, cols, maxval, format ); + + /* tiles */ + + for ( col = 0; col < cols; ++col ) ++countTile[thisrow[col]]; + + /* y-edges */ + + for ( col = 0; col < cols; ++col ) ++countEdgeY[thisrow[col]]; + + /* x-edges */ + + ++countEdgeX[thisrow[0]]; + + for ( col = 0; col < cols-1; ++col ) + ++countEdgeX[ MAX2(thisrow[col], thisrow[col+1]) ]; + + ++countEdgeX[thisrow[cols-1]]; + + /* shortcut: for the first row, countVertex == countEdgeX */ + + ++countVertex[thisrow[0]]; + + for ( col = 0; col < cols-1; ++col ) + ++countVertex[ MAX2(thisrow[col], thisrow[col+1]) ]; + + ++countVertex[thisrow[cols-1]]; + + + + for ( row = 1; row < rows; ++row ){ + + tmprow = prevrow; + prevrow = thisrow; + thisrow = tmprow; + + pgm_readpgmrow( ifp, thisrow, cols, maxval, format ); + + /* tiles */ + + for ( col = 0; col < cols; ++col ) ++countTile[thisrow[col]]; + + /* y-edges */ + + for ( col = 0; col < cols; ++col ) + ++countEdgeY[ MAX2(thisrow[col], prevrow[col]) ]; + /* x-edges */ + + ++countEdgeX[thisrow[0]]; + + for ( col = 0; col < cols-1; ++col ) + ++countEdgeX[ MAX2(thisrow[col], thisrow[col+1]) ]; + + ++countEdgeX[thisrow[cols-1]]; + + /* vertices */ + + ++countVertex[ MAX2(thisrow[0],prevrow[0]) ]; + + for ( col = 0; col < cols-1; ++col ) + ++countVertex[ + MAX4(thisrow[col], thisrow[col+1], prevrow[col], prevrow[col+1]) + ]; + + ++countVertex[ MAX2(thisrow[cols-1],prevrow[cols-1]) ]; + + } /* for row */ + + /* now thisrow contains the top row*/ + + /* tiles and x-edges have been counted, now upper + y-edges and top vertices remain */ + + /* y-edges */ + + for ( col = 0; col < cols; ++col ) ++countEdgeY[ thisrow[col] ]; + + /* vertices */ + + ++countVertex[thisrow[0]]; + + for ( col = 0; col < cols-1; ++col ) + ++countVertex[ MAX2(thisrow[col],thisrow[col+1]) ]; + + ++countVertex[ thisrow[cols-1] ]; + + + /* cleanup */ + + maxtiles = rows * cols; + maxedgex = rows * (cols+1); + maxedgey = (rows+1) * cols; + maxvertex= (rows+1) * (cols+1); + + l2inv = 1.0/maxtiles; + linv = 0.5/(rows+cols); + + /* And print it. */ + printf( "#threshold\t tiles\tx-edges\ty-edges\tvertices\n" ); + printf( "#---------\t -----\t-------\t-------\t--------\n" ); + for ( i = 0; i <= maxval; i++ ){ + + if( !(countTile[i] || countEdgeX[i] || countEdgeY[i] || countVertex[i] ) ) + continue; /* skip empty slots */ + + area = maxtiles; + perimeter = 2*maxedgex + 2*maxedgey - 4*maxtiles; + eulerchi = maxtiles - maxedgex - maxedgey + maxvertex; + + printf( "%f\t%6d\t%7d\t%7d\t%8d\t%g\t%g\t%6d\n", (float) i/(1.0*maxval), + maxtiles, maxedgex, maxedgey, maxvertex, + area*l2inv, perimeter*linv, eulerchi + ); + + + maxtiles -= countTile[i]; + maxedgex -= countEdgeX[i]; + maxedgey -= countEdgeY[i]; + maxvertex-= countVertex[i]; + + /* i, countTile[i], countEdgeX[i], countEdgeY[i], countVertex[i] */ + + } + + /* these should be zero: */ + printf( "# check:\t%6d\t%7d\t%7d\t%8d\n", + maxtiles, maxedgex, maxedgey, maxvertex ); + + pm_close( ifp ); + + exit( 0 ); + +} /*main*/ + + diff --git a/analyzer/pgmtexture.c b/analyzer/pgmtexture.c new file mode 100644 index 00000000..38eab114 --- /dev/null +++ b/analyzer/pgmtexture.c @@ -0,0 +1,1047 @@ +/* pgmtexture.c - calculate textural features on a portable graymap +** +** Author: James Darrell McCauley +** Texas Agricultural Experiment Station +** Department of Agricultural Engineering +** Texas A&M University +** College Station, Texas 77843-2117 USA +** +** Code written partially taken from pgmtofs.c in the PBMPLUS package +** by Jef Poskanzer. +** +** Algorithms for calculating features (and some explanatory comments) are +** taken from: +** +** Haralick, R.M., K. Shanmugam, and I. Dinstein. 1973. Textural features +** for image classification. IEEE Transactions on Systems, Man, and +** Cybertinetics, SMC-3(6):610-621. +** +** Copyright (C) 1991 Texas Agricultural Experiment Station, employer for +** hire of James Darrell McCauley +** +** Permission to use, copy, modify, and distribute this software and its +** documentation for any purpose and without fee is hereby granted, provided +** that the above copyright notice appear in all copies and that both that +** copyright notice and this permission notice appear in supporting +** documentation. This software is provided "as is" without express or +** implied warranty. +** +** THE TEXAS AGRICULTURAL EXPERIMENT STATION (TAES) AND THE TEXAS A&M +** UNIVERSITY SYSTEM (TAMUS) MAKE NO EXPRESS OR IMPLIED WARRANTIES +** (INCLUDING BY WAY OF EXAMPLE, MERCHANTABILITY) WITH RESPECT TO ANY +** ITEM, AND SHALL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL +** OR CONSEQUENTAL DAMAGES ARISING OUT OF THE POSESSION OR USE OF +** ANY SUCH ITEM. LICENSEE AND/OR USER AGREES TO INDEMNIFY AND HOLD +** TAES AND TAMUS HARMLESS FROM ANY CLAIMS ARISING OUT OF THE USE OR +** POSSESSION OF SUCH ITEMS. +** +** Modification History: +** 24 Jun 91 - J. Michael Carstensen supplied fix for +** correlation function. +** +** 05 Oct 05 - Marc Breithecker +** Fix calculation or normalizing constants for d > 1. +*/ + +#include + +#include "pm_c_util.h" +#include "pgm.h" +#include "mallocvar.h" + +#define RADIX 2.0 +#define EPSILON 0.000000001 +#define BL "Angle " +#define F1 "Angular Second Moment " +#define F2 "Contrast " +#define F3 "Correlation " +#define F4 "Variance " +#define F5 "Inverse Diff Moment " +#define F6 "Sum Average " +#define F7 "Sum Variance " +#define F8 "Sum Entropy " +#define F9 "Entropy " +#define F10 "Difference Variance " +#define F11 "Difference Entropy " +#define F12 "Meas of Correlation-1 " +#define F13 "Meas of Correlation-2 " +#define F14 "Max Correlation Coeff " + +#define SIGN(x,y) ((y)<0 ? -fabs(x) : fabs(x)) +#define DOT fprintf(stderr,".") +#define SWAP(a,b) {y=(a);(a)=(b);(b)=y;} + + +static bool sortit = FALSE; + +static float * +vector (int nl, int nh) +{ + float *v; + + MALLOCARRAY(v, (unsigned) (nh - nl + 1)); + if (v == NULL) + pm_error("Unable to allocate memory for a vector."); + return v - nl; +} + + +static float ** +matrix (int nrl, int nrh, int ncl, int nch) + +/* Allocates a float matrix with range [nrl..nrh][ncl..nch] */ +{ + int i; + float **m; + + /* allocate pointers to rows */ + MALLOCARRAY(m, (unsigned) (nrh - nrl + 1)); + if (m == NULL) + pm_error("Unable to allocate memory for a matrix."); + + m -= ncl; + + /* allocate rows and set pointers to them */ + for (i = nrl; i <= nrh; i++) + { + MALLOCARRAY(m[i], (unsigned) (nch - ncl + 1)); + if (m[i] == NULL) + pm_error("Unable to allocate memory for a matrix row."); + m[i] -= ncl; + } + /* return pointer to array of pointers to rows */ + return m; +} + +static void +results (const char * const c, const float * const a) +{ + int i; + + DOT; + fprintf (stdout, "%s", c); + for (i = 0; i < 4; ++i) + fprintf (stdout, "% 1.3e ", a[i]); + fprintf (stdout, "% 1.3e\n", (a[0] + a[1] + a[2] + a[3]) / 4); +} + +static void +simplesrt (int n, float arr[]) +{ + int i, j; + float a; + + for (j = 2; j <= n; j++) + { + a = arr[j]; + i = j - 1; + while (i > 0 && arr[i] > a) + { + arr[i + 1] = arr[i]; + i--; + } + arr[i + 1] = a; + } +} + +static void +mkbalanced (float **a, int n) +{ + int last, j, i; + float s, r, g, f, c, sqrdx; + + sqrdx = RADIX * RADIX; + last = 0; + while (last == 0) + { + last = 1; + for (i = 1; i <= n; i++) + { + r = c = 0.0; + for (j = 1; j <= n; j++) + if (j != i) + { + c += fabs (a[j][i]); + r += fabs (a[i][j]); + } + if (c && r) + { + g = r / RADIX; + f = 1.0; + s = c + r; + while (c < g) + { + f *= RADIX; + c *= sqrdx; + } + g = r * RADIX; + while (c > g) + { + f /= RADIX; + c /= sqrdx; + } + if ((c + r) / f < 0.95 * s) + { + last = 0; + g = 1.0 / f; + for (j = 1; j <= n; j++) + a[i][j] *= g; + for (j = 1; j <= n; j++) + a[j][i] *= f; + } + } + } + } +} + + +static void +reduction (float **a, int n) +{ + int m, j, i; + float y, x; + + for (m = 2; m < n; m++) + { + x = 0.0; + i = m; + for (j = m; j <= n; j++) + { + if (fabs (a[j][m - 1]) > fabs (x)) + { + x = a[j][m - 1]; + i = j; + } + } + if (i != m) + { + for (j = m - 1; j <= n; j++) + SWAP (a[i][j], a[m][j]) + for (j = 1; j <= n; j++) + SWAP (a[j][i], a[j][m]) + a[j][i] = a[j][i]; + } + if (x) + { + for (i = m + 1; i <= n; i++) + { + if ((y = a[i][m - 1])) + { + y /= x; + a[i][m - 1] = y; + for (j = m; j <= n; j++) + a[i][j] -= y * a[m][j]; + for (j = 1; j <= n; j++) + a[j][m] += y * a[j][i]; + } + } + } + } +} + + + +static void +hessenberg (float **a, int n, float wr[], float wi[]) + +{ + int nn, m, l, k, j, its, i, mmin; + float z, y, x, w, v, u, t, s, r, q, p, anorm; + + anorm = fabs (a[1][1]); + for (i = 2; i <= n; i++) + for (j = (i - 1); j <= n; j++) + anorm += fabs (a[i][j]); + nn = n; + t = 0.0; + while (nn >= 1) + { + its = 0; + do + { + for (l = nn; l >= 2; l--) + { + s = fabs (a[l - 1][l - 1]) + fabs (a[l][l]); + if (s == 0.0) + s = anorm; + if ((float) (fabs (a[l][l - 1]) + s) == s) + break; + } + x = a[nn][nn]; + if (l == nn) + { + wr[nn] = x + t; + wi[nn--] = 0.0; + } + else + { + y = a[nn - 1][nn - 1]; + w = a[nn][nn - 1] * a[nn - 1][nn]; + if (l == (nn - 1)) + { + p = 0.5 * (y - x); + q = p * p + w; + z = sqrt (fabs (q)); + x += t; + if (q >= 0.0) + { + z = p + SIGN (z, p); + wr[nn - 1] = wr[nn] = x + z; + if (z) + wr[nn] = x - w / z; + wi[nn - 1] = wi[nn] = 0.0; + } + else + { + wr[nn - 1] = wr[nn] = x + p; + wi[nn - 1] = -(wi[nn] = z); + } + nn -= 2; + } + else + { + if (its == 30) + pm_error("Too many iterations to required " + "to find %s. Giving up", F14); + if (its == 10 || its == 20) + { + t += x; + for (i = 1; i <= nn; i++) + a[i][i] -= x; + s = fabs (a[nn][nn - 1]) + fabs (a[nn - 1][nn - 2]); + y = x = 0.75 * s; + w = -0.4375 * s * s; + } + ++its; + for (m = (nn - 2); m >= l; m--) + { + z = a[m][m]; + r = x - z; + s = y - z; + p = (r * s - w) / a[m + 1][m] + a[m][m + 1]; + q = a[m + 1][m + 1] - z - r - s; + r = a[m + 2][m + 1]; + s = fabs (p) + fabs (q) + fabs (r); + p /= s; + q /= s; + r /= s; + if (m == l) + break; + u = fabs (a[m][m - 1]) * (fabs (q) + fabs (r)); + v = fabs (p) * (fabs (a[m - 1][m - 1]) + fabs (z) + + fabs (a[m + 1][m + 1])); + if ((float) (u + v) == v) + break; + } + for (i = m + 2; i <= nn; i++) + { + a[i][i - 2] = 0.0; + if (i != (m + 2)) + a[i][i - 3] = 0.0; + } + for (k = m; k <= nn - 1; k++) + { + if (k != m) + { + p = a[k][k - 1]; + q = a[k + 1][k - 1]; + r = 0.0; + if (k != (nn - 1)) + r = a[k + 2][k - 1]; + if ((x = fabs (p) + fabs (q) + fabs (r))) + { + p /= x; + q /= x; + r /= x; + } + } + if ((s = SIGN (sqrt (p * p + q * q + r * r), p))) + { + if (k == m) + { + if (l != m) + a[k][k - 1] = -a[k][k - 1]; + } + else + a[k][k - 1] = -s * x; + p += s; + x = p / s; + y = q / s; + z = r / s; + q /= p; + r /= p; + for (j = k; j <= nn; j++) + { + p = a[k][j] + q * a[k + 1][j]; + if (k != (nn - 1)) + { + p += r * a[k + 2][j]; + a[k + 2][j] -= p * z; + } + a[k + 1][j] -= p * y; + a[k][j] -= p * x; + } + mmin = nn < k + 3 ? nn : k + 3; + for (i = l; i <= mmin; i++) + { + p = x * a[i][k] + y * a[i][k + 1]; + if (k != (nn - 1)) + { + p += z * a[i][k + 2]; + a[i][k + 2] -= p * r; + } + a[i][k + 1] -= p * q; + a[i][k] -= p; + } + } + } + } + } + } while (l < nn - 1); + } +} + + + +static float +f1_asm (float **P, int Ng) + +/* Angular Second Moment */ +{ + int i, j; + float sum = 0; + + for (i = 0; i < Ng; ++i) + for (j = 0; j < Ng; ++j) + sum += P[i][j] * P[i][j]; + + return sum; + + /* + * The angular second-moment feature (ASM) f1 is a measure of homogeneity + * of the image. In a homogeneous image, there are very few dominant + * gray-tone transitions. Hence the P matrix for such an image will have + * fewer entries of large magnitude. + */ +} + + +static float +f2_contrast (float **P, int Ng) + +/* Contrast */ +{ + int i, j, n; + float sum = 0, bigsum = 0; + + for (n = 0; n < Ng; ++n) + { + for (i = 0; i < Ng; ++i) + for (j = 0; j < Ng; ++j) + if ((i - j) == n || (j - i) == n) + sum += P[i][j]; + bigsum += n * n * sum; + + sum = 0; + } + return bigsum; + + /* + * The contrast feature is a difference moment of the P matrix and is a + * measure of the contrast or the amount of local variations present in an + * image. + */ +} + +static float +f3_corr (float **P, int Ng) + +/* Correlation */ +{ + int i, j; + float sum_sqrx = 0, sum_sqry = 0, tmp, *px; + float meanx =0 , meany = 0 , stddevx, stddevy; + + px = vector (0, Ng); + for (i = 0; i < Ng; ++i) + px[i] = 0; + + /* + * px[i] is the (i-1)th entry in the marginal probability matrix obtained + * by summing the rows of p[i][j] + */ + for (i = 0; i < Ng; ++i) + for (j = 0; j < Ng; ++j) + px[i] += P[i][j]; + + + /* Now calculate the means and standard deviations of px and py */ + /*- fix supplied by J. Michael Christensen, 21 Jun 1991 */ + /*- further modified by James Darrell McCauley, 16 Aug 1991 + * after realizing that meanx=meany and stddevx=stddevy + */ + for (i = 0; i < Ng; ++i) + { + meanx += px[i]*i; + sum_sqrx += px[i]*i*i; + } + meany = meanx; + sum_sqry = sum_sqrx; + stddevx = sqrt (sum_sqrx - (meanx * meanx)); + stddevy = stddevx; + + /* Finally, the correlation ... */ + for (tmp = 0, i = 0; i < Ng; ++i) + for (j = 0; j < Ng; ++j) + tmp += i*j*P[i][j]; + + return (tmp - meanx * meany) / (stddevx * stddevy); + /* + * This correlation feature is a measure of gray-tone linear-dependencies + * in the image. + */ +} + + +static float +f4_var (float **P, int Ng) + +/* Sum of Squares: Variance */ +{ + int i, j; + float mean = 0, var = 0; + + /*- Corrected by James Darrell McCauley, 16 Aug 1991 + * calculates the mean intensity level instead of the mean of + * cooccurrence matrix elements + */ + for (i = 0; i < Ng; ++i) + for (j = 0; j < Ng; ++j) + mean += i * P[i][j]; + + for (i = 0; i < Ng; ++i) + for (j = 0; j < Ng; ++j) + var += (i + 1 - mean) * (i + 1 - mean) * P[i][j]; + + return var; +} + +static float +f5_idm (float **P, int Ng) + +/* Inverse Difference Moment */ +{ + int i, j; + float idm = 0; + + for (i = 0; i < Ng; ++i) + for (j = 0; j < Ng; ++j) + idm += P[i][j] / (1 + (i - j) * (i - j)); + + return idm; +} + +static float +Pxpy[2 * PGM_MAXMAXVAL]; + +static float +f6_savg (float **P, int Ng) + +/* Sum Average */ +{ + int i, j; + float savg = 0; + + for (i = 0; i <= 2 * Ng; ++i) + Pxpy[i] = 0; + + for (i = 0; i < Ng; ++i) + for (j = 0; j < Ng; ++j) + Pxpy[i + j + 2] += P[i][j]; + for (i = 2; i <= 2 * Ng; ++i) + savg += i * Pxpy[i]; + + return savg; +} + + +static float +f7_svar (float **P, int Ng, float S) { +/* Sum Variance */ + int i, j; + float var = 0; + + for (i = 0; i <= 2 * Ng; ++i) + Pxpy[i] = 0; + + for (i = 0; i < Ng; ++i) + for (j = 0; j < Ng; ++j) + Pxpy[i + j + 2] += P[i][j]; + + for (i = 2; i <= 2 * Ng; ++i) + var += (i - S) * (i - S) * Pxpy[i]; + + return var; +} + +static float +f8_sentropy (float **P, int Ng) + +/* Sum Entropy */ +{ + int i, j; + float sentropy = 0; + + for (i = 0; i <= 2 * Ng; ++i) + Pxpy[i] = 0; + + for (i = 0; i < Ng; ++i) + for (j = 0; j < Ng; ++j) + Pxpy[i + j + 2] += P[i][j]; + + for (i = 2; i <= 2 * Ng; ++i) + sentropy -= Pxpy[i] * log10 (Pxpy[i] + EPSILON); + + return sentropy; +} + + +static float +f9_entropy (float **P, int Ng) + +/* Entropy */ +{ + int i, j; + float entropy = 0; + + for (i = 0; i < Ng; ++i) + for (j = 0; j < Ng; ++j) + entropy += P[i][j] * log10 (P[i][j] + EPSILON); + + return -entropy; +} + + +static float +f10_dvar (float **P, int Ng) + +/* Difference Variance */ +{ + int i, j, tmp; + float sum = 0, sum_sqr = 0, var = 0; + + for (i = 0; i <= 2 * Ng; ++i) + Pxpy[i] = 0; + + for (i = 0; i < Ng; ++i) + for (j = 0; j < Ng; ++j) + Pxpy[abs (i - j)] += P[i][j]; + + /* Now calculate the variance of Pxpy (Px-y) */ + for (i = 0; i < Ng; ++i) + { + sum += Pxpy[i]; + sum_sqr += Pxpy[i] * Pxpy[i]; + } + tmp = Ng * Ng; + var = ((tmp * sum_sqr) - (sum * sum)) / (tmp * tmp); + + return var; +} + +static float +f11_dentropy (float **P, int Ng) + +/* Difference Entropy */ +{ + int i, j; + float sum = 0; + + for (i = 0; i <= 2 * Ng; ++i) + Pxpy[i] = 0; + + for (i = 0; i < Ng; ++i) + for (j = 0; j < Ng; ++j) + Pxpy[abs (i - j)] += P[i][j]; + + for (i = 0; i < Ng; ++i) + sum += Pxpy[i] * log10 (Pxpy[i] + EPSILON); + + return -sum; +} + +static float +f12_icorr (float **P, int Ng) + +/* Information Measures of Correlation */ +{ + int i, j; + float *px, *py; + float hx = 0, hy = 0, hxy = 0, hxy1 = 0, hxy2 = 0; + + px = vector (0, Ng); + py = vector (0, Ng); + + /* + * px[i] is the (i-1)th entry in the marginal probability matrix obtained + * by summing the rows of p[i][j] + */ + for (i = 0; i < Ng; ++i) + { + for (j = 0; j < Ng; ++j) + { + px[i] += P[i][j]; + py[j] += P[i][j]; + } + } + + for (i = 0; i < Ng; ++i) + for (j = 0; j < Ng; ++j) + { + hxy1 -= P[i][j] * log10 (px[i] * py[j] + EPSILON); + hxy2 -= px[i] * py[j] * log10 (px[i] * py[j] + EPSILON); + hxy -= P[i][j] * log10 (P[i][j] + EPSILON); + } + + /* Calculate entropies of px and py - is this right? */ + for (i = 0; i < Ng; ++i) + { + hx -= px[i] * log10 (px[i] + EPSILON); + hy -= py[i] * log10 (py[i] + EPSILON); + } +/* fprintf(stderr,"hxy1=%f\thxy=%f\thx=%f\thy=%f\n",hxy1,hxy,hx,hy); */ + return ((hxy - hxy1) / (hx > hy ? hx : hy)); +} + +static float +f13_icorr (float **P, int Ng) + +/* Information Measures of Correlation */ +{ + int i, j; + float *px, *py; + float hx = 0, hy = 0, hxy = 0, hxy1 = 0, hxy2 = 0; + + px = vector (0, Ng); + py = vector (0, Ng); + + /* + * px[i] is the (i-1)th entry in the marginal probability matrix obtained + * by summing the rows of p[i][j] + */ + for (i = 0; i < Ng; ++i) + { + for (j = 0; j < Ng; ++j) + { + px[i] += P[i][j]; + py[j] += P[i][j]; + } + } + + for (i = 0; i < Ng; ++i) + for (j = 0; j < Ng; ++j) + { + hxy1 -= P[i][j] * log10 (px[i] * py[j] + EPSILON); + hxy2 -= px[i] * py[j] * log10 (px[i] * py[j] + EPSILON); + hxy -= P[i][j] * log10 (P[i][j] + EPSILON); + } + + /* Calculate entropies of px and py */ + for (i = 0; i < Ng; ++i) + { + hx -= px[i] * log10 (px[i] + EPSILON); + hy -= py[i] * log10 (py[i] + EPSILON); + } + /* fprintf(stderr,"hx=%f\thxy2=%f\n",hx,hxy2); */ + return (sqrt (fabs (1 - exp (-2.0 * (hxy2 - hxy))))); +} + +static float +f14_maxcorr (float **P, int Ng) + +/* Returns the Maximal Correlation Coefficient */ +{ + int i, j, k; + float *px, *py, **Q; + float *x, *iy, tmp; + + px = vector (0, Ng); + py = vector (0, Ng); + Q = matrix (1, Ng + 1, 1, Ng + 1); + x = vector (1, Ng); + iy = vector (1, Ng); + + /* + * px[i] is the (i-1)th entry in the marginal probability matrix obtained + * by summing the rows of p[i][j] + */ + for (i = 0; i < Ng; ++i) + { + for (j = 0; j < Ng; ++j) + { + px[i] += P[i][j]; + py[j] += P[i][j]; + } + } + + /* Find the Q matrix */ + for (i = 0; i < Ng; ++i) + { + for (j = 0; j < Ng; ++j) + { + Q[i + 1][j + 1] = 0; + for (k = 0; k < Ng; ++k) + Q[i + 1][j + 1] += P[i][k] * P[j][k] / px[i] / py[k]; + } + } + + /* Balance the matrix */ + mkbalanced (Q, Ng); + /* Reduction to Hessenberg Form */ + reduction (Q, Ng); + /* Finding eigenvalue for nonsymetric matrix using QR algorithm */ + hessenberg (Q, Ng, x, iy); + if (sortit) + simplesrt(Ng,x); + /* Returns the sqrt of the second largest eigenvalue of Q */ + for (i = 2, tmp = x[1]; i <= Ng; ++i) + tmp = (tmp > x[i]) ? tmp : x[i]; + return sqrt (x[Ng - 1]); +} + +int +main (int argc, char *argv[]) { + FILE *ifp; + register gray **grays; + int tone[PGM_MAXMAXVAL], R0, R45, R90, angle, d = 1, x, y; + int argn, rows, cols, row, col; + int itone, jtone, tones; + float **P_matrix0, **P_matrix45, **P_matrix90, **P_matrix135; + float ASM[4], contrast[4], corr[4], var[4], idm[4], savg[4]; + float sentropy[4], svar[4], entropy[4], dvar[4], dentropy[4]; + float icorr[4], maxcorr[4]; + gray maxval; + const char * const usage = "[-d ] [pgmfile]"; + + + pgm_init( &argc, argv ); + + argn = 1; + + /* Check for flags. */ + if ( argn < argc && argv[argn][0] == '-' ) + { + if ( argv[argn][1] == 'd' ) + { + ++argn; + if ( argn == argc || sscanf( argv[argn], "%d", &d ) != 1 ) + pm_usage( usage ); + } + else + pm_usage( usage ); + ++argn; + } + + if ( argn < argc ) + { + ifp = pm_openr( argv[argn] ); + ++argn; + } + else + ifp = stdin; + + if ( argn != argc ) + pm_usage( usage ); + + grays = pgm_readpgm (ifp, &cols, &rows, &maxval); + pm_close (ifp); + + if (maxval > PGM_MAXMAXVAL) + pm_error("The maxval of the image (%d) is too high. \n" + "This program's maximum is %d.", maxval, PGM_MAXMAXVAL); + + /* Determine the number of different gray scales (not maxval) */ + for (row = PGM_MAXMAXVAL; row >= 0; --row) + tone[row] = -1; + for (row = rows - 1; row >= 0; --row) + for (col = 0; col < cols; ++col) + tone[grays[row][col]] = grays[row][col]; + for (row = PGM_MAXMAXVAL, tones = 0; row >= 0; --row) + if (tone[row] != -1) + tones++; + pm_message("(Image has %d graylevels.)", tones); + + /* Collapse array, taking out all zero values */ + for (row = 0, itone = 0; row <= PGM_MAXMAXVAL; row++) + if (tone[row] != -1) + tone[itone++] = tone[row]; + /* Now array contains only the gray levels present (in ascending order) */ + + /* Allocate memory for gray-tone spatial dependence matrix */ + P_matrix0 = matrix (0, tones, 0, tones); + P_matrix45 = matrix (0, tones, 0, tones); + P_matrix90 = matrix (0, tones, 0, tones); + P_matrix135 = matrix (0, tones, 0, tones); + for (row = 0; row < tones; ++row) + for (col = 0; col < tones; ++col) + { + P_matrix0[row][col] = P_matrix45[row][col] = 0; + P_matrix90[row][col] = P_matrix135[row][col] = 0; + } + + /* Find gray-tone spatial dependence matrix */ + fprintf (stderr, "(Computing spatial dependence matrix..."); + for (row = 0; row < rows; ++row) + for (col = 0; col < cols; ++col) + for (x = 0, angle = 0; angle <= 135; angle += 45) + { + while (tone[x] != grays[row][col]) + x++; + if (angle == 0 && col + d < cols) + { + y = 0; + while (tone[y] != grays[row][col + d]) + y++; + P_matrix0[x][y]++; + P_matrix0[y][x]++; + } + if (angle == 90 && row + d < rows) + { + y = 0; + while (tone[y] != grays[row + d][col]) + y++; + P_matrix90[x][y]++; + P_matrix90[y][x]++; + } + if (angle == 45 && row + d < rows && col - d >= 0) + { + y = 0; + while (tone[y] != grays[row + d][col - d]) + y++; + P_matrix45[x][y]++; + P_matrix45[y][x]++; + } + if (angle == 135 && row + d < rows && col + d < cols) + { + y = 0; + while (tone[y] != grays[row + d][col + d]) + y++; + P_matrix135[x][y]++; + P_matrix135[y][x]++; + } + } + /* Gray-tone spatial dependence matrices are complete */ + + /* Find normalizing constants */ + R0 = 2 * rows * (cols - d); + R45 = 2 * (rows - d) * (cols - d); + R90 = 2 * (rows - d) * cols; + + /* Normalize gray-tone spatial dependence matrix */ + for (itone = 0; itone < tones; ++itone) + for (jtone = 0; jtone < tones; ++jtone) + { + P_matrix0[itone][jtone] /= R0; + P_matrix45[itone][jtone] /= R45; + P_matrix90[itone][jtone] /= R90; + P_matrix135[itone][jtone] /= R45; + } + + fprintf (stderr, " done.)\n"); + fprintf (stderr, "(Computing textural features"); + fprintf (stdout, "\n"); + DOT; + fprintf (stdout, + "%s 0 45 90 135 Avg\n", + BL); + + ASM[0] = f1_asm (P_matrix0, tones); + ASM[1] = f1_asm (P_matrix45, tones); + ASM[2] = f1_asm (P_matrix90, tones); + ASM[3] = f1_asm (P_matrix135, tones); + results (F1, ASM); + + contrast[0] = f2_contrast (P_matrix0, tones); + contrast[1] = f2_contrast (P_matrix45, tones); + contrast[2] = f2_contrast (P_matrix90, tones); + contrast[3] = f2_contrast (P_matrix135, tones); + results (F2, contrast); + + + corr[0] = f3_corr (P_matrix0, tones); + corr[1] = f3_corr (P_matrix45, tones); + corr[2] = f3_corr (P_matrix90, tones); + corr[3] = f3_corr (P_matrix135, tones); + results (F3, corr); + + var[0] = f4_var (P_matrix0, tones); + var[1] = f4_var (P_matrix45, tones); + var[2] = f4_var (P_matrix90, tones); + var[3] = f4_var (P_matrix135, tones); + results (F4, var); + + + idm[0] = f5_idm (P_matrix0, tones); + idm[1] = f5_idm (P_matrix45, tones); + idm[2] = f5_idm (P_matrix90, tones); + idm[3] = f5_idm (P_matrix135, tones); + results (F5, idm); + + savg[0] = f6_savg (P_matrix0, tones); + savg[1] = f6_savg (P_matrix45, tones); + savg[2] = f6_savg (P_matrix90, tones); + savg[3] = f6_savg (P_matrix135, tones); + results (F6, savg); + + sentropy[0] = f8_sentropy (P_matrix0, tones); + sentropy[1] = f8_sentropy (P_matrix45, tones); + sentropy[2] = f8_sentropy (P_matrix90, tones); + sentropy[3] = f8_sentropy (P_matrix135, tones); + svar[0] = f7_svar (P_matrix0, tones, sentropy[0]); + svar[1] = f7_svar (P_matrix45, tones, sentropy[1]); + svar[2] = f7_svar (P_matrix90, tones, sentropy[2]); + svar[3] = f7_svar (P_matrix135, tones, sentropy[3]); + results (F7, svar); + results (F8, sentropy); + + entropy[0] = f9_entropy (P_matrix0, tones); + entropy[1] = f9_entropy (P_matrix45, tones); + entropy[2] = f9_entropy (P_matrix90, tones); + entropy[3] = f9_entropy (P_matrix135, tones); + results (F9, entropy); + + dvar[0] = f10_dvar (P_matrix0, tones); + dvar[1] = f10_dvar (P_matrix45, tones); + dvar[2] = f10_dvar (P_matrix90, tones); + dvar[3] = f10_dvar (P_matrix135, tones); + results (F10, dvar); + + dentropy[0] = f11_dentropy (P_matrix0, tones); + dentropy[1] = f11_dentropy (P_matrix45, tones); + dentropy[2] = f11_dentropy (P_matrix90, tones); + dentropy[3] = f11_dentropy (P_matrix135, tones); + results (F11, dentropy); + + icorr[0] = f12_icorr (P_matrix0, tones); + icorr[1] = f12_icorr (P_matrix45, tones); + icorr[2] = f12_icorr (P_matrix90, tones); + icorr[3] = f12_icorr (P_matrix135, tones); + results (F12, icorr); + + icorr[0] = f13_icorr (P_matrix0, tones); + icorr[1] = f13_icorr (P_matrix45, tones); + icorr[2] = f13_icorr (P_matrix90, tones); + icorr[3] = f13_icorr (P_matrix135, tones); + results (F13, icorr); + + maxcorr[0] = f14_maxcorr (P_matrix0, tones); + maxcorr[1] = f14_maxcorr (P_matrix45, tones); + maxcorr[2] = f14_maxcorr (P_matrix90, tones); + maxcorr[3] = f14_maxcorr (P_matrix135, tones); + results (F14, maxcorr); + + + fprintf (stderr, " done.)\n"); + + return 0; +} diff --git a/analyzer/pnmhistmap.c b/analyzer/pnmhistmap.c new file mode 100644 index 00000000..0b1eeb1f --- /dev/null +++ b/analyzer/pnmhistmap.c @@ -0,0 +1,483 @@ +/* pnmhistmap.c - + * Draw a histogram for a PGM or PPM file + * + * Options: -verbose: the usual + * -max N: force scaling value to N + * -black: ignore all-black count + * -white: ignore all-white count + * + * - PGM histogram is a PBM file, PPM histogram is a PPM file + * - No conditional code - assumes all three: PBM, PGM, PPM + * + * Copyright (C) 1993 by Wilson H. Bent, Jr (whb@usc.edu) + * + * 2004-12-11 john h. dubois iii (john@armory.com) + * - Added options: + * -dots, -nmax, -red, -green, -blue, -width, -height, -lval, -rval + * - Deal properly with maxvals other than 256 + */ + +#include + +#include "pnm.h" +#include "shhopt.h" +#include "mallocvar.h" + +static double const epsilon = .00001; + +#define SCALE_H(value) (hscale_unity ? (value) : (int)((value) * hscale)) + +enum wantedColor {WANT_RED=0, WANT_GRN=1, WANT_BLU=2}; + +struct cmdlineInfo { + /* All the information the user supplied in the command line, + in a form easy for the program to use. + */ + const char *inputFilespec; /* Filespecs of input files */ + unsigned int black; + unsigned int white; + unsigned int dots; + bool colorWanted[3]; + /* subscript is enum wantedColor */ + unsigned int verbose; + unsigned int nmaxSpec; + float nmax; + unsigned int lval; + unsigned int rval; + unsigned int widthSpec; + unsigned int width; + unsigned int height; +}; + + + +static void +parseCommandLine(int argc, char ** argv, + struct cmdlineInfo *cmdlineP) { +/*---------------------------------------------------------------------------- + Note that the file spec array we return is stored in the storage that + was passed to us as the argv array. +-----------------------------------------------------------------------------*/ + optEntry *option_def; + /* Instructions to optParseOptions3 on how to parse our options. + */ + optStruct3 opt; + + unsigned int option_def_index; + unsigned int lvalSpec, rvalSpec, heightSpec; + unsigned int redSpec, greenSpec, blueSpec; + + MALLOCARRAY_NOFAIL(option_def, 100); + + option_def_index = 0; /* incremented by OPTENT3 */ + OPTENT3(0, "black", OPT_FLAG, NULL, &cmdlineP->black, 0); + OPTENT3(0, "white", OPT_FLAG, NULL, &cmdlineP->white, 0); + OPTENT3(0, "dots", OPT_FLAG, NULL, &cmdlineP->dots, 0); + OPTENT3(0, "red", OPT_FLAG, NULL, &redSpec, 0); + OPTENT3(0, "green", OPT_FLAG, NULL, &greenSpec, 0); + OPTENT3(0, "blue", OPT_FLAG, NULL, &blueSpec, 0); + OPTENT3(0, "verbose", OPT_FLAG, NULL, &cmdlineP->verbose, 0); + OPTENT3(0, "nmax", OPT_FLOAT, &cmdlineP->nmax, + &cmdlineP->nmaxSpec, 0); + OPTENT3(0, "lval", OPT_UINT, &cmdlineP->lval, + &lvalSpec, 0); + OPTENT3(0, "rval", OPT_UINT, &cmdlineP->rval, + &rvalSpec, 0); + OPTENT3(0, "width", OPT_UINT, &cmdlineP->width, + &cmdlineP->widthSpec, 0); + OPTENT3(0, "height", OPT_UINT, &cmdlineP->height, + &heightSpec, 0); + + opt.opt_table = option_def; + opt.short_allowed = FALSE; /* We have no short (old-fashioned) options */ + opt.allowNegNum = FALSE; /* We may have parms that are negative numbers */ + + optParseOptions3(&argc, argv, opt, sizeof(opt), 0); + /* Uses and sets argc, argv, and some of *cmdlineP and others. */ + + if (!lvalSpec) + cmdlineP->lval = 0; + if (!rvalSpec) + cmdlineP->rval = PNM_OVERALLMAXVAL; + + if (!redSpec && !greenSpec && !blueSpec) { + cmdlineP->colorWanted[WANT_RED] = TRUE; + cmdlineP->colorWanted[WANT_GRN] = TRUE; + cmdlineP->colorWanted[WANT_BLU] = TRUE; + } else { + cmdlineP->colorWanted[WANT_RED] = redSpec; + cmdlineP->colorWanted[WANT_GRN] = greenSpec; + cmdlineP->colorWanted[WANT_BLU] = blueSpec; + } + + if (!heightSpec) + cmdlineP->height = 200; + + if (argc-1 == 0) + cmdlineP->inputFilespec = "-"; + else if (argc-1 != 1) + pm_error("Program takes zero or one argument (filename). You " + "specified %d", argc-1); + else + cmdlineP->inputFilespec = argv[1]; +} + + + +static unsigned int +maxSlotCount(const unsigned int * const hist, + unsigned int const hist_width, + bool const no_white, + bool const no_black) { +/*---------------------------------------------------------------------------- + Return the maximum count among all the slots in hist[], not counting + the first and last as suggested by 'no_white' and 'no_black'. +-----------------------------------------------------------------------------*/ + unsigned int hmax; + unsigned int i; + + unsigned int const start = (no_black ? 1 : 0); + unsigned int const finish = (no_white ? hist_width - 1 : hist_width); + for (hmax = 0, i = start; i < finish; ++i) + if (hmax < hist[i]) + hmax = hist[i]; + + return hmax; +} + + + +static void +clipHistogram(unsigned int * const hist, + unsigned int const hist_width, + unsigned int const hmax) { + + unsigned int i; + + for (i = 0; i < hist_width; ++i) + hist[i] = MIN(hmax, hist[i]); +} + + + +static void +pgm_hist(FILE * const fp, + int const cols, + int const rows, + xelval const maxval, + int const format, + bool const dots, + bool const no_white, + bool const no_black, + bool const verbose, + xelval const startval, + xelval const endval, + unsigned int const hist_width, + unsigned int const hist_height, + bool const clipSpec, + unsigned int const clipCount, + double const hscale) { + + bool const hscale_unity = hscale - 1 < epsilon; + + gray * grayrow; + bit ** bits; + int i, j; + unsigned int * ghist; + double vscale; + unsigned int hmax; + + if ((ghist = calloc(hist_width, sizeof(int))) == NULL) + pm_error ("Not enough memory for histogram array (%d bytes)", + hist_width * sizeof(int)); + if ((bits = pbm_allocarray (hist_width, hist_height)) == NULL) + pm_error ("no space for output array (%d bits)", + hist_width * hist_height); + memset (ghist, 0, sizeof (ghist)); + + /* read the pixel values into the histogram arrays */ + grayrow = pgm_allocrow (cols); + /*XX error-check! */ + if (verbose) pm_message ("making histogram..."); + for (i = rows; i > 0; --i) { + pgm_readpgmrow (fp, grayrow, cols, maxval, format); + for (j = cols-1; j >= 0; --j) { + int value; + + if ((value = grayrow[j]) >= startval && value <= endval) + ghist[SCALE_H(value-startval)]++; + } + } + pgm_freerow (grayrow); + fclose (fp); + + /* find the highest-valued slot and set the vertical scale value */ + if (verbose) + pm_message ("finding max. slot height..."); + if (clipSpec) + hmax = clipCount; + else + hmax = maxSlotCount(ghist, hist_width, no_white, no_black); + + if (verbose) + pm_message ("Done: height = %u", hmax); + + clipHistogram(ghist, hist_width, hmax); + + vscale = (double) hist_height / hmax; + + for (i = 0; i < hist_width; ++i) { + int mark = hist_height - (int)(vscale * ghist[i]); + for (j = 0; j < mark; ++j) + bits[j][i] = PBM_BLACK; + if (j < hist_height) + bits[j++][i] = PBM_WHITE; + for ( ; j < hist_height; ++j) + bits[j][i] = dots ? PBM_BLACK : PBM_WHITE; + } + + pbm_writepbm (stdout, bits, hist_width, hist_height, 0); +} + + + +static unsigned int +maxSlotCountAll(unsigned int * const hist[3], + unsigned int const hist_width, + bool const no_white, + bool const no_black) { +/*---------------------------------------------------------------------------- + Return the maximum count among all the slots in hist[x] not + counting the first and last as suggested by 'no_white' and + 'no_black'. hist[x] may be NULL to indicate none. +-----------------------------------------------------------------------------*/ + unsigned int hmax; + unsigned int color; + + hmax = 0; + + for (color = 0; color < 3; ++color) + if (hist[color]) + hmax = MAX(hmax, + maxSlotCount(hist[color], + hist_width, no_white, no_black)); + + return hmax; +} + + + +static void +createHist(bool const colorWanted[3], + unsigned int const hist_width, + unsigned int * (* const histP)[3]) { +/*---------------------------------------------------------------------------- + Allocate the histogram arrays and set each slot count to zero. +-----------------------------------------------------------------------------*/ + unsigned int color; + + for (color = 0; color < 3; ++color) + if (colorWanted[color]) { + unsigned int * hist; + unsigned int i; + MALLOCARRAY(hist, hist_width); + if (hist == NULL) + pm_error ("Not enough memory for histogram arrays (%u bytes)", + hist_width * sizeof(int) * 3); + + for (i = 0; i < hist_width; ++i) + hist[i] = 0; + (*histP)[color] = hist; + } else + (*histP)[color] = NULL; +} + + + +static void +clipHistogramAll(unsigned int * const hist[3], + unsigned int const hist_width, + unsigned int const hmax) { + + unsigned int color; + + for (color = 0; color < 3; ++color) + if (hist[color]) + clipHistogram(hist[color], hist_width, hmax); +} + + + +static void +ppm_hist(FILE * const fp, + int const cols, + int const rows, + xelval const maxval, + int const format, + bool const dots, + bool const no_white, + bool const no_black, + bool const colorWanted[3], + bool const verbose, + xelval const startval, + xelval const endval, + unsigned int const hist_width, + unsigned int const hist_height, + bool const clipSpec, + unsigned int const clipCount, + double const hscale) { + + bool const hscale_unity = hscale - 1 < epsilon; + + pixel *pixrow; + pixel **pixels; + int i, j; + unsigned int * hist[3]; /* Subscript is enum wantedColor */ + double vscale; + unsigned int hmax; + + createHist(colorWanted, hist_width, &hist); + + if ((pixels = ppm_allocarray (hist_width, hist_height)) == NULL) + pm_error ("no space for output array (%d pixels)", + hist_width * hist_height); + for (i = 0; i < hist_height; ++i) + memset (pixels[i], 0, hist_width * sizeof (pixel)); + + /* read the pixel values into the histogram arrays */ + pixrow = ppm_allocrow (cols); + /*XX error-check! */ + if (verbose) pm_message ("making histogram..."); + for (i = rows; i > 0; --i) { + ppm_readppmrow (fp, pixrow, cols, maxval, format); + for (j = cols-1; j >= 0; --j) { + int value; + + if (colorWanted[WANT_RED] && + (value = PPM_GETR(pixrow[j])) >= startval && + value <= endval) + hist[WANT_RED][SCALE_H(value-startval)]++; + if (colorWanted[WANT_GRN] && + (value = PPM_GETG(pixrow[j])) >= startval && + value <= endval) + hist[WANT_GRN][SCALE_H(value-startval)]++; + if (colorWanted[WANT_BLU] && + (value = PPM_GETB(pixrow[j])) >= startval && + value <= endval) + hist[WANT_BLU][SCALE_H(value-startval)]++; + } + } + ppm_freerow (pixrow); + fclose (fp); + + /* find the highest-valued slot and set the vertical scale value */ + if (verbose) + pm_message ("finding max. slot height..."); + if (clipSpec) + hmax = clipCount; + else + hmax = maxSlotCountAll(hist, hist_width, no_white, no_black); + + clipHistogramAll(hist, hist_width, hmax); + + vscale = (double) hist_height / hmax; + if (verbose) + pm_message("Done: height = %d, vertical scale factor = %g", + hmax, vscale); + + for (i = 0; i < hist_width; ++i) { + if (hist[WANT_RED]) { + unsigned int j; + bool plotted; + plotted = FALSE; + for (j = hist_height - (int)(vscale * hist[WANT_RED][i]); + j < hist_height && !plotted; + ++j) { + PPM_PUTR(pixels[j][i], maxval); + plotted = dots; + } + } + if (hist[WANT_GRN]) { + unsigned int j; + bool plotted; + plotted = FALSE; + for (j = hist_height - (int)(vscale * hist[WANT_GRN][i]); + j < hist_height && !plotted; + ++j) { + PPM_PUTG(pixels[j][i], maxval); + plotted = dots; + } + } + if (hist[WANT_BLU]) { + unsigned int j; + bool plotted; + plotted = FALSE; + for (j = hist_height - (int)(vscale * hist[WANT_BLU][i]); + j < hist_height && !plotted; + ++j) { + PPM_PUTB(pixels[j][i], maxval); + plotted = dots; + } + } + } + ppm_writeppm (stdout, pixels, hist_width, hist_height, maxval, 0); +} + + + +int +main (int argc, char ** argv) { + + struct cmdlineInfo cmdline; + FILE* ifP; + int cols, rows; + xelval maxval; + int format; + unsigned int hist_width; + unsigned int range; + double hscale; + int hmax; + + pnm_init (&argc, argv); + + parseCommandLine(argc, argv, &cmdline); + + ifP = pm_openr(cmdline.inputFilespec); + + pnm_readpnminit(ifP, &cols, &rows, &maxval, &format); + + range = MIN(maxval, cmdline.rval) - cmdline.lval + 1; + + if (cmdline.widthSpec) + hist_width = cmdline.width; + else + hist_width = range; + + hscale = (float)hist_width / range; + if (hscale - 1.0 < epsilon && cmdline.verbose) + pm_message("Horizontal scale factor: %g (maxval = %u)", + hscale, maxval); + + if (cmdline.nmaxSpec) + hmax = cols * rows / hist_width * cmdline.nmax; + + switch (PNM_FORMAT_TYPE(format)) { + case PPM_TYPE: + ppm_hist(ifP, cols, rows, maxval, format, + cmdline.dots, cmdline.white, cmdline.black, + cmdline.colorWanted, + cmdline.verbose, cmdline.lval, cmdline.rval, + hist_width, cmdline.height, cmdline.nmaxSpec, hmax, hscale); + break; + case PGM_TYPE: + pgm_hist(ifP, cols, rows, maxval, format, + cmdline.dots, cmdline.white, cmdline.black, + cmdline.verbose, cmdline.lval, cmdline.rval, + hist_width, cmdline.height, cmdline.nmaxSpec, hmax, hscale); + break; + case PBM_TYPE: + pm_error("Cannot do a histogram of a a PBM file"); + break; + } + return 0; +} diff --git a/analyzer/pnmpsnr.c b/analyzer/pnmpsnr.c new file mode 100644 index 00000000..4a6bfe56 --- /dev/null +++ b/analyzer/pnmpsnr.c @@ -0,0 +1,209 @@ +/* + * pnmpsnr.c: Compute error (RMSE, PSNR) between images + * + * + * Derived from pnmpnsmr by Ulrich Hafner, part of his fiasco package, + * On 2001.03.04. + + * Copyright (C) 1994-2000 Ullrich Hafner + */ + +#include +#include +#include + +#include "pm_c_util.h" +#include "pam.h" + +#define MAXFILES 16 + +static int +udiff(unsigned int const subtrahend, unsigned int const subtractor) { + return subtrahend-subtractor; +} + + +static double +square(double const arg) { + return(arg*arg); +} + + +static void +validate_input(const struct pam pam1, const struct pam pam2) { + + if (pam1.width != pam2.width) + pm_error("images are not the same width, so can't be compared. " + "The first is %d columns wide, " + "while the second is %d columns wide.", + pam1.width, pam2.width); + if (pam1.height != pam2.height) + pm_error("images are not the same height, so can't be compared. " + "The first is %d rows high, " + "while the second is %d rows high.", + pam1.height, pam2.height); + + if (pam1.maxval != pam2.maxval) + pm_error("images do not have the same maxval. This programs works " + "only on like maxvals. " + "The first image has maxval %u, " + "while the second has %u. Use Pnmdepth to change the " + "maxval of one of them.", + (unsigned int) pam1.maxval, (unsigned int) pam2.maxval); + + if (strcmp(pam1.tuple_type, pam2.tuple_type) != 0) + pm_error("images are not of the same type. The tuple types are " + "'%s' and '%s', respectively.", + pam1.tuple_type, pam2.tuple_type); + + if (strcmp(pam1.tuple_type, PAM_PBM_TUPLETYPE) != 0 && + strcmp(pam1.tuple_type, PAM_PGM_TUPLETYPE) != 0 && + strcmp(pam1.tuple_type, PAM_PPM_TUPLETYPE) != 0) + pm_error("Images are not of a PNM type. Tuple type is '%s'", + pam1.tuple_type); +} + + + +static void +psnr_color(tuple const tuple1, tuple const tuple2, + double * const ySqDiffP, + double * const cbSqDiffP, double * const crSqDiffP) { + + double y1, y2, cb1, cb2, cr1, cr2; + + pnm_YCbCrtuple(tuple1, &y1, &cb1, &cr1); + pnm_YCbCrtuple(tuple2, &y2, &cb2, &cr2); + + *ySqDiffP = square(y1 - y2); + *cbSqDiffP = square(cb1 - cb2); + *crSqDiffP = square(cr1 - cr2); +} + + + +static void +reportPsnr(struct pam const pam1, struct pam const pam2, + double const ySumSqDiff, + double const crSumSqDiff, double const cbSumSqDiff, + const char filespec1[], const char filespec2[]) { + + bool const color = (strcmp(pam1.tuple_type, PAM_PPM_TUPLETYPE) == 0); + + /* The PSNR is the mean of the sum of squares of the differences, + normalized to the range 0..1 + */ + double const yPsnr = ySumSqDiff + / (pam1.width * pam1.height) + / square(pam1.maxval); + + if (color) { + double const cbPsnr = cbSumSqDiff + / (pam1.width * pam1.height) + / square(pam1.maxval); + double const crPsnr = crSumSqDiff + / (pam1.width * pam1.height) + / (pam1.maxval * pam2.maxval); + + pm_message("PSNR between %s and %s:", filespec1, filespec2); + if (yPsnr > 1e-9) + pm_message("Y color component: %.2f dB", 10 * log10(1/yPsnr)); + else + pm_message("Y color component does not differ."); + if (cbPsnr > 1e-9) + pm_message("Cb color component: %.2f dB", 10 * log10(1/cbPsnr)); + else + pm_message("Cb color component does not differ."); + if (crPsnr > 1e-9) + pm_message("Cr color component: %.2f dB", 10 * log10(1/crPsnr)); + else + pm_message("Cr color component does not differ."); + } else { + if (yPsnr > 1e-9) + pm_message("PSNR between %s and %s: %.2f dB", + filespec1, filespec2, 10 * log10(1/yPsnr)); + else + pm_message("Images %s and %s don't differ.", + filespec1, filespec2); + } +} + + + +int +main (int argc, char **argv) { + char *filespec1, *filespec2; /* specs of two files to compare */ + FILE *file1, *file2; + struct pam pam1, pam2; + bool color; + /* It's a color image */ + double ySumSqDiff, crSumSqDiff, cbSumSqDiff; + tuple *tuplerow1, *tuplerow2; /* malloc'ed */ + int row; + + pnm_init(&argc, argv); + + if (argc < 2) + pm_error("Takes two arguments: specifications of the two files."); + else { + filespec1 = argv[1]; + filespec2 = argv[2]; + } + + file1 = pm_openr(filespec1); + file2 = pm_openr(filespec2); + + pnm_readpaminit(file1, &pam1, PAM_STRUCT_SIZE(tuple_type)); + pnm_readpaminit(file2, &pam2, PAM_STRUCT_SIZE(tuple_type)); + + validate_input(pam1, pam2); + + if (strcmp(pam1.tuple_type, PAM_PPM_TUPLETYPE) == 0) + color = TRUE; + else + color = FALSE; + + tuplerow1 = pnm_allocpamrow(&pam1); + tuplerow2 = pnm_allocpamrow(&pam2); + + ySumSqDiff = 0.0; + cbSumSqDiff = 0.0; + crSumSqDiff = 0.0; + + for (row = 0; row < pam1.height; ++row) { + int col; + + pnm_readpamrow(&pam1, tuplerow1); + pnm_readpamrow(&pam2, tuplerow2); + + for (col = 0; col < pam1.width; ++col) { + if (color) { + double ySqDiff, cbSqDiff, crSqDiff; + psnr_color(tuplerow1[col], tuplerow2[col], + &ySqDiff, &cbSqDiff, &crSqDiff); + ySumSqDiff += ySqDiff; + cbSumSqDiff += cbSqDiff; + crSumSqDiff += crSqDiff; + + } else { + unsigned int yDiffSq; + yDiffSq = square(udiff(tuplerow1[col][0], tuplerow2[col][0])); + ySumSqDiff += yDiffSq; + } + } + } + + reportPsnr(pam1, pam2, ySumSqDiff, crSumSqDiff, cbSumSqDiff, + filespec1, filespec2); + + pnm_freepamrow(tuplerow1); + pnm_freepamrow(tuplerow2); + + return 0; +} + + + + + + diff --git a/analyzer/ppmhist.c b/analyzer/ppmhist.c new file mode 100644 index 00000000..4c4d3c55 --- /dev/null +++ b/analyzer/ppmhist.c @@ -0,0 +1,290 @@ +/* ppmhist.c - read a PPM image and compute a color histogram +** +** Copyright (C) 1989 by Jef Poskanzer. +** +** Permission to use, copy, modify, and distribute this software and its +** documentation for any purpose and without fee is hereby granted, provided +** that the above copyright notice appear in all copies and that both that +** copyright notice and this permission notice appear in supporting +** documentation. This software is provided "as is" without express or +** implied warranty. +*/ + +#include + +#include "ppm.h" +#include "shhopt.h" +#include "nstring.h" + +enum sort {SORT_BY_FREQUENCY, SORT_BY_RGB}; + +enum colorFmt {FMT_DECIMAL, FMT_HEX, FMT_FLOAT, FMT_PPMPLAIN}; + +struct cmdline_info { + /* All the information the user supplied in the command line, + in a form easy for the program to use. + */ + const char *input_filespec; /* Filespecs of input files */ + unsigned int noheader; /* -noheader option */ + enum colorFmt colorFmt; + unsigned int colorname; /* -colorname option */ + enum sort sort; /* -sort option */ +}; + + + +static void +parse_command_line(int argc, char ** argv, + struct cmdline_info * const cmdlineP) { +/*---------------------------------------------------------------------------- + Note that the file spec array we return is stored in the storage that + was passed to us as the argv array. +-----------------------------------------------------------------------------*/ + optStruct3 opt; /* set by OPTENT3 */ + optEntry *option_def = malloc(100*sizeof(optEntry)); + unsigned int option_def_index; + + unsigned int hexcolorOpt, floatOpt, mapOpt, nomapOpt; + const char * sort_type; + + option_def_index = 0; /* incremented by OPTENTRY */ + OPTENT3(0, "map", OPT_FLAG, NULL, &mapOpt, 0); + OPTENT3(0, "nomap", OPT_FLAG, NULL, &nomapOpt, 0); + OPTENT3(0, "noheader", OPT_FLAG, NULL, &cmdlineP->noheader, 0); + OPTENT3(0, "hexcolor", OPT_FLAG, NULL, &hexcolorOpt, 0); + OPTENT3(0, "float", OPT_FLAG, NULL, &floatOpt, 0); + OPTENT3(0, "colorname", OPT_FLAG, NULL, &cmdlineP->colorname, 0); + OPTENT3(0, "sort", OPT_STRING, &sort_type, NULL, 0); + + opt.opt_table = option_def; + opt.short_allowed = FALSE; /* We have no short (old-fashioned) options */ + opt.allowNegNum = FALSE; /* We have no parms that are negative numbers */ + + /* Set defaults */ + sort_type = "frequency"; + + optParseOptions3(&argc, argv, opt, sizeof(opt), 0); + /* Uses and sets argc, argv, and some of *cmdlineP and others. */ + + if (argc-1 == 0) + cmdlineP->input_filespec = "-"; + else if (argc-1 != 1) + pm_error("Program takes zero or one argument (filename). You " + "specified %d", argc-1); + else + cmdlineP->input_filespec = argv[1]; + + if (hexcolorOpt + floatOpt + mapOpt > 1) + pm_error("You can specify only one of -hexcolor, -float, and -map"); + if (hexcolorOpt) + cmdlineP->colorFmt = FMT_HEX; + else if (floatOpt) + cmdlineP->colorFmt = FMT_FLOAT; + else if (mapOpt) + cmdlineP->colorFmt = FMT_PPMPLAIN; + else + cmdlineP->colorFmt = FMT_DECIMAL; + + if (strcmp(sort_type, "frequency") == 0) + cmdlineP->sort = SORT_BY_FREQUENCY; + else if (strcmp(sort_type, "rgb") == 0) + cmdlineP->sort = SORT_BY_RGB; + else + pm_error("Invalid -sort value: '%s'. The valid values are " + "'frequency' and 'rgb'.", sort_type); +} + + + +static int +countcompare(const void *ch1, const void *ch2) { + return ((colorhist_vector)ch2)->value - ((colorhist_vector)ch1)->value; +} + + +static int +rgbcompare(const void * arg1, const void * arg2) { + + colorhist_vector const ch1 = (colorhist_vector) arg1; + colorhist_vector const ch2 = (colorhist_vector) arg2; + + int retval; + + retval = (PPM_GETR(ch1->color) - PPM_GETR(ch2->color)); + if (retval == 0) { + retval = (PPM_GETG(ch1->color) - PPM_GETG(ch2->color)); + if (retval == 0) + retval = (PPM_GETB(ch1->color) - PPM_GETB(ch2->color)); + } + return retval; +} + + + +static const char * +colornameLabel(pixel const color, + pixval const maxval, + unsigned int const nDictColor, + pixel const dictColors[], + const char * const dictColornames[]) { +/*---------------------------------------------------------------------------- + Return the name of the color 'color' or the closest color in the + dictionary to it. If the name returned is not the exact color, + prefix it with "*". Otherwise, prefix it with " ". + + 'nDictColor', dictColors[], and dictColorNames[] are the color + dictionary. + + Return the name in static storage within this subroutine. +-----------------------------------------------------------------------------*/ + static char retval[32]; + int colorIndex; + + pixel color255; + /* The color, normalized to a maxval of 255: the maxval of a color + dictionary. + */ + + PPM_DEPTH(color255, color, maxval, 255); + + colorIndex = ppm_findclosestcolor(dictColors, nDictColor, &color); + + assert(colorIndex >= 0 && colorIndex < nDictColor); + + if (PPM_EQUAL(dictColors[colorIndex], color)) + STRSCPY(retval, " "); + else + STRSCPY(retval, "*"); + + STRSCAT(retval, dictColornames[colorIndex]); + + return retval; +} + + + +static void +printColors(colorhist_vector const chv, + int const nColors, + pixval const maxval, + enum colorFmt const colorFmt, + unsigned int const nKnown, + pixel const knownColors[], + const char * const colornames[]) { + + int i; + + for (i = 0; i < nColors; i++) { + pixval const r = PPM_GETR(chv[i].color); + pixval const g = PPM_GETG(chv[i].color); + pixval const b = PPM_GETB(chv[i].color); + double const lum = PPM_LUMIN(chv[i].color); + unsigned int const intLum = lum + 0.5; + double const floatLum = lum / maxval; + unsigned int const count = chv[i].value; + + const char * colornameValue; + + if (colornames) + colornameValue = colornameLabel(chv[i].color, maxval, + nKnown, knownColors, colornames); + else + colornameValue = ""; + + switch(colorFmt) { + case FMT_FLOAT: + printf(" %1.3f %1.3f %1.3f\t%1.3f\t%7d %s\n", + (double)r / maxval, + (double)g / maxval, + (double)b / maxval, + floatLum, count, colornameValue); + break; + case FMT_HEX: + printf(" %04x %04x %04x\t%5d\t%7d %s\n", + r, g, b, intLum, count, colornameValue); + break; + case FMT_DECIMAL: + printf(" %5d %5d %5d\t%5d\t%7d %s\n", + r, g, b, intLum, count, colornameValue); + break; + case FMT_PPMPLAIN: + printf(" %5d %5d %5d#\t%5d\t%7d %s\n", + r, g, b, intLum, count, colornameValue); + break; + } + } +} + + + +int +main(int argc, char *argv[] ) { + struct cmdline_info cmdline; + FILE* ifP; + colorhist_vector chv; + int rows, cols; + pixval maxval; + int format; + int nColors; + int (*compare_function)(const void *, const void *); + /* The compare function to be used with qsort() to sort the + histogram for output + */ + unsigned int nDictColor; + const char ** dictColornames; + pixel * dictColors; + + ppm_init( &argc, argv ); + + parse_command_line(argc, argv, &cmdline); + + ifP = pm_openr(cmdline.input_filespec); + + ppm_readppminit(ifP, &cols, &rows, &maxval, &format); + + chv = ppm_computecolorhist2(ifP, cols, rows, maxval, format, 0, &nColors); + + pm_close(ifP); + + switch (cmdline.sort) { + case SORT_BY_FREQUENCY: + compare_function = countcompare; break; + case SORT_BY_RGB: + compare_function = rgbcompare; break; + } + + qsort((char*) chv, nColors, sizeof(struct colorhist_item), + compare_function); + + /* And print the histogram. */ + if (cmdline.colorFmt == FMT_PPMPLAIN) + printf("P3\n# color map\n%d 1\n%d\n", nColors, maxval); + + if (!cmdline.noheader) { + const char commentDelim = cmdline.colorFmt == FMT_PPMPLAIN ? '#' : ' '; + printf("%c r g b \t lum \t count %s\n", + commentDelim, cmdline.colorname ? "name" : ""); + printf("%c----- ----- ----- \t-----\t------- %s\n", + commentDelim, cmdline.colorname ? "----" : ""); + } + if (cmdline.colorname) { + bool mustOpenTrue = TRUE; + ppm_readcolordict(NULL, mustOpenTrue, + &nDictColor, &dictColornames, &dictColors, NULL); + } else { + dictColors = NULL; + dictColornames = NULL; + } + + printColors(chv, nColors, maxval, + cmdline.colorFmt, nDictColor, dictColors, dictColornames); + + if (dictColors) + free(dictColors); + if (dictColornames) + free(dictColornames); + + ppm_freecolorhist(chv); + + return 0; +} diff --git a/build_complete b/build_complete new file mode 100644 index 00000000..e7113111 --- /dev/null +++ b/build_complete @@ -0,0 +1 @@ +EXISTENCE OF THIS FILE MEANS NETPBM HAS BEEN BUILT. diff --git a/buildtools/Makefile b/buildtools/Makefile new file mode 100644 index 00000000..63da1adf --- /dev/null +++ b/buildtools/Makefile @@ -0,0 +1,46 @@ +ifeq ($(SRCDIR)x,x) + SRCDIR = $(CURDIR)/.. + BUILDDIR = $(SRCDIR) +endif +SUBDIR = buildtools +VPATH = .:$(SRCDIR)/$(SUBDIR) +include $(BUILDDIR)/Makefile.config + +MERGE_OBJECTS = + +# These are programs that are used by the make files: +PROGS = libopt typegen endiangen + +all: $(PROGS) + +BINARIES = +SCRIPTS = + +OMIT_BUILDTOOL_RULE = 1 +include $(SRCDIR)/Makefile.common + +ifdef DLLVER +STRIP_DLL_VERSION=-DDLLVERSTR="\"$(DLLVER)\"" +endif + +ifeq ($(LINKER_CAN_DO_EXPLICIT_LIBRARY),Y) +EXPLICIT=-DEXPLICIT +endif + +libopt.o: libopt.c + $(CC_FOR_BUILD) -c $(CFLAGS_FOR_BUILD) \ + -DSHLIBPREFIXLIST="\"$(SHLIBPREFIXLIST)\"" \ + $(STRIP_DLL_VERSION) $(EXPLICIT) $(CFLAGS_PERSONAL) $(CADD) \ + -o $@ $< + +typegen.o endiangen.o:%.o:%.c + $(CC_FOR_BUILD) -c $(CFLAGS_FOR_BUILD) -o $@ $< + +$(PROGS):%:%.o + $(LD_FOR_BUILD) -o $@ $< + +clean: cleanlocal +.PHONY: cleanlocal +cleanlocal: + rm -f $(PROGS) + diff --git a/buildtools/Makefile.manpage b/buildtools/Makefile.manpage new file mode 100644 index 00000000..e8c17972 --- /dev/null +++ b/buildtools/Makefile.manpage @@ -0,0 +1,366 @@ +# -*-makefile-*- <-- an Emacs control + +# Make Unix man pages from Netpbm HTML user manual + +MAKEMAN = makeman + +MANDIR = /usr/share/man/man1 + +# These can convert to man pages cleanly +MAN1 = \ + 411toppm.1 \ + anytopnm.1 \ + asciitopgm.1 \ + atktopbm.1 \ + bioradtopgm.1 \ + bmptopnm.1 \ + bmptoppm.1 \ + brushtopbm.1 \ + cmuwmtopbm.1 \ + ddbugtopbm.1 \ + escp2topbm.1 \ + eyuvtoppm.1 \ + fiascotopnm.1 \ + fitstopnm.1 \ + fstopgm.1 \ + g3topbm.1 \ + gemtopbm.1 \ + gemtopnm.1 \ + giftopnm.1 \ + gouldtoppm.1 \ + hdifftopam.1 \ + hipstopgm.1 \ + hpcdtoppm.1 \ + icontopbm.1 \ + ilbmtoppm.1 \ + imgtoppm.1 \ + infotopam.1 \ + jbigtopnm.1 \ + jpeg2ktopam.1 \ + jpegtopnm.1 \ + leaftoppm.1 \ + lispmtopgm.1 \ + macptopbm.1 \ + mdatopbm.1 \ + mgrtopbm.1 \ + mrf.1 \ + mrftopbm.1 \ + mtvtoppm.1 \ + neotoppm.1 \ + palmtopnm.1 \ + pamarith.1 \ + pamchannel.1 \ + pamcomp.1 \ + pamcut.1 \ + pamdeinterlace.1 \ + pamdice.1 \ + pamditherbw.1 \ + pamedge.1 \ + pamendian.1 \ + pamfile.1 \ + pamflip.1 \ + pamfunc.1 \ + pamgauss.1 \ + pamlookup.1 \ + pamoil.1 \ + pamperspective.1 \ + pampop9.1 \ + pamscale.1 \ + pamseq.1 \ + pamsharpmap.1 \ + pamsharpness.1 \ + pamslice.1 \ + pamstack.1 \ + pamstereogram.1 \ + pamstretch-gen.1 \ + pamstretch.1 \ + pamsummcol.1 \ + pamsumm.1 \ + pamtodjvurle.1 \ + pamtohdiff.1 \ + pamtohtmltbl.1 \ + pamtojpeg2k.1 \ + pamtopfm.1 \ + pamtopnm.1 \ + pamtotga.1 \ + pamtouil.1 \ + pbmclean.1 \ + pbmlife.1 \ + pbmmake.1 \ + pbmmask.1 \ + pbmpage.1 \ + pbmpscale.1 \ + pbmreduce.1 \ + pbmtext.1 \ + pbmtextps.1 \ + pbmto10x.1 \ + pbmto4425.1 \ + pbmtoascii.1 \ + pbmtoatk.1 \ + pbmtobbnbg.1 \ + pbmtocmuwm.1 \ + pbmtodjvurle.1 \ + pbmtoepsi.1 \ + pbmtoepson.1 \ + pbmtoescp2.1 \ + pbmtog3.1 \ + pbmtogem.1 \ + pbmtogo.1 \ + pbmtoicon.1 \ + pbmtolj.1 \ + pbmtoln03.1 \ + pbmtolps.1 \ + pbmtomacp.1 \ + pbmtomda.1 \ + pbmtomgr.1 \ + pbmtomrf.1 \ + pbmtonokia.1 \ + pbmtopgm.1 \ + pbmtopi3.1 \ + pbmtopk.1 \ + pbmtoplot.1 \ + pbmtoppa.1 \ + pbmtopsg3.1 \ + pbmtoptx.1 \ + pbmtowbmp.1 \ + pbmtox10bm.1 \ + pbmtoxbm.1 \ + pbmtoybm.1 \ + pbmtozinc.1 \ + pbmupc.1 \ + pc1toppm.1 \ + pcdovtoppm.1 \ + pcxtoppm.1 \ + pfmtopam.1 \ + pgmabel.1 \ + pgmbentley.1 \ + pgmcrater.1 \ + pgmedge.1 \ + pgmenhance.1 \ + pgmhist.1 \ + pgmkernel.1 \ + pgmminkowski.1 \ + pgmmorphconv.1 \ + pgmnoise.1 \ + pgmnorm.1 \ + pgmoil.1 \ + pgmramp.1 \ + pgmslice.1 \ + pgmtexture.1 \ + pgmtofs.1 \ + pgmtolispm.1 \ + pgmtopbm.1 \ + pgmtopgm.1 \ + pgmtoppm.1 \ + pi1toppm.1 \ + pi3topbm.1 \ + picttoppm.1 \ + pjtoppm.1 \ + pktopbm.1 \ + pngtopnm.1 \ + pnmalias.1 \ + pnmarith.1 \ + pnmcat.1 \ + pnmcolormap.1 \ + pnmcomp.1 \ + pnmconvol.1 \ + pnmcrop.1 \ + pnmcut.1 \ + pnmdepth.1 \ + pnmenlarge.1 \ + pnmfile.1 \ + pnmgamma.1 \ + pnmhisteq.1 \ + pnmhistmap.1 \ + pnmindex.1 \ + pnminterp.1 \ + pnminvert.1 \ + pnmmargin.1 \ + pnmmontage.1 \ + pnmnlfilt.1 \ + pnmnoraw.1 \ + pnmnorm.1 \ + pnmpad.1 \ + pnmpaste.1 \ + pnmpsnr.1 \ + pnmquant.1 \ + pnmremap.1 \ + pnmrotate.1 \ + pnmscalefixed.1 \ + pnmscale.1 \ + pnmshear.1 \ + pnmsmooth.1 \ + pnmsplit.1 \ + pnmstitch.1 \ + pnmtile.1 \ + pnmtoddif.1 \ + pnmtofiasco.1 \ + pnmtofits.1 \ + pnmtojbig.1 \ + pnmtojpeg.1 \ + pnmtopalm.1 \ + pnmtopclxl.1 \ + pnmtoplainpnm.1 \ + pnmtopng.1 \ + pnmtopnm.1 \ + pnmtops.1 \ + pnmtorast.1 \ + pnmtorle.1 \ + pnmtosgi.1 \ + pnmtosir.1 \ + pnmtotiffcmyk.1 \ + pnmtotiff.1 \ + pnmtoxwd.1 \ + ppm3d.1 \ + ppmbrighten.1 \ + ppmchange.1 \ + ppmcie.1 \ + ppmcolormask.1 \ + ppmdim.1 \ + ppmdist.1 \ + ppmdither.1 \ + ppmfade.1 \ + ppmflash.1 \ + ppmforge.1 \ + ppmglobe.1 \ + ppmhist.1 \ + ppmlabel.1 \ + ppmmake.1 \ + ppmmix.1 \ + ppmnorm.1 \ + ppmntsc.1 \ + ppmpat.1 \ + ppmquantall.1 \ + ppmquant.1 \ + ppmrainbow.1 \ + ppmrelief.1 \ + ppmrough.1 \ + ppmshadow.1 \ + ppmshift.1 \ + ppmspread.1 \ + ppmsvgalib.1 \ + ppmtoacad.1 \ + ppmtoarbtxt.1 \ + ppmtobmp.1 \ + ppmtoeyuv.1 \ + ppmtogif.1 \ + ppmtoicr.1 \ + ppmtoilbm.1 \ + ppmtojpeg.1 \ + ppmtoleaf.1 \ + ppmtolj.1 \ + ppmtomitsu.1 \ + ppmtompeg.1 \ + ppmtoneo.1 \ + ppmtopcx.1 \ + ppmtopgm.1 \ + ppmtopi1.1 \ + ppmtopict.1 \ + ppmtopj.1 \ + ppmtopjxl.1 \ + ppmtoppm.1 \ + ppmtopuzz.1 \ + ppmtorgb3.1 \ + ppmtosixel.1 \ + ppmtoterm.1 \ + ppmtotga.1 \ + ppmtouil.1 \ + ppmtowinicon.1 \ + ppmtoxpm.1 \ + ppmtoyuv.1 \ + ppmtoyuvsplit.1 \ + ppmtv.1 \ + ppmwheel.1 \ + psidtopgm.1 \ + pstopnm.1 \ + qrttoppm.1 \ + rasttopnm.1 \ + rawtopgm.1 \ + rawtoppm.1 \ + rgb3toppm.1 \ + rletopnm.1 \ + sbigtopgm.1 \ + sgitopnm.1 \ + sirtopnm.1 \ + sldtoppm.1 \ + spctoppm.1 \ + spottopgm.1 \ + sputoppm.1 \ + tgatoppm.1 \ + thinkjettopbm.1 \ + tifftopnm.1 \ + vidtoppm.1 \ + wbmptopbm.1 \ + winicontoppm.1 \ + xbmtopbm.1 \ + ximtoppm.1 \ + xpmtoppm.1 \ + xvminitoppm.1 \ + xwdtopnm.1 \ + ybmtopbm.1 \ + yuvsplittoppm.1 \ + yuvtoppm.1 \ + zeisstopnm.1 \ + +MAN3 = \ + libnetpbm.3 \ + libnetpbm_image.3 \ + libnetpbm_ug.3 \ + libpbm.3 \ + libpgm.3 \ + libpm.3 \ + libpnm.3 \ + libppm.3 \ + libsystem.3 \ + libtmpfile.3 \ + +MAN5 = \ + extendedopacity.5 \ + pam.5 \ + pbm.5 \ + pgm.5 \ + pnm.5 \ + ppm.5 \ + +MANPAGES = $(MAN1) netpbm.1 $(MAN3) $(MAN5) +HTMLMANUALS = $(MAN1:.1=.html) $(MAN3:.3=.html) $(MAN5:.5=.html) +XML = $(HTMLMANUALS:.html=.xml) netpbm.xml + +# These things don't get converted to manual pages +# They're basically link lists, not useful in the man hierarchy. +EXCEPTIONS = directory.html libnetpbm_dir.html + +# Make man pages -- reports bad lines to standard error +manpages: + @python $(MAKEMAN) index.html $(HTMLMANUALS) + mv index.1 netpbm.1 + +# Make XML pages, and validate them. +xmlpages: + @for x in $(MANPAGES); do doclifter $$x; done + @for x in $(XML); do xmllint -xinclude --postvalid $$x >/dev/null; done + +# This will install the generated man pages +installman: manpages + for f in $(MAN1); do \ + if [ -f $$f ]; then gzip <$$f >$(MANDIR)/man1/$$f.gz; fi; \ + done + for f in $(MAN3); do \ + if [ -f $$f ]; then gzip <$$f >$(MANDIR)/man3/$$f.gz; fi; \ + done + for f in $(MAN5); do \ + if [ -f $$f ]; then gzip <$$f >$(MANDIR)/man5/$$f.gz; fi; \ + done + # Clean up old locations on Fedora Core 2 + rm -f $(MANDIR)/man1/extendedopacity.1.gz + rm -f $(MANDIR)/man3/directory.3.gz + rm -f $(MANDIR)/man3/libnetpbm_dir.3.gz + # remove pointer man pages (that say, "The man page isn't here") + # which might have been installed previously + for f in $(MAN1); do rm -f $(MANDIR)/man1/$$f; done + for f in $(MAN3); do rm -f $(MANDIR)/man3/$$f; done + for f in $(MAN5); do rm -f $(MANDIR)/man5/$$f; done + +clean: + @rm -f *.[135] $(XML) + diff --git a/buildtools/README.pkg b/buildtools/README.pkg new file mode 100644 index 00000000..b2a6b0ef --- /dev/null +++ b/buildtools/README.pkg @@ -0,0 +1,144 @@ +THESE ARE THE MANUAL INSTALLATION INSTRUCTIONS FOR NETPBM + +Most people install using the interactive install program 'installnetpbm' +that is in the top level directory of the Netpbm source tree. But it +isn't right for everyone. If it doesn't do what you need, you can use +these instructions instead. + + +Once you have built and packaged Netpbm, installing is pretty +straightforward. If you browse the package directory, you can +probably figure it out without reading any further. + + +The parts to be installed are: + + Executables + + These are the basic Netpbm programs, such as 'jpegtopnm'. + You will find these in the 'bin' subdirectory of the package directory. + + You normally want to copy all of these into a directory that is in your + default program search path (which is controlled by your PATH + environment variable). Typical directories for this are /bin, /usr/bin, + and /usr/local/bin. + + Shared Library + + This is the library that all Netpbm programs need to load and link + to at run time. It is in the 'lib' subdirectory of the package + directory. Building a shared library is optional; if you didn't + do it (which means you built executables that don't require it), + you don't have a 'lib' subdirectory. Shared libraries are also + known as dynamic libraries and DLLs. + + You normally want to copy the shared library to a directory that + is in your system's default shared library search path. On + systems that have an 'ldconfig' program, that program controls the + shared library search path, and you must run it after copying the + Netpbm shared library to its directory. Often, simply rebooting + will cause it to run cleanly. + + Typical directories for this are /lib, /usr/lib, and /usr/local/lib. + + On Windows, the DLLs are treated like executables, so you should + find the 'lib' directory empty and you should find the Netpbm DLL + in the 'bin' directory. You'll probably want to install the DLL + and the executables in the same directory, because the shared + library and executable search paths are the same. + + Link Library + + This is a static link library. You don't need it to run Netpbm. You + need it only if you want to build your own programs that use the Netpbm + library. It is in the 'link' subdirectory of the package directory. + + You normally want to copy the link library into a directory that is + in the default search path of your linker. Typical directories for + this are /usr/lib and /usr/local/lib. + + Interface Headers + + These are the files that declare the interface to the Netpbm + programming library. You don't need them to run Netpbm. You need + them only if you want to build your own programs that use the + Netpbm library. They are in the 'include' subdirectory of the + package directory. + + You normally want to copy the interface header files into a directory + that is in the default search path of your compiler. Typical + directories for this are /usr/include and /usr/local/include. + + Data Files + + These are files that you can use for various purposes as input to + Netpbm programs. People rarely have uses for them, actually. They + are in the 'data' subdirectory of the package directory. + + Put these somewhere that users will be able to find them. + /usr/lib/netpbm and /usr/share/netpbm are typical choices. + + Man Pages + + Netpbm does not have the typical Unix form of documentation. The + documentation is not in files that you can read with the common + 'man' program. Instead, it is in HTML form, and it is not in the + package directory at all. You must install it separately. + + But so that a user who is not familiar with Netpbm documentation + doesn't find himself out in the cold with no access to + documentation, the package directory contains traditional man + pages that do nothing but tell you where to get the real + documentation. (Exactly where that is depends on the options with + which you built and packaged Netpbm). We call these "pointer man + pages." You will find these man pages in the 'man' subdirectory + of the package directory. + + You should copy the contents of this directory wherever your 'man' + program looks for man pages. Typically, this is /usr/man, which + has subdirectories equivalent to those in the package directory's + 'man' subdirectory. + + + One of the Netpbm programs is Manweb, which is designed to be a + replacement for the classic Man program that can access both + traditional man pages and worldwide web documentation in the + Netpbm style with the familiar 'man jpegtopnm' kind of command. + To set up your system for this, you will have to be sure to create + the /usr/man/web directory, with 'netpbm.url' in it. Also, If you + install Manweb as 'man', there is no point to installing the + pointer man pages -- they will never be used. + + + +The instructions above suggest putting the Netpbm parts in common +directories such as /usr/bin, mingled with other packages. This is +usually the easiest way to get Netpbm working. But also consider +putting all Netpbm parts in separate Netpbm directories, such as +/usr/bin/netpbm/ and /usr/link/netpbm. In fact, you can just copy the +entire package directory in one piece to some place such as +/usr/local/netpbm. You'll have to take care to set up search paths +and such to make this kind of configuration work. The advantage of +keeping Netpbm separate is that it makes it easy to wipe out the +entire installation when you don't want it anymore, and to keep +multiple versions around. + + +netpbm.config +------------- + +You should create a shell script named 'netpbm.config' out of the +template file 'config_template' in the package directory, and install +netpbm.config in your executable search path. Programs that want to +find out where you installed some part of Netpbm can invoke +netpbm.config and it will tell them. For example, a make file for a +program that uses the Netpbm programming library might use +netpbm.config to generate the necessary compiler and linker options to +access that library. + +Using netpbm.config, it's possible to have a viable Netpbm +installation where netpbm.config is the only file in any default +search path. + +The xxx.config file concept is a relatively new but growing convention, +seen mostly in software related to the X Window System. diff --git a/buildtools/config_template b/buildtools/config_template new file mode 100644 index 00000000..04a32079 --- /dev/null +++ b/buildtools/config_template @@ -0,0 +1,52 @@ +@ This is a template to be processed into a Bourne shell program. +@ +#!/bin/sh + +# This program was generated by the Netpbm installer. Its purpose is to +# allow other programs to find out about how Netpbm is installed on this +# system. This program is supposed to be invoked via the PATH. + +@ The following @xxx@ strings get replaced by Installnetpbm when it turns +@ this template into an actual Bourne shell program. +version='@VERSION@' +datadir='@DATADIR@' +linkdir='@LINKDIR@' +includedir='@INCLUDEDIR@' +bindir='@BINDIR@' + + +if test $# -eq 0; then + echo >&2 "You need to specify one of these options:" + echo >&2 " --version" + echo >&2 " --datadir" + echo >&2 " --linkdir" + echo >&2 " --includedir" + echo >&2 " --bindir" + exit 100 + fi + +case "$1" in + --version) + echo $version + exit 0 + ;; + --datadir) + echo $datadir + exit 0 + ;; + --linkdir) + echo $linkdir + exit 0 + ;; + --includedir) + echo $includedir + exit 0 + ;; + --bindir) + echo $bindir + exit 0 + ;; + *) + echo >&2 "Unrecognized option to $0: $1" + exit 100 + esac diff --git a/buildtools/configure.pl b/buildtools/configure.pl new file mode 100755 index 00000000..3a44a0da --- /dev/null +++ b/buildtools/configure.pl @@ -0,0 +1,2111 @@ +#!/usr/bin/perl -w + +require 5.000; + +use strict; +use English; +use File::Basename; +use Cwd 'abs_path'; +use Fcntl; +use Config; +#use File::Temp "tempfile"; Not available before Perl 5.6.1 + + +my ($TRUE, $FALSE) = (1,0); + +# This program generates Makefile.config, which is included by all of the +# Netpbm makefiles. You run this program as the first step in building +# Netpbm. (The second step is 'make'). + +# This program is only a convenience. It is supported to create +# Makefile.config any way you want. In fact, an easy way is to copy +# Makefile.config.in and follow the instructions in the comments therein +# to uncomment certain lines and make other changes. + +# Note that if you invoke 'make' without having first run 'configure', +# the make will call 'configure' itself when it finds +# 'Makefile.config' missing. That might look a little messy to the +# user, but it isn't the normal build process. + +# The argument to this program is the filepath of the Makefile.config.in +# file. If unspecified, the default is 'Makefile.config.in' in the +# Netpbm source directory. + +# For explanations of the stuff we put in the make files, see the comments +# in Makefile.config.in. + + +# $testCc is the command we use to do test compiles. Note that test +# compiles are never more than heuristics, because we may be configuring +# a build that will happen on a whole different system, which will build +# programs to run on a third system. + +my $testCc; + +#****************************************************************************** +# +# SUBROUTINES +# +#***************************************************************************** + +sub autoFlushStdout() { + my $oldFh = select(STDOUT); + $OUTPUT_AUTOFLUSH = $TRUE; + select($oldFh); +} + + + +sub prompt($$) { + + my ($prompt, $default) = @_; + + my $defaultPrompt = defined($default) ? $default : "?"; + + print("$prompt [$defaultPrompt] ==> "); + + my $response = ; + + if (defined($response)) { + chomp($response); + if ($response eq "" && defined($default)) { + $response = $default; + } + } else { + print("\n"); + die("End of file on Standard Input when expecting response to prompt"); + } + + return $response; +} + + + +sub tmpdir() { +# This is our approximation of File::Spec->tmpdir(), which became part of +# basic Perl some time after Perl 5.005_03. + + my $retval; + + if ($ENV{"TMPDIR"}) { + $retval = $ENV{"TMPDIR"}; + } else { + if ($Config{'osvers'} eq "djgpp") { + $retval = "/dev/env/DJDIR/tmp"; + } else { + $retval = "/tmp"; + } + } + return $retval; +} + + + +sub tempFile($) { + +# Here's what we'd do if we could expect Perl 5.6.1 or later, instead +# of calling this subroutine: +# my ($cFile, $cFileName) = tempfile("netpbmXXXX", +# SUFFIX=>".c", +# DIR=>File::Spec->tmpdir(), +# UNLINK=>0); + my ($suffix) = @_; + my $fileName; + local *file; # For some inexplicable reason, must be local, not my + my $i; + $i = 0; + do { + $fileName = tmpdir() . "/netpbm" . $i++ . $suffix; + } until sysopen(*file, $fileName, O_RDWR|O_CREAT|O_EXCL); + + return(*file, $fileName); +} + + + +sub commandExists($) { + my ($command) = @_; +#----------------------------------------------------------------------------- +# Return TRUE iff a shell command $command exists. +#----------------------------------------------------------------------------- + +# Note that it's significant that the redirection on the following +# causes it to be executed in a shell. That makes the return code +# from system() a lot different than if system() were to try to +# execute the program directly. + + return(system("$command 1/dev/null 2>/dev/null")/256 != 127); +} + + + +sub chooseTestCompiler($$) { + + my ($compiler, $testCcR) = @_; + + my $cc; + + if (!defined($compiler)) { + if ($ENV{'CC'}) { + $cc = $ENV{'CC'}; + } else { + if (commandExists('cc')) { + $cc = 'cc'; + } elsif (commandExists("gcc")) { + $cc = 'gcc'; + } + } + } elsif ($compiler eq 'cc') { + $cc = "cc"; + } elsif ($compiler eq 'gcc') { + $cc = 'gcc'; + } else { + die("Internal error: invalid value \"$compiler\" for \$compiler"); + } + $$testCcR = $cc; +} + + + +sub testCflags($) { + my ($needLocal) = @_; + + my $cflags; + + $cflags = ""; # initial value + + if ($ENV{"CPPFLAGS"}) { + $cflags = $ENV{"CPPFLAGS"}; + } else { + $cflags = ""; + } + + if ($ENV{"CFLAGS"}) { + $cflags .= " " . $ENV{"CFLAGS"}; + } + + if ($needLocal) { + $cflags .= " -I/usr/local/include"; + } + return $cflags; +} + + + +sub testCompile($$$) { + my ($cflags, $cSourceCodeR, $successR) = @_; +#----------------------------------------------------------------------------- +# Do a test compile of the program in @{$cSourceCodeR}. +# +# Return $$successR == $TRUE iff the compile succeeds (exit code 0). +#----------------------------------------------------------------------------- + my ($cFile, $cFileName) = tempFile(".c"); + + print $cFile @{$cSourceCodeR}; + + my ($oFile, $oFileName) = tempFile(".o"); + # Note: we tried using /dev/null for the output file and got complaints + # from the Sun compiler that it has the wrong suffix. 2002.08.09. + + my $compileCommand = "$testCc -c -o $oFileName $cflags $cFileName"; + print ("Doing test compile: $compileCommand\n"); + my $rc = system($compileCommand); + + unlink($oFileName); + close($oFile); + unlink($cFileName); + close($cFile); + + $$successR = ($rc == 0); +} + + + +sub displayIntroduction() { + print("This is the Netpbm configurator. It is an interactive dialog " . + "that\n"); + print("helps you build the file 'Makefile.config' and prepare to build "); + print("Netpbm.\n"); + print("\n"); + + print("Do not be put off by all the questions. Configure gives you " . + "the \n"); + print("opportunity to make a lot of choices, but you don't have to. " . + "If \n"); + print("you don't have reason to believe you're smarter than Configure,\n"); + print("just take the defaults (hit ENTER) and don't sweat it.\n"); + print("\n"); + + print("If you are considering having a program feed answers to the " . + "questions\n"); + print("below, please read doc/INSTALL, because that's probably the " . + "wrong thing to do.\n"); + print("\n"); + + print("Hit ENTER to begin.\n"); + my $response = ; +} + + +sub askAboutCygwin() { + + print("Are you building in/for the Cygwin environment?\n"); + print("\n"); + + my $default; + if ($OSNAME eq "cygwin") { + $default = "y"; + } else { + $default = "n"; + } + + my $retval; + + while (!defined($retval)) { + my $response = prompt("(y)es or (n)o", $default); + + if (uc($response) =~ /^(Y|YES)$/) { + $retval = $TRUE; + } elsif (uc($response) =~ /^(N|NO)$/) { + $retval = $FALSE; + } else { + print("'$response' isn't one of the choices. \n" . + "You must choose 'yes' or 'no' (or 'y' or 'n').\n"); + } + } + return $retval; +} + + + +sub askAboutDjgpp() { + + print("Are you building in/for the DJGPP environment?\n"); + print("\n"); + + my $default; + if ($OSNAME eq "dos") { + $default = "y"; + } else { + $default = "n"; + } + + my $retval; + + while (!defined($retval)) { + my $response = prompt("(y)es or (n)o", $default); + + if (uc($response) =~ /^(Y|YES)$/) { + $retval = $TRUE; + } elsif (uc($response) =~ /^(N|NO)$/) { + $retval = $FALSE; + } else { + print("'$response' isn't one of the choices. \n" . + "You must choose 'yes' or 'no' (or 'y' or 'n').\n"); + } + } +} + + + +sub computePlatformDefault($) { + + my ($defaultP) = @_; + + if ($OSNAME eq "linux") { + $$defaultP = "gnu"; + } elsif ($OSNAME eq "cygwin") { + $$defaultP = "win"; + } elsif ($OSNAME eq "dos") { + # DJGPP says "dos" + $$defaultP = "win"; + } elsif ($OSNAME eq "aix" || $OSNAME eq "freebsd" || $OSNAME eq "darwin" || + $OSNAME eq "amigaos") { + $$defaultP = $OSNAME; + } elsif ($OSNAME eq "solaris") { + $$defaultP = "sun"; + } elsif ($OSNAME eq "dec_osf") { + $$defaultP = "tru64"; + } else { + print("Unrecognized OSNAME='$OSNAME'. No default possible\n"); + } + # OK - if you know what $OSNAME is on any other platform, send me a patch! +} + + + +sub getPlatform() { + + my $platform; + my $default; + + computePlatformDefault(\$default); + + print("Which of the following best describes your platform?\n"); + + print("gnu GNU/Linux\n"); + print("sun Solaris or SunOS\n"); + print("hp HP-UX\n"); + print("aix AIX\n"); + print("win Windows/DOS (Cygwin, DJGPP, Mingw32)\n"); + print("tru64 Tru64\n"); + print("irix Irix\n"); + print("bsd NetBSD, BSD/OS\n"); + print("openbsd OpenBSD\n"); + print("freebsd FreeBSD\n"); + print("darwin Darwin or Mac OS X\n"); + print("amigaos Amiga\n"); + print("unixware Unixware\n"); + print("sco SCO OpenServer\n"); + print("beos BeOS\n"); + print("none none of these are even close\n"); + print("\n"); + + my $response = prompt("Platform", $default); + + my %platform = ("gnu" => "GNU", + "sun" => "SOLARIS", + "hp" => "HP-UX", + "aix" => "AIX", + "tru64" => "TRU64", + "irix" => "IRIX", + "win" => "WINDOWS", + "beos" => "BEOS", + "bsd" => "NETBSD", + "openbsd" => "OPENBSD", + "freebsd" => "FREEBSD", + "unixware" => "UNIXWARE", + "sco" => "SCO", + "darwin" => "DARWIN", + "amigaos" => "AMIGA", + "none" => "NONE" + ); + + $platform = $platform{$response}; + if (!defined($platform)) { + print("'$response' isn't one of the choices.\n"); + exit 8; + } + + my $subplatform; + + if ($platform eq "WINDOWS") { + my ($djgpp, $cygwin); + + if ($OSNAME eq "dos") { + $djgpp = askAboutDjgpp(); + if ($djgpp) { + $cygwin = $FALSE; + } else { + $cygwin = askAboutCygwin(); + } + } else { + $cygwin = askAboutCygwin(); + if ($cygwin) { + $djgpp = $FALSE; + } else { + $djgpp = askAboutDjgpp(); + } + } + + if ($cygwin) { + $subplatform = "cygwin"; + } elsif ($djgpp) { + $subplatform = "djgpp"; + } else { + $subplatform = "other"; + } + } + + return($platform, $subplatform); +} + + + +sub getCompiler($$) { + my ($platform, $compilerR) = @_; +#----------------------------------------------------------------------------- +# Here are some of the issues surrounding choosing a compiler: +# +# - It's not just the name of the program we need -- different compilers +# need different options. +# +# - There are basically two choices on any system: native compiler or +# GNU compiler. That's all this program recognizes, anyway. +# +# - A user may well have various compilers. Different releases, using +# different standard libraries, for different target machines, etc. +# +# - The CC environment variable tells the default compiler. +# +# - In the absence of a CC environment variable, 'cc' is the default +# compiler. +# +# - The user must be able to specify the compiler by overriding the CC +# make variable (e.g. make CC=gcc2). +# +# - Configure needs to do test compiles. The test is best if it uses +# the same compiler that the build eventually will use, but it's +# useful even if not. +# +# The value this subroutine returns is NOT the command name to invoke the +# compiler. It is simply "cc" to mean native compiler or "gcc" to mean +# GNU compiler or undefined to express no preference. +#----------------------------------------------------------------------------- + my %gccCapablePlatform = ("SOLARIS" => 1, + "TRU64" => 1, + "SCO" => 1, + "AIX" => 1, + "HP" => 1); + + if ($gccCapablePlatform{$platform}) { + print("GNU compiler or native operating system compiler (cc)?\n"); + print("\n"); + + my $default; + + if ($platform eq "SOLARIS" || $platform eq "SCO" ) { + $default = "gcc"; + } else { + $default = "cc"; + } + + my $response = prompt("gcc or cc", $default); + + if ($response eq "gcc") { + $$compilerR = "gcc"; + } elsif ($response eq "cc") { + $$compilerR = "cc"; + } else { + print("'$response' isn't one of the choices. \n" . + "You must choose 'gcc' or 'cc'.\n"); + exit 12; + } + + if ($$compilerR eq 'gcc' && !commandExists('gcc')) { + print("WARNING: You selected the GNU compiler, " . + "but do not appear to have a program " . + "named 'gcc' in your PATH. This may " . + "cause trouble later. You may need to " . + "set the CC environment variable or CC " . + "makefile variable or install 'gcc'\n"); + } + print("\n"); + } +} + + + +sub gccLinker() { +#----------------------------------------------------------------------------- +# Determine what linker Gcc on this system appears to use. +# +# Return either "gnu" or "sun" +# +# For now, we assume it must be either a GNU linker or Sun linker and +# that all Sun linkers are fungible. +# +# If we can't tell, we assume it is the GNU linker. +#----------------------------------------------------------------------------- + # First, we assume that the compiler calls 'collect2' as the linker + # front end. The specs file might specify some other program, but + # it usually says 'collect2'. + + my $retval; + + my $collect2 = qx{gcc --print-prog-name=collect2}; + + if (defined($collect2)) { + chomp($collect2); + my $linker = qx{$collect2 -v 2>&1}; + if (defined($linker) && $linker =~ m{GNU ld}) { + $retval = "gnu"; + } else { + $retval = "sun"; + } + } else { + $retval = "gnu"; + } + return $retval; +} + + + +sub getLinker($$$$) { + + my ($platform, $compiler, $baseLinkerR, $viaCompilerR) = @_; + + my $baseLinker; + + if ($platform eq "SOLARIS") { + $$viaCompilerR = $TRUE; + + while (!defined($$baseLinkerR)) { + print("GNU linker or SUN linker?\n"); + print("\n"); + + my $default; + + if ($compiler eq "gcc") { + $default = gccLinker(); + } else { + $default = "sun"; + } + my $response = prompt("sun or gnu", $default); + + if ($response eq "gnu") { + $$baseLinkerR = "GNU"; + } elsif ($response eq "sun") { + $$baseLinkerR = "SUN"; + } else { + print("'$response' isn't one of the choices. \n" . + "You must choose 'sun' or 'gnu'.\n"); + } + print("\n"); + } + } else { + $$viaCompilerR = $TRUE; + $$baseLinkerR = "?"; + } +} + + + +sub libSuffix($) { + my ($platform) = @_; +#----------------------------------------------------------------------------- +# Return the traditional suffix for the link-time library on platform +# type $platform. +# +# Note that this information is used mainly for cosmetic purposes in this +# this program and the Netpbm build, because the build typically removes +# any suffix and uses link options such as "-ltiff" to link the library. +# This leaves it up to the linker to supply the actual suffix. +#----------------------------------------------------------------------------- + my $suffix; + + if ($platform eq "windows") { + $suffix = ".a"; + } else { + $suffix = ".so"; + } +} + + + +sub getLibTypes($$$$$$$$) { + my ($platform, $subplatform, $default_target, + $netpbmlibtypeR, $netpbmlibsuffixR, $shlibprefixlistR, + $willBuildSharedR, $staticlib_tooR) = @_; + + print("Do you want libnetpbm to be statically linked or shared?\n"); + print("\n"); + + my $default = ($default_target eq "merge") ? "static" : "shared"; + + my ($netpbmlibtype, $netpbmlibsuffix, $shlibprefixlist, + $willBuildShared, $staticlib_too); + + my $response = prompt("static or shared", $default); + + if ($response eq "shared") { + $willBuildShared = $TRUE; + if ($platform eq "WINDOWS") { + $netpbmlibtype = "dll"; + $netpbmlibsuffix = "dll"; + if ($subplatform eq "cygwin") { + $shlibprefixlist = "cyg lib"; + } + } elsif ($platform eq "DARWIN") { + $netpbmlibtype = "dylib"; + $netpbmlibsuffix = "dylib"; + } else { + if ($platform eq "IRIX") { + $netpbmlibtype = "irixshared"; + } else { + $netpbmlibtype = "unixshared"; + } + if ($platform eq "AIX") { + $netpbmlibsuffix = "a"; + } elsif ($platform eq "HP-UX") { + $netpbmlibsuffix = "sl"; + } else { + $netpbmlibsuffix = "so"; + } + } + } elsif ($response eq "static") { + $willBuildShared = $FALSE; + $netpbmlibtype = "unixstatic"; + $netpbmlibsuffix = "a"; + # targets, but needed for building + # libopt + } else { + print("'$response' isn't one of the choices. \n" . + "You must choose 'static' or 'shared'.\n"); + exit 12; + } + + print("\n"); + + # Note that we can't do both a static and shared library for AIX, because + # they both have the same name: libnetpbm.a. + + if (($netpbmlibtype eq "unixshared" or + $netpbmlibtype eq "irixshared" or + $netpbmlibtype eq "dll") and $netpbmlibsuffix ne "a") { + print("Do you want to build static libraries too (for linking to \n"); + print("programs not in the Netpbm package?\n"); + print("\n"); + + my $default = "y"; + + my $response = prompt("(y)es or (n)o", $default); + + if (uc($response) =~ /^(Y|YES)$/) { + $staticlib_too = "y"; + } elsif (uc($response) =~ /^(N|NO)$/) { + $staticlib_too = "n"; + } else { + print("'$response' isn't one of the choices. \n" . + "You must choose 'yes' or 'no' (or 'y' or 'n').\n"); + exit 12; + } + } else { + $staticlib_too = "n"; + } + print("\n"); + + $$netpbmlibtypeR = $netpbmlibtype; + $$netpbmlibsuffixR = $netpbmlibsuffix; + $$shlibprefixlistR = $shlibprefixlist; + $$willBuildSharedR = $willBuildShared; + $$staticlib_tooR = $staticlib_too; +} + + + +sub inttypesDefault() { + + my $retval; + + if (defined($testCc)) { + + print("(Doing test compiles to choose a default for you -- " . + "ignore errors)\n"); + + my $cflags = testCflags($FALSE); + + my $works; + + # We saw a system (Irix 5.3 with native IDO, December 2005) on + # which sys/types.h defines uint32_t, but not int32_t and other + # similar types. We saw a Mac OS X system (January 2006) on which + # sys/types sometimes defines uint32_t, but sometimes doesn't. + # So we make those last resorts. + + # int_fastXXX_t are the least likely of all the types to be + # defined, so we look for that. + + # Solaris 8, for example, has a that defines + # int32_t and uint32_t, but nothing the defines int_fast32_t. + + my @candidateList = ("", "", + "", ""); + + for (my $i = 0; $i < @candidateList && !$works; ++$i) { + my $candidate = $candidateList[$i]; + my @cSourceCode = ( + "#include $candidate\n", + "int_fast32_t testvar;\n" + ); + + testCompile($cflags, \@cSourceCode, \my $success); + + if ($success) { + $works = $candidate; + } + } + if ($works) { + $retval = $works; + } else { + testCompile($cflags, ["int_fast32_t testvar;"], \my $success); + if ($success) { + $retval = "NONE"; + } else { + $retval = '"inttypes_netpbm.h"'; + } + } + print("\n"); + } else { + $retval = ''; + } + return $retval; +} + + + +sub getInttypes($) { + my ($inttypesHeaderFileR) = @_; + + my $gotit; + + print("What header file defines uint32_t, etc.?\n"); + print("\n"); + + my $default = inttypesDefault(); + + while (!$gotit) { + my $response = prompt("'#include' argument or NONE", $default); + + if ($response eq "NONE") { + $$inttypesHeaderFileR = ''; + $gotit = $TRUE; + } else { + if ($response !~ m{<.+>} && + $response !~ m{".+"}) { + print("'$response' is not a legal argument of a C #include " . + "statement. It must be something in <> or \"\".\n"); + } else { + $gotit = $TRUE; + $$inttypesHeaderFileR = $response; + } + } + } +} + + +sub getInt64($$) { + + my ($inttypes_h, $haveInt64R) = @_; + + if (defined($testCc)) { + + print("(Doing test compiles to determine if you have int64 type -- " . + "ignore errors)\n"); + + my $cflags = testCflags($FALSE); + + my $works; + + my @cSourceCode = ( + "#include $inttypes_h\n", + "int64_t testvar;\n" + ); + + testCompile($cflags, \@cSourceCode, \my $success); + + if ($success) { + print("You do.\n"); + $$haveInt64R = 'Y'; + } else { + print("You do not. 64-bit code won't be built.\n"); + $$haveInt64R = 'N'; + } + print("\n"); + } else { + $$haveInt64R = "N"; + } +} + + + +# TODO: These should do test compiles to see if the headers are in the +# default search path, both to create a default to offer and to issue a +# warning after user has chosen. Also test links to test the link library. + +# It looks like these should all be in the default search paths and were there +# just to override defaults in Makefile.config.in. Since Configure now +# creates a default of "standard search path," I'm guessing we don't need +# to set these anymore. + +sub getTiffLibrary($@) { + + my ($platform, @suggestedHdrDir) = @_; + + my $tifflib; + { + my $default = "libtiff" . libSuffix($platform); + + print("What is your TIFF (graphics format) library?\n"); + + my $response = prompt("library filename or 'none'", $default); + + if ($response ne "none") { + $tifflib = $response; + } + if (defined($tifflib) and $tifflib =~ m{/} and !-f($tifflib)) { + printf("WARNING: No regular file named '$tifflib' exists.\n"); + } + } + my $tiffhdr_dir; + if (defined($tifflib)) { + my $default; + + if (-d("/usr/include/tiff")) { + $default = "/usr/include/tiff"; + } elsif (-d("/usr/include/libtiff")) { + $default = "/usr/include/libtiff"; + } else { + $default = "default"; + } + print("Where are the interface headers for it?\n"); + + my $response = prompt("TIFF header directory", $default); + + if ($response ne "default") { + $tiffhdr_dir = $response; + } + if (defined($tiffhdr_dir) and !-d($tiffhdr_dir)) { + printf("WARNING: No directory named '$tiffhdr_dir' exists.\n"); + } + } + return($tifflib, $tiffhdr_dir); +} + + + +sub getJpegLibrary($@) { + + my ($platform, @suggestedHdrDir) = @_; + + my $jpeglib; + { + my $default = "libjpeg" . libSuffix($platform); + + print("What is your JPEG (graphics format) library?\n"); + + my $response = prompt("library filename or 'none'", $default); + + if ($response ne "none") { + $jpeglib = $response; + } + } + my $jpeghdr_dir; + if (defined($jpeglib)) { + my $default; + + if (-d("/usr/include/jpeg")) { + $default = "/usr/include/jpeg"; + } else { + $default = "default"; + } + print("Where are the interface headers for it?\n"); + + my $response = prompt("JPEG header directory", $default); + + if ($response ne "default") { + $jpeghdr_dir = $response; + } + if (defined($jpeghdr_dir) and !-d($jpeghdr_dir)) { + printf("WARNING: No directory named '$jpeghdr_dir' exists.\n"); + } + } + return($jpeglib, $jpeghdr_dir); +} + + + +sub getPngLibrary($@) { + + my ($platform, @suggestedHdrDir) = @_; + + my ($pnglib, $pnghdr_dir); + + if (commandExists('libpng-config')) { + # We don't need to ask where Libpng is; there's a 'libpng-config' + # That tells exactly how to access it, and the make files will use + # that. + } else { + { + my $default = "libpng" . libSuffix($platform); + + print("What is your PNG (graphics format) library?\n"); + + my $response = prompt("library filename or 'none'", $default); + + if ($response ne "none") { + $pnglib = $response; + } + } + if (defined($pnglib)) { + my $default; + + if (-d("/usr/include/png")) { + $default = "/usr/include/libpng"; + } else { + $default = "default"; + } + + print("Where are the interface headers for it?\n"); + + my $response = prompt("PNG header directory", $default); + + if ($response ne "default") { + $pnghdr_dir = $response; + } + } + } + return($pnglib, $pnghdr_dir); +} + + + +sub getZLibrary($@) { + + my ($platform, @suggestedHdrDir) = @_; + + my ($zlib, $zhdr_dir); + + { + my $default = "libz" . libSuffix($platform); + + print("What is your Z (compression) library?\n"); + + my $response = prompt("library filename or 'none'", $default); + + if ($response ne "none") { + $zlib = $response; + } + } + if (defined($zlib)) { + my $default; + + if (-d("/usr/include/zlib")) { + $default = "/usr/include/zlib"; + } else { + $default = "default"; + } + + print("Where are the interface headers for it?\n"); + + my $response = prompt("Z header directory", $default); + + if ($response ne "default") { + $zhdr_dir = $response; + } + } + return($zlib, $zhdr_dir); +} + + + +sub getX11Library($@) { + + my ($platform, @suggestedHdrDir) = @_; + + my $x11lib; + { + my $default; + + if (-d('/usr/link/X11')) { + $default = '/usr/link/X11/libX11' . libSuffix($platform); + } elsif (-d('/usr/lib/X11')) { + $default = '/usr/lib/libX11' . libSuffix($platform); + } else { + $default = "libX11" . libSuffix($platform); + } + print("What is your X11 (X client) library?\n"); + + my $response = prompt("library filename or 'none'", $default); + + if ($response ne "none") { + $x11lib = $response; + } + } + my $x11hdr_dir; + if (defined($x11lib)) { + my $default; + + $default = "default"; + + print("Where are the interface headers for it?\n"); + + my $response = prompt("X11 header directory", $default); + + if ($response ne "default") { + $x11hdr_dir = $response; + } + if (defined($x11hdr_dir)) { + if (!-d($x11hdr_dir)) { + printf("WARNING: No directory named '$x11hdr_dir' exists.\n"); + } elsif (!-d("$x11hdr_dir/X11")) { + printf("WARNING: Directory '$x11hdr_dir' does not contain " . + "the requisite 'X11' subdirectory\n"); + } + } + } + return($x11lib, $x11hdr_dir); +} + + + +sub getLinuxsvgaLibrary($@) { + + my ($platform, @suggestedHdrDir) = @_; + + my ($svgalib, $svgalibhdr_dir); + + if ($platform eq "GNU") { + { + my $default; + + if (-d('/usr/link/svgalib')) { + $default = '/usr/link/svgalib/libvga.so'; + } elsif (-d('/usr/lib/svgalib')) { + $default = '/usr/lib/svgalib/libvga.so'; + } else { + $default = 'libvga.so'; + } + + print("What is your Svgalib library?\n"); + + my $response = prompt("library filename or 'none'", $default); + + if ($response ne "none") { + $svgalib = $response; + } + } + } + if (defined($svgalib)) { + my $default; + + if (-d('/usr/include/svgalib')) { + $default = '/usr/include/svgalib'; + } else { + $default = "default"; + } + print("Where are the interface headers for it?\n"); + + my $response = prompt("Svgalib header directory", $default); + + if ($response ne "default") { + $svgalibhdr_dir = $response; + } + if (defined($svgalibhdr_dir)) { + if (!-d($svgalibhdr_dir)) { + printf("WARNING: No directory named " . + "'$svgalibhdr_dir' exists.\n"); + } + } + } + return($svgalib, $svgalibhdr_dir); +} + + + +sub symlink_command() { + + my $retval; + + # Some Windows environments don't have symbolic links (or even a + # simulation via a "ln" command, but have a "cp" command which works + # in a pinch. Some Windows environments have "ln", but it won't do + # symbolic links. + + if (commandExists("ln")) { + # We assume if Perl can do symbolic links, so can Ln, and vice + # versa. + + my $symlink_exists = eval { symlink("",""); 1 }; + + if ($symlink_exists) { + $retval = "ln -s"; + } else { + $retval = "ln"; + } + } elsif (commandExists("cp")) { + $retval = "cp"; + } else { + # Well, maybe we just made a mistake. + $retval = "ln -s"; + } + return $retval; +} + + + +sub help() { + + print("This is the Netpbm custom configuration program. \n"); + print("It is not GNU Configure.\n"); + print("\n"); + print("There is one optional argument to this program: The " . + "name of the file to use as the basis for the Makefile.config " . + "file. Default is 'Makefile.config.in'\n"); + print("\n"); + print("Otherwise, the program is interactive.\n"); +} + + + +sub gnuOptimizeOpt($) { + my ($gccCommandName) = @_; +#----------------------------------------------------------------------------- +# Compute the -O compiler flag appropriate for a GNU system. Ordinarily, +# this is just -O3. But many popular GNU systems have a broken compiler +# that causes -O3 to generate incorrect code (symptom: pnmtojpeg --quality=95 +# generates a syntax error message from shhopt). +#----------------------------------------------------------------------------- +# I don't know what are exactly the cases that Gcc is broken. I know +# Red Hat 7.1 and 7.2 and Mandrake 8.2, running gcc 2.96.1, commonly have +# the problem. But it may be limited to a certain subrelease level or +# CPU type or other environment. People who have reported the problem have +# reported that Gcc 3.0 doesn't have it. Gcc 2.95.3 doesn't have it. + +# Note that automatic inlining happens at -O3 level, but there are some +# subroutines in Netpbm marked for explicit inlining, and we need to disable +# that inlining too, so we must go all the way down to -O0. + + my @gccVerboseResp = `$gccCommandName --verbose 2>&1`; + + my $brokenCompiler; + + if (@gccVerboseResp ==2) { + if ($gccVerboseResp[1] =~ m{gcc version 2.96}) { + $brokenCompiler = $TRUE; + } else { + $brokenCompiler = $FALSE; + } + } else { + $brokenCompiler = $FALSE; + } + + my $oOpt; + + if ($brokenCompiler) { + print("You appear to have a broken compiler which would produce \n"); + print("incorrect code if requested to do inline optimization.\n"); + print("Therefore, I am configuring the build to not do inline \n"); + print("optimization. This will make some Netpbm programs \n"); + print("noticeably slower. If I am wrong about your compiler, just\n"); + print("edit Makefile.config and change -O0 to -O3 near the bottom.\n"); + print("\n"); + print("The problem is known to exist in the GNU Compiler \n"); + print("release 2.96. If you upgrade, you will not have this \n"); + print("problem.\n"); + print("---------------------------------------------\n"); + print("\n"); + $oOpt = "-O0"; + } else { + $oOpt = "-O3"; + } + return $oOpt; +} + + + +sub needLocal($) { +#----------------------------------------------------------------------------- +# Return wether or not /usr/local paths must be added to compiles and +# links. In a properly configured system, those paths should be in +# the compiler and linker default search paths, e.g. the compiler +# should search /usr/local/include and then /usr/include without any +# -I options needed. But we've seen some systems where it isn't. +# +# Actually, I have doubts now as to whether these misconfigured systems +# really exist. This subroutine was apparently always broken, because +# before 04.03.15, it had "netbsd", etc. in lower case. So it always +# returned false. I never had a complaint. Plus, we had a bug in +# Makefile.config.in wherein it wiped out the user's setting of the LDFLAGS +# environment variable. This could explain /usr/local/lib not being in +# the path when it should have been. +# +# So I've disabled this function; we'll see if we encounter any truly +# misconfigured systems. 04.03.15. +#----------------------------------------------------------------------------- + my ($platform) = @_; + + return $FALSE; # See comments above. + + my $needLocal; + + if ($platform eq "NETBSD" || $platform eq "OPENBSD" || + $platform eq "FREEBSD") { + $needLocal = $TRUE; + } else { + $needLocal = $FALSE; + } + return $needLocal; +} + + + +sub findProcessManagement($) { + my ($dontHaveProcessMgmtR) = @_; +#----------------------------------------------------------------------------- +# Return $TRUE iff the system does not have in its default +# search path. +#----------------------------------------------------------------------------- + my $cflags = testCflags($FALSE); + + my @cSourceCode = ( + "#include \n", + ); + + testCompile($cflags, \@cSourceCode, \my $success); + + if (!$success) { + print("Your system does not appear to have in its " . + "standard compiler include path. Therefore, we will build " . + "Netpbm with some function missing (e.g. the pm_system() " . + "function in libnetpbm and most of 'pamlookup'\n"); + $$dontHaveProcessMgmtR = $TRUE; + } else { + $$dontHaveProcessMgmtR = $FALSE; + } +} + + + +sub validateLibraries(@) { + my @libList = @_; +#----------------------------------------------------------------------------- +# Check each library name in the list @libList for viability. +#----------------------------------------------------------------------------- + foreach my $libname (@libList) { + if (defined($libname)) { + if ($libname =~ m{/} and !-f($libname)) { + print("WARNING: No regular file named '$libname' exists.\n"); + } elsif (!($libname =~ m{ .* \. (so|a|sa|sl|dll|dylib) $ }x)) { + print("WARNING: The library name '$libname' does not have " . + "a conventional suffix (.so, .a, .dll, etc.)\n"); + } + } + } +} + + + +sub warnJpegTiffDependency($$) { + my ($jpeglib, $tifflib) = @_; + + if (defined($tifflib) && !defined($jpeglib)) { + print("WARNING: You say you have a Tiff library, " . + "but no Jpeg library.\n"); + print("Sometimes the Tiff library prerequires the " . + "Jpeg library. If \n"); + print("that is the case on your system, you will " . + "have some links fail with\n"); + print("missing 'jpeg...' symbols. If so, rerun " . + "Configure and say you\n"); + print("have no Tiff library either.\n"); + print("\n"); + } +} + + + +sub testCompileJpeglibH($$) { + my ($cflags, $successR) = @_; +#----------------------------------------------------------------------------- +# Do a test compile to see if we can see jpeglib.h. +#----------------------------------------------------------------------------- + my @cSourceCode = ( + "#include \n", + "#include \n", + "#include \n", + ); + + testCompile($cflags, \@cSourceCode, $successR); +} + + + +sub testCompileJpegMarkerStruct($$) { + my ($cflags, $successR) = @_; +#----------------------------------------------------------------------------- +# Do a test compile to see if struct jpeg_marker_struct is defined in +# jpeglib.h. Assume it is already established that the compiler works +# and can find jpeglib.h. +#----------------------------------------------------------------------------- + my @cSourceCode = ( + "#include \n", + "#include \n", + "#include \n", + "struct jpeg_marker_struct test;\n", + ); + + testCompile($cflags, \@cSourceCode, $successR); +} + + + +sub printMissingHdrWarning($$) { + + my ($name, $hdr_dir) = @_; + + print("WARNING: You said the compile-time part of the $name library " . + "(the header\n"); + print("files) is in "); + + if (defined($hdr_dir)) { + print("directory '$hdr_dir', "); + } else { + print("the compiler's default search path, "); + } + print("but a test compile failed\n"); + print("to confirm that. If your configuration is exotic, the test " . + "compile might\n"); + print("just be wrong, but otherwise the Netpbm build will fail.\n"); + print("\n"); + print("To fix this, either install the $name library there \n"); + print("or re-run Configure and answer the question about the $name " . + "library\n"); + print("differently.\n"); + print("\n"); +} + + + +sub printOldJpegWarning() { + print("WARNING: Your JPEG library appears to be too old for Netpbm.\n"); + print("We base this conclusion on the fact that jpeglib.h apparently\n"); + print("does not define struct jpeg_marker_struct.\n"); + print("If the JPEG library is not Independent Jpeg Group's Version 6b\n"); + print("or better, the Netpbm build will fail when it attempts to build\n"); + print("the parts that use the JPEG library.\n"); + print("\n"); + print("If your configuration is exotic, this test may just be wrong.\n"); + print("Otherwise, either upgrade your JPEG library or re-run Configure\n"); + print("and say you don't have a JPEG library.\n"); + print("\n"); +} + + + +sub testJpegHdr($$) { + + my ($needLocal, $jpeghdr_dir) = @_; + + if (defined($testCc)) { + + my $generalCflags = testCflags($needLocal); + + my $jpegIOpt = $jpeghdr_dir ? "-I$jpeghdr_dir" : ""; + + testCompileJpeglibH("$generalCflags $jpegIOpt", \my $success); + + if (!$success) { + print("\n"); + printMissingHdrWarning("JPEG", $jpeghdr_dir); + } else { + # We can get to something named jpeglib.h, but maybe it's an old + # version we can't use. Check it out. + testCompileJpegMarkerStruct("$generalCflags $jpegIOpt", + \my $success); + if (!$success) { + print("\n"); + printOldJpegWarning(); + } + } + } +} + + + +sub testCompileZlibH($$) { + my ($cflags, $successR) = @_; +#----------------------------------------------------------------------------- +# Do a test compile to see if we can see zlib.h. +#----------------------------------------------------------------------------- + my @cSourceCode = ( + "#include \n", + ); + + testCompile($cflags, \@cSourceCode, $successR); +} + + + +sub testCompilePngH($$) { + my ($cflags, $successR) = @_; +#----------------------------------------------------------------------------- +# Do a test compile to see if we can see png.h, assuming we can see +# zlib.h, which png.h #includes. +#----------------------------------------------------------------------------- + my @cSourceCode = ( + "#include \n", + ); + + testCompile($cflags, \@cSourceCode, $successR); +} + + + +sub testPngHdr($$$) { +#----------------------------------------------------------------------------- +# Issue a warning if the compiler can't find png.h. +#----------------------------------------------------------------------------- + my ($needLocal, $pnghdr_dir, $zhdr_dir) = @_; + + if (defined($testCc)) { + + my $generalCflags = testCflags($needLocal); + + my $zlibIOpt = $zhdr_dir ? "-I$zhdr_dir" : ""; + + testCompileZlibH("$generalCflags $zlibIOpt", \my $success); + if (!$success) { + print("\n"); + printMissingHdrWarning("Zlib", $zhdr_dir); + } else { + my $pngIOpt = $pnghdr_dir ? "-I$pnghdr_dir" : ""; + + testCompilePngH("$generalCflags $zlibIOpt $pngIOpt", + \my $success); + + if (!$success) { + print("\n"); + printMissingHdrWarning("PNG", $pnghdr_dir); + } + } + } +} + + + +sub testLibpngConfig($) { + my ($needLocal) = @_; +#----------------------------------------------------------------------------- +# Issue a warning if the instructions 'libpng-config' give for compiling +# with Libpng don't work. +#----------------------------------------------------------------------------- + my $generalCflags = testCflags($needLocal); + + my $pngCflags = qx{libpng-config --cflags}; + chomp($pngCflags); + + testCompilePngH("$generalCflags $pngCflags", \my $success); + + if (!$success) { + print("\n"); + print("Unable to compile a test PNG program using the compiler " . + "flags that libpng-config says to use: '$pngCflags'.\n"); + print("This indicates that you have Libpng installed incorrectly.\n"); + print("libpng-config gets installed as part of the Libpng package.\n"); + } else { + + + + } +} + + + +sub testConfiguration($$$$$$$) { + + my ($needLocal, $jpeglib, $jpeghdr_dir, + $pnglib, $pnghdr_dir, $zlib, $zhdr_dir) = @_; + + if (defined($jpeglib)) { + testJpegHdr($needLocal, $jpeghdr_dir); + } + if (defined($pnglib) && defined($zlib)) { + testPngHdr($needLocal, $pnghdr_dir, $zhdr_dir); + } elsif (commandExists('libpng-config')) { + testLibpngConfig($needLocal); + } + + # TODO: We ought to validate other libraries too. But it's not + # that important, because in the vast majority of cases where the + # user incorrectly identifies any library, it affects all the + # libraries and if the user can get a handle on the JPEG library + # problem, he will also solve problems with any other library. +} + + + +#****************************************************************************** +# +# MAINLINE +# +#***************************************************************************** + +autoFlushStdout(); + +my $configInPathArg; +if (@ARGV > 0) { + if ($ARGV[0] =~ "^-") { + if ($ARGV[0] eq "--help") { + help(); + exit(0); + } else { + die("Unrecognized option: $ARGV[0]"); + } + } + $configInPathArg = $ARGV[0]; +} + +if (stat("Makefile.config")) { + print("Discard existing Makefile.config?\n"); + print("Y or N (N) ==> "); + + my $answer = ; + if (!defined($answer)) { + die("\nEnd of file on Standard Input"); + } + chomp($answer); + if (uc($answer) ne "Y") { + print("Aborting at user request.\n"); + exit(1); + } +} + +print("\n"); + +displayIntroduction(); + +my ($platform, $subplatform) = getPlatform(); + +print("\n"); + +if ($platform eq "NONE") { + print("You will have to construct Makefile.config manually. To do \n"); + print("this, copy Makefile.config.in as Makefile.config, and then \n"); + print("edit it. Follow the instructions and examples in the file. \n"); + print("Please report your results to the Netpbm maintainer so he \n"); + print("can improve the configure program. \n"); + exit; +} + +getCompiler($platform, \my $compiler); +getLinker($platform, $compiler, \my $baseLinker, \my $linkViaCompiler); + +chooseTestCompiler($compiler, \$testCc); + +my $netpbmlib_runtime_path; + # Undefined if the default from Makefile.config.in is acceptable. + +if ($platform eq "SOLARIS" or $platform eq "IRIX" or + $platform eq "DARWIN" or $platform eq "NETBSD" or + $platform eq "AMIGA") { + print("Where will the Netpbm shared library reside once installed?\n"); + print("Enter 'default' if it will reside somewhere that the shared\n"); + print("library loader will find it automatically. Otherwise, \n"); + print("this directory will get built into the Netpbm programs.\n"); + print("\n"); + + my $default = "default"; + my $response = prompt("Netpbm shared library directory", $default); + + if ($response eq "default") { + $netpbmlib_runtime_path = ""; + } else { + $netpbmlib_runtime_path = $response; + } +} + +my $default_target; + +print("Do you want a regular build or a merge build?\n"); +print("If you don't know what this means, " . + "take the default or see doc/INSTALL\n"); +print("\n"); + +{ + my $default = "regular"; + my $response = prompt("regular or merge", $default); + + if ($response eq "regular") { + $default_target = "nonmerge"; + } elsif ($response eq "merge") { + $default_target = "merge"; + } else { + print("'$response' isn't one of the choices. \n" . + "You must choose 'regular' or 'merge'.\n"); + exit 12; + } +} + +print("\n"); + +getLibTypes($platform, $subplatform, $default_target, + \my $netpbmlibtype, \my $netpbmlibsuffix, \my $shlibprefixlist, + \my $willBuildShared, \my $staticlib_too); + + +getInttypes(\my $inttypesHeaderFile); + +getInt64($inttypesHeaderFile, \my $haveInt64); + +findProcessManagement(\my $dontHaveProcessMgmt); + +#****************************************************************************** +# +# FIND THE PREREQUISITE LIBRARIES +# +#***************************************************************************** + +print("\n\n"); +print("The following questions concern the subroutine libraries that are " . + "Netpbm\n"); +print("prerequisites. Every library has a compile-time part (header " . + "files)\n"); +print("and a link-time part. In the case of a shared library, these are " . + "both\n"); +print("part of the \"development\" component of the library, which may be " . + "separately\n"); +print("installable from the runtime shared library. For each library, you " . + "must\n"); +print("give the filename of the link library. If it is not in your " . + "linker's\n"); +print("default search path, give the absolute pathname of the file. In " . + "addition,\n"); +print("you will be asked for the directory in which the library's interface " . + "headers\n"); +print("reside, and you can respond 'default' if they are in your compiler's " . + "default\n"); +print("search path.\n"); +print("\n"); +print("If you don't have the library on your system, you can enter 'none' " . + "as the\n"); +print("library filename and the builder will skip any part that requires " . + "that "); +print("library.\n"); +print("\n"); + +my ($jpeglib, $jpeghdr_dir) = getJpegLibrary($platform); +print("\n"); +my ($tifflib, $tiffhdr_dir) = getTiffLibrary($platform, $jpeghdr_dir); +print("\n"); +my ($pnglib, $pnghdr_dir) = getPngLibrary($platform, + $tiffhdr_dir, $jpeghdr_dir); +print("\n"); +my ($zlib, $zhdr_dir) = getZLibrary($platform, + $pnghdr_dir, + $tiffhdr_dir, + $jpeghdr_dir); +print("\n"); +my ($x11lib, $x11hdr_dir) = getX11Library($platform); + +print("\n"); +my ($linuxsvgalib, $linuxsvgahdr_dir) = getLinuxsvgaLibrary($platform); + +print("\n"); + +# We should add the JBIG and URT libraries here too. They're a little +# more complicated because there are versions shipped with Netpbm. + + +#****************************************************************************** +# +# CONFIGURE DOCUMENTATION +# +#***************************************************************************** + +print("What URL will you use for the main Netpbm documentation page?\n"); +print("This information does not get built into any programs or libraries.\n"); +print("It does not make anything actually install that web page.\n"); +print("It is just for including in legacy man pages.\n"); +print("\n"); + +my $default = "http://netpbm.sourceforge.net/doc/"; + +my $netpbm_docurl = prompt("Documentation URL", $default); + +print("\n"); + + + + +#****************************************************************************** +# +# VALIDATE THE CONFIGURATION USER HAS SELECTED +# +#***************************************************************************** + +validateLibraries($jpeglib, $tifflib, $pnglib, $zlib); + +warnJpegTiffDependency($jpeglib, $tifflib); + +testConfiguration(needLocal($platform), + $jpeglib, $jpeghdr_dir, + $pnglib, $pnghdr_dir, + $zlib, $zhdr_dir, + ); + +#****************************************************************************** +# +# FIND THE NETPBM SOURCE TREE AND INITIALIZE BUILD TREE +# +#***************************************************************************** + +my $defaultConfigInPath; + +if (-f("GNUmakefile")) { + # He's apparently running us in the source tree or an already set up + # build directory. + $defaultConfigInPath = "Makefile.config.in"; +} else { + my $srcdir; + my $done; + + $done = $FALSE; + while (!$done) { + print("Where is the Netpbm source code?\n"); + + $srcdir = prompt("Netpbm source directory", + abs_path(dirname($0) . "/..")); + + if (-f("$srcdir/GNUmakefile")) { + $done = $TRUE; + } else { + print("That doesn't appear to contain Netpbm source code.\n"); + print("There is no file named 'GNUmakefile' in it.\n"); + print("\n"); + } + } + unlink("GNUmakefile"); + symlink("$srcdir/GNUmakefile", "GNUmakefile"); + unlink("Makefile"); + symlink("$srcdir/Makefile", "Makefile"); + + open(SRCDIR, ">Makefile.srcdir"); + print(SRCDIR "SRCDIR = $srcdir\n"); + close(SRCDIR); + + $defaultConfigInPath = "$srcdir/Makefile.config.in"; +} + +sub makeCompilerGcc($) { + my ($Makefile_configR) = @_; + my $compileCommand = 'gcc'; + push(@{$Makefile_configR}, "CC = $compileCommand\n"); + push(@{$Makefile_configR}, gnuCflags($compileCommand)); +} + + +#****************************************************************************** +# +# BUILD Makefile.config +# +#***************************************************************************** + +sub gnuCflags($) { + my ($gccCommandName) = @_; + + return("CFLAGS = " . gnuOptimizeOpt($gccCommandName) . " -ffast-math " . + " -pedantic -fno-common " . + "-Wall -Wno-uninitialized -Wmissing-declarations -Wimplicit " . + "-Wwrite-strings -Wmissing-prototypes -Wundef\n"); +} + +my @Makefile_config; + # This is the complete Makefile.config contents. We construct it here + # and ultimately write the whole thing out as Makefile.config. + +# First, we just read the 'Makefile.config.in' in + +my $configInPath; +if (defined($configInPathArg)) { + $configInPath = $configInPathArg; +} else { + $configInPath = $defaultConfigInPath; +} +open (CONFIG_IN,"<$configInPath") or + die("Unable to open file '$configInPath' for input."); + +@Makefile_config = ; + +unshift(@Makefile_config, + "####This file was automatically created by 'configure.'\n", + "####Many variables are set twice -- a generic setting, then \n", + "####a system-specific override at the bottom of the file.\n", + "####\n"); + +close(CONFIG_IN); + +# Now, add the variable settings that override the default settings that are +# done by the Makefile.config.in contents. + +push(@Makefile_config, "\n\n\n\n"); +push(@Makefile_config, "####Lines above were copied from Makefile.config.in " . + "by 'configure'.\n"); +push(@Makefile_config, "####Lines below were added by 'configure' based on " . + "the $platform platform.\n"); +if (defined($subplatform)) { + push(@Makefile_config, "####subplatform '$subplatform'\n"); +} + +push(@Makefile_config, "DEFAULT_TARGET = $default_target\n"); + +push(@Makefile_config, "NETPBMLIBTYPE=$netpbmlibtype\n"); +push(@Makefile_config, "NETPBMLIBSUFFIX=$netpbmlibsuffix\n"); +if (defined($shlibprefixlist)) { + push(@Makefile_config, "SHLIBPREFIXLIST=$shlibprefixlist\n"); +} +push(@Makefile_config, "STATICLIB_TOO=$staticlib_too\n"); + +if (defined($netpbmlib_runtime_path)) { + push(@Makefile_config, "NETPBMLIB_RUNTIME_PATH=$netpbmlib_runtime_path\n"); +} + +if ($platform eq "GNU") { + my $compileCommand; + if (!commandExists("cc") && commandExists("gcc")) { + $compileCommand = "gcc"; + push(@Makefile_config, "CC = $compileCommand\n"); + } else { + $compileCommand = "cc"; + } + push(@Makefile_config, gnuCflags($compileCommand)); +# The merged programs have a main_XXX subroutine instead of main(), +# which would cause a warning with -Wmissing-declarations or +# -Wmissing-prototypes. + push(@Makefile_config, "CFLAGS_MERGE = " . + "-Wno-missing-declarations -Wno-missing-prototypes\n"); + push(@Makefile_config, "LDRELOC = ld --reloc\n"); + push(@Makefile_config, "LINKER_CAN_DO_EXPLICIT_LIBRARY=Y\n"); +} elsif ($platform eq "SOLARIS") { + push(@Makefile_config, 'LDSHLIB = -Wl,-Bdynamic,-G,-h,$(SONAME)', "\n"); + + push(@Makefile_config, 'NEED_RUNTIME_PATH = Y', "\n"); + if ($compiler eq "cc") { + push(@Makefile_config, "CFLAGS = -O\n"); + push(@Makefile_config, "CFLAGS_SHLIB = -Kpic\n"); + } else { + makeCompilerGcc(\@Makefile_config); + } + # Before Netpbm 10.20 (January 2004), we set this to -R for + # $compiler == cc and -rpath otherwise. But now we know that the GNU + # compiler can also invoke a linker that needs -R, so we're more flexible. + if ($baseLinker eq "GNU") { + push(@Makefile_config, "RPATHOPTNAME = -rpath\n"); + } else { + push(@Makefile_config, "RPATHOPTNAME = -R\n"); + } + push(@Makefile_config, "NETWORKLD = -lsocket -lnsl\n"); +} elsif ($platform eq "HP-UX") { + if ($compiler eq "gcc") { + makeCompilerGcc(\@Makefile_config); + push(@Makefile_config, "CFLAGS += -fPIC\n"); + push(@Makefile_config, "LDSHLIB = -shared -fPIC\n"); + push(@Makefile_config, 'LDFLAGS += -Wl,+b,/usr/pubsw/lib', "\n"); + } else { + # We don't know what to do here. We used to (before 10.20) just + # just assume the compiler was gcc. We know that the gcc stuff + # above does NOT work for HP native compiler. + } +} elsif ($platform eq "AIX") { + push(@Makefile_config, 'LDFLAGS = -L /usr/pubsw/lib', "\n"); + if ($compiler eq "cc") { + # Yes, the -L option implies the runtime as well as linktime library + # search path. There's no way to specify runtime path independently. + push(@Makefile_config, "RPATHOPTNAME = -L\n"); + push(@Makefile_config, "LDSHLIB = -qmkshrobj\n"); + } else { + makeCompilerGcc(\@Makefile_config); + push(@Makefile_config, "LDSHLIB = -shared\n"); + } +} elsif ($platform eq "TRU64") { +# push(@Makefile_config, "INSTALL = installbsd\n"); + if ($compiler eq "cc") { + push(@Makefile_config, 'CFLAGS = -O2 -std1', "\n"); + push(@Makefile_config, "LDFLAGS = -call_shared -oldstyle_liblookup " . + "-L/usr/local/lib\n"); + push(@Makefile_config, "LDSHLIB = -shared -expect_unresolved \"*\"\n"); + } else { + # We've never tested this. This is just here to give a user a + # headstart on submitting to us the necessary information. 2002.07.04. + push(@Makefile_config, "CC = gcc\n"); + push(@Makefile_config, 'CFLAGS = -O3', "\n"); + push(@Makefile_config, "LDSHLIB = -shared\n"); + } + # Between May 2000 and July 2003, we had -DLONG_32 in these options. + # We took it out because it generated bad code for a TRU64 user in + # July 2003 whose system has 64 bit long and 32 bit int. It affects + # only Ppmtompeg and it isn't clear that using long instead of int is + # ever right anyway. + + push(@Makefile_config, "OMIT_NETWORK = y\n"); + push(@Makefile_config, "LINKER_CAN_DO_EXPLICIT_LIBRARY=Y\n"); +} elsif ($platform eq "IRIX") { +# push(@Makefile_config, "INSTALL = install\n"); + push(@Makefile_config, "MANPAGE_FORMAT = cat\n"); + push(@Makefile_config, "RANLIB = true\n"); + push(@Makefile_config, "CFLAGS = -n32 -O3 -fullwarn\n"); + push(@Makefile_config, "LDFLAGS = -n32\n"); + push(@Makefile_config, "LDSHLIB = -shared -n32\n"); +} elsif ($platform eq "WINDOWS") { + if ($subplatform eq "cygwin") { + makeCompilerGcc(\@Makefile_config); + } + push(@Makefile_config, "EXE = .exe\n"); + push(@Makefile_config, "OMIT_NETWORK = y\n"); +# # Though it may not have the link as "ginstall", "install" in a Windows +# # Unix environment is usually GNU install. +# my $ginstall_result = `ginstall --version 2>/dev/null`; +# if (!$ginstall_result) { +# # System doesn't have 'ginstall', so use 'install' instead. +# push(@Makefile_config, "INSTALL = install\n"); +# } + push(@Makefile_config, 'SYMLINK = ', symlink_command(), "\n"); + push(@Makefile_config, 'DLLVER=$(NETPBM_MAJOR_RELEASE)', "\n"); + push(@Makefile_config, "LDSHLIB = " . + '-shared -Wl,--image-base=0x10000000 -Wl,--enable-auto-import', "\n"); +} elsif ($platform eq "BEOS") { + push(@Makefile_config, "LDSHLIB = -nostart\n"); +} elsif ($platform eq "NETBSD") { + push(@Makefile_config, 'CFLAGS_SHLIB = -fpic', "\n"); +} elsif ($platform eq "OPENBSD") { + # vedge@vedge.com.ar says on 2001.04.29 that there are a ton of + # undefined symbols in the Fiasco stuff on OpenBSD. So we'll just + # cut it out of the build until someone feels like fixing it. + push(@Makefile_config, "BUILD_FIASCO = N\n"); +} elsif ($platform eq "FREEBSD") { +} elsif ($platform eq "AMIGA") { + push(@Makefile_config, "CFLAGS = -m68020-60 -ffast-math -mstackextend\n"); +} elsif ($platform eq "UNIXWARE") { + # Nothing to do. +} elsif ($platform eq "SCO") { + # Got this from "John H. DuBois III" 2002.09.27: + push(@Makefile_config, "RANLIB = true\n"); + if ($compiler eq "cc") { + push(@Makefile_config, "CFLAGS = -O\n"); + push(@Makefile_config, "CFLAGS_SHLIB = -O -K pic\n"); + push(@Makefile_config, "LD_SHLIB = -G\n"); + push(@Makefile_config, "SHLIB_CLIB =\n"); + } else { + makeCompilerGcc(\@Makefile_config); + } + push(@Makefile_config, "CFLAGS_SHLIB = -fPIC\n"); + push(@Makefile_config, "LDSHLIB = -shared\n"); + push(@Makefile_config, "NETWORKLD = -lsocket -lresolve\n"); +} elsif ($platform eq "DARWIN") { + push(@Makefile_config, "CC = cc -no-cpp-precomp\n"); + push(@Makefile_config, 'CFLAGS_SHLIB = -fno-common', "\n"); + push(@Makefile_config, "LDSHLIB = ", + "-dynamiclib ", + '-install_name $(NETPBM_RUNTIME_PATH)/libnetpbm.$(MAJ).dylib', + "\n"); +# push(@Makefile_config, "INSTALL = install\n"); +} else { + die ("Internal error: invalid value for \$platform: '$platform'\n"); +} + +if (needLocal($platform)) { + push(@Makefile_config, "CFLAGS += -I/usr/local/include\n"); + push(@Makefile_config, "LDFLAGS += -L/usr/local/lib\n"); +} + +if ($linkViaCompiler) { + push(@Makefile_config, "LINKERISCOMPILER = Y\n"); +} + +my $flex_result = `flex --version`; +if (!$flex_result) { + # System doesn't have 'flex'. Maybe 'lex' will work. See the + # make rules for Thinkjettopbm for information on our experiences + # with Lexes besides Flex. + + my $systemRc = system('lex /dev/null'); + + if ($systemRc >> 8 == 127) { + print("\n"); + print("You do not appear to have the 'flex' or 'lex' pattern \n"); + print("matcher generator on your system, so we will not build \n"); + print("programs that need it (Thinkjettopbm)\n"); + + print("\n"); + print("Press ENTER to continue.\n"); + my $key = ; + print("\n"); + + push(@Makefile_config, "LEX=\n"); + } else { + print("\n"); + print("Using 'lex' as the pattern matcher generator, " . + "since we cannot\n"); + print("find 'flex' on your system.\n"); + print("\n"); + + push(@Makefile_config, "LEX = lex\n"); + } +} + +if (defined($tiffhdr_dir)) { + push(@Makefile_config, "TIFFHDR_DIR = $tiffhdr_dir\n"); +} +if (defined($tifflib)) { + push(@Makefile_config, "TIFFLIB = $tifflib\n"); +} + +if (defined($jpeghdr_dir)) { + push(@Makefile_config, "JPEGHDR_DIR = $jpeghdr_dir\n"); +} +if (defined($jpeglib)) { + push(@Makefile_config, "JPEGLIB = $jpeglib\n"); +} + +if (defined($pnghdr_dir)) { + push(@Makefile_config, "PNGHDR_DIR = $pnghdr_dir\n"); +} +if (defined($pnglib)) { + push(@Makefile_config, "PNGLIB = $pnglib\n"); +} + +if (defined($zhdr_dir)) { + push(@Makefile_config, "ZHDR_DIR = $zhdr_dir\n"); +} +if (defined($zlib)) { + push(@Makefile_config, "ZLIB = $zlib\n"); +} + +if (defined($x11hdr_dir)) { + push(@Makefile_config, "X11HDR_DIR = $x11hdr_dir\n"); +} +if (defined($x11lib)) { + push(@Makefile_config, "X11LIB = $x11lib\n"); +} + +if (defined($linuxsvgahdr_dir)) { + push(@Makefile_config, "LINUXSVGAHDR_DIR = $linuxsvgahdr_dir\n"); +} +if (defined($linuxsvgalib)) { + push(@Makefile_config, "LINUXSVGALIB = $linuxsvgalib\n"); +} + +if (defined($netpbm_docurl)) { + push(@Makefile_config, "NETPBM_DOCURL = $netpbm_docurl\n"); +} + +if ($inttypesHeaderFile ne '') { + push(@Makefile_config, "INTTYPES_H = $inttypesHeaderFile\n"); +} + +if ($haveInt64 ne 'Y') { + push(@Makefile_config, "HAVE_INT64 = $haveInt64\n"); +} + +if ($dontHaveProcessMgmt) { + push(@Makefile_config, "DONT_HAVE_PROCESS_MGMT = Y\n"); +} + +#****************************************************************************** +# +# WRITE OUT THE FILE +# +#***************************************************************************** + +open(MAKEFILE_CONFIG, ">Makefile.config") or + die("Unable to open Makefile.config for writing in the current " . + "directory."); + +print MAKEFILE_CONFIG @Makefile_config; + +close(MAKEFILE_CONFIG) or + die("Error: Close of Makefile.config failed.\n"); + +print("\n"); +print("We have created the file 'Makefile.config'. Note, however, that \n"); +print("we guessed a lot at your configuration and you may want to look \n"); +print("at Makefile.config and edit it to your requirements and taste \n"); +print("before doing the make.\n"); +print("\n"); + + +print("Now you may proceed with 'make'\n"); +print("\n"); + + +exit 0; diff --git a/buildtools/empty_depend b/buildtools/empty_depend new file mode 100755 index 00000000..a4ba372c --- /dev/null +++ b/buildtools/empty_depend @@ -0,0 +1,19 @@ +#!/usr/bin/perl -w + +use strict; + +# This program turns every Makefile.depend file into an empty file, +# so that dependencies in there can't make trouble for users trying to +# build Netpbm. They don't need dependencies anyway, since they're +# building everything and not modifying anything. + +# Developers should do 'make dep' to create real Makefile.depend files +# before building + +my $mf_list = `find . -name Makefile.depend`; +my @mf_list = split(/\s/, $mf_list); +foreach (@mf_list) { + print "Emptying $_\n"; + open(MF, ">$_"); + close(MF); +} diff --git a/buildtools/endiangen b/buildtools/endiangen new file mode 100755 index 00000000..8783096e Binary files /dev/null and b/buildtools/endiangen differ diff --git a/buildtools/endiangen.c b/buildtools/endiangen.c new file mode 100644 index 00000000..07560c10 --- /dev/null +++ b/buildtools/endiangen.c @@ -0,0 +1,97 @@ +/*---------------------------------------------------------------------------- + endiangen +------------------------------------------------------------------------------ + This is a program to create C code that declares the endianness of the + machine on which it is run. + + It generates something like this: + + #ifndef LITTLE_ENDIAN + #define LITTLE_ENDIAN 1234 + #endif + + #ifndef BIG_ENDIAN + #define BIG_ENDIAN 4321 + #endif + + #ifndef BYTE_ORDER + #define BYTE_ORDER LITTLE_ENDIAN + #endif + + #define BITS_PER_WORD 32 + #endif + + + Really good code usually is not sensitive to endianness. But fast, + not-so-good code often is. The best way for code to determine + endianness is for it to do a runtime cast of an integer to an array + of characters and see where the bytes land. But if speed requires + even sleazier code than that, use these macros. + +-----------------------------------------------------------------------------*/ +#include +#include + +#define MAX(a,b) ((a) > (b) ? (a) : (b)) + +enum endianness {ENDIAN_LITTLE, ENDIAN_BIG}; + +static enum endianness +byteOrder(void) { + + enum endianness retval; + + union { + unsigned char arrayval[2]; + unsigned short numval; + } testunion; + + testunion.numval = 3; + + if (testunion.arrayval[0] == 3) + retval = ENDIAN_LITTLE; + else + retval = ENDIAN_BIG; + + return retval; +} + + + +static unsigned int +bitsPerWord(void) { + + return MAX(sizeof(long), sizeof(int)) * 8; +} + + + +int +main(int argc, char **argv) { + + printf("/* This was generated by the program 'endiangen' */\n"); + printf("\n"); + printf("/* LITTLE_ENDIAN, BIG_ENDIAN, and BYTE_ORDER " + "may come from the C library\n"); + printf("via ctype.h. */\n"); + printf("#include \n"); + printf("#ifndef LITTLE_ENDIAN\n"); + printf("#define LITTLE_ENDIAN 1234\n"); + printf("#endif\n"); + printf("#ifndef BIG_ENDIAN\n"); + printf("#define BIG_ENDIAN 4321\n"); + printf("#endif\n"); + printf("\n"); + printf("#ifndef BYTE_ORDER\n"); + printf("#define BYTE_ORDER %s\n", + byteOrder() == ENDIAN_LITTLE ? "LITTLE_ENDIAN" : "BIG_ENDIAN"); + printf("#endif\n"); + printf("\n"); + printf("#define BITS_PER_WORD %u\n", bitsPerWord()); + + return 0; +} + + + + diff --git a/buildtools/install.sh b/buildtools/install.sh new file mode 100755 index 00000000..cd324f3d --- /dev/null +++ b/buildtools/install.sh @@ -0,0 +1,255 @@ +#! /bin/sh +# +# install - install a program, script, or datafile +# This comes from X11R5 (mit/util/scripts/install.sh). +# +# Copyright 1991 by the Massachusetts Institute of Technology +# +# Permission to use, copy, modify, distribute, and sell this software and its +# documentation for any purpose is hereby granted without fee, provided that +# the above copyright notice appear in all copies and that both that +# copyright notice and this permission notice appear in supporting +# documentation, and that the name of M.I.T. not be used in advertising or +# publicity pertaining to distribution of the software without specific, +# written prior permission. M.I.T. makes no representations about the +# suitability of this software for any purpose. It is provided "as is" +# without express or implied warranty. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# `make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. +# + + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit="${DOITPROG-}" + + +# put in absolute paths if you don't have them in your path; or use env. vars. + +mvprog="${MVPROG-mv}" +cpprog="${CPPROG-cp}" +chmodprog="${CHMODPROG-chmod}" +chownprog="${CHOWNPROG-chown}" +chgrpprog="${CHGRPPROG-chgrp}" +stripprog="${STRIPPROG-strip}" +rmprog="${RMPROG-rm}" +mkdirprog="${MKDIRPROG-mkdir}" + +transformbasename="" +transform_arg="" +instcmd="$mvprog" +chmodcmd="$chmodprog 0755" +chowncmd="" +chgrpcmd="" +stripcmd="" +rmcmd="$rmprog -f" +mvcmd="$mvprog" +src="" +dst="" +dir_arg="" + +while [ x"$1" != x ]; do + case $1 in + -c) instcmd="$cpprog" + shift + continue;; + + -d) dir_arg=true + shift + continue;; + + -m) chmodcmd="$chmodprog $2" + shift + shift + continue;; + + -o) chowncmd="$chownprog $2" + shift + shift + continue;; + + -g) chgrpcmd="$chgrpprog $2" + shift + shift + continue;; + + -s) stripcmd="$stripprog" + shift + continue;; + + -t=*) transformarg=`echo $1 | sed 's/-t=//'` + shift + continue;; + + -b=*) transformbasename=`echo $1 | sed 's/-b=//'` + shift + continue;; + + *) if [ x"$src" = x ] + then + if [ -f "$1.exe" ] + then + src=$1.exe + else + src=$1 + fi + else + # this colon is to work around a 386BSD /bin/sh bug + : + dst=$1 + fi + shift + continue;; + esac +done + +if [ x"$src" = x ] +then + echo "install: no input file specified" + exit 1 +else + true +fi + +if [ x"$dir_arg" != x ]; then + dst=$src + src="" + + if [ -d $dst ]; then + instcmd=: + else + instcmd=mkdir + fi +else + +# Waiting for this to be detected by the "$instcmd $src $dsttmp" command +# might cause directories to be created, which would be especially bad +# if $src (and thus $dsttmp) contains '*'. + + if [ -f $src -o -d $src ] + then + true + else + echo "install: $src does not exist" + exit 1 + fi + + if [ x"$dst" = x ] + then + echo "install: no destination specified" + exit 1 + else + true + fi + +# If destination is a directory, append the input filename; if your system +# does not like double slashes in filenames, you may need to add some logic + + if [ -d $dst ] + then + dst="$dst"/`basename $src` + else + true + fi +fi + +## this sed command emulates the dirname command +dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` + +# Make sure that the destination directory exists. +# this part is taken from Noah Friedman's mkinstalldirs script + +# Skip lots of stat calls in the usual case. +if [ ! -d "$dstdir" ]; then +defaultIFS=' +' +IFS="${IFS-${defaultIFS}}" + +oIFS="${IFS}" +# Some sh's can't handle IFS=/ for some reason. +IFS='%' +set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` +IFS="${oIFS}" + +pathcomp='' + +while [ $# -ne 0 ] ; do + pathcomp="${pathcomp}${1}" + shift + + if [ ! -d "${pathcomp}" ] ; + then + $mkdirprog "${pathcomp}" + else + true + fi + + pathcomp="${pathcomp}/" +done +fi + +if [ x"$dir_arg" != x ] +then + $doit $instcmd $dst && + + if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi +else + +# If we're going to rename the final executable, determine the name now. + + if [ x"$transformarg" = x ] + then + dstfile=`basename $dst` + else + dstfile=`basename $dst $transformbasename | + sed $transformarg`$transformbasename + fi + +# don't allow the sed command to completely eliminate the filename + + if [ x"$dstfile" = x ] + then + dstfile=`basename $dst` + else + true + fi + +# Make a temp file name in the proper directory. + + dsttmp=$dstdir/#inst.$$# + +# Move or copy the file name to the temp name + + $doit $instcmd $src $dsttmp && + + trap "rm -f ${dsttmp}" 0 && + +# and set any options; do chmod last to preserve setuid bits + +# If any of these fail, we abort the whole thing. If we want to +# ignore errors from any of these, just make sure not to ignore +# errors from the above "$doit $instcmd $src $dsttmp" command. + + if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && + +# Now rename the file to the real destination. + + $doit $rmcmd -f $dstdir/$dstfile && + $doit $mvcmd $dsttmp $dstdir/$dstfile + +fi && + + +exit 0 diff --git a/buildtools/installnetpbm.pl b/buildtools/installnetpbm.pl new file mode 100755 index 00000000..db3f6200 --- /dev/null +++ b/buildtools/installnetpbm.pl @@ -0,0 +1,919 @@ +#!/usr/bin/perl -w + +require 5.000; + +#Note: mkdir() must have 2 arguments as late as 5.005. + +use strict; +use English; +use Fcntl; +use File::Basename; + +my ($TRUE, $FALSE) = (1,0); + +my $cpCommand; +#use vars qw($cpCommand); + +#****************************************************************************** +# +# SUBROUTINES +# +#***************************************************************************** + +sub autoFlushStdout() { + my $oldFh = select(STDOUT); + $OUTPUT_AUTOFLUSH = $TRUE; + select($oldFh); +} + + + +sub prompt($$) { + + my ($prompt, $default) = @_; + + print("$prompt ($default) ==> "); + + my $response = ; + + chomp($response); + if ($response eq "") { + $response = $default; + } + + return $response; +} + + + +sub getPkgdir() { + + my $pkgdir; + + while (!$pkgdir) { + + print("Where is the install package you created with " . + "'make package'?\n"); + my $default = "/tmp/netpbm"; + + my $response = prompt("package directory", $default); + + if (!-f("$response/pkginfo")) { + print("This does not appear to be a Netpbm install package. \n"); + print("A file named $response/pkginfo does not exist.\n"); + print("\n"); + } else { + $pkgdir = $response; + } + } + print("\n"); + return $pkgdir; +} + + + +sub makePrefixDirectory($) { + + my ($prefixDir) = @_; + + if ($prefixDir ne "" and !-d($prefixDir)) { + print("No directory named '$prefixDir' exists. Do you want " . + "to create it?\n"); + + my $done; + while (!$done) { + my $response = prompt("Y(es) or N(o)", "Y"); + if (uc($response) eq "Y") { + my $success = mkdir($prefixDir, 0777); + if (!$success) { + print("Unable to create directory '$prefixDir'. " . + "Error is $ERRNO\n"); + } + $done = $TRUE; + } elsif (uc($response) eq "N") { + $done = $TRUE; + } + } + } +} + + + + + +sub getPrefix() { + + print("Enter the default prefix for installation locations. " . + "I will use \n"); + print("this in generating defaults for the following prompts to " . + "save you \n"); + print("typing. If you plan to spread Netpbm across your system, \n" . + "enter '/'.\n"); + print("\n"); + + my $default; + if ($OSNAME eq "cygwin") { + $default = "/usr/local"; + } elsif ($ENV{OSTYPE} && $ENV{OSTYPE} eq "msdosdjgpp") { + $default = "/dev/env/DJDIR"; + } else { + $default = "/usr/local/netpbm"; + } + + my $response = prompt("install prefix", $default); + + my $prefix; + + # Remove possible trailing / + if (substr($response,-1,1) eq "/") { + $prefix = substr($response, 0, -1); + } else { + $prefix = $response; + } + print("\n"); + + makePrefixDirectory($prefix); + + return $prefix; +} + + + +sub getCpCommand() { +#----------------------------------------------------------------------------- +# compute the command + options need to do a recursive copy, preserving +# symbolic links and file attributes. +#----------------------------------------------------------------------------- + my $cpCommand; + + # We definitely need more intelligence here, but we'll need input from + # users to do it. Maybe we should just bundle GNU Cp with Netpbm as an + # install tool. Maybe we should write a small recursive copy program + # that uses more invariant tools, like buildtools/install.sh does for + # single files. + + if (`cp --version 2>/dev/null` =~ m/GNU/) { + # It's GNU Cp -- we have options galore, and they're readable. + $cpCommand = "cp --recursive --preserve --no-dereference"; + } else { + # This works on Cp from "4th Berkeley Distribution", July 1994. + # Mac OSX has this. + # -R means recursive with no dereferencing of symlinks + # -p means preserve attributes + $cpCommand = "cp -R -p"; + } + return($cpCommand); +} + + + +sub getBinDir($) { + + my ($prefix) = @_; + + print("Where do you want the programs installed?\n"); + print("\n"); + + my $binDir; + + while (!$binDir) { + my $default = "$prefix/bin"; + + my $response = prompt("program directory", $default); + + if (-d($response)) { + $binDir = $response; + } else { + my $succeeded = mkdir($response, 0777); + + if (!$succeeded) { + print("Unable to create directory '$response'. " . + "Error=$ERRNO\n"); + } else { + $binDir = $response; + } + } + } + print("\n"); + + return $binDir; +} + + + +sub installProgram($$$) { + + my ($pkgdir, $prefix, $bindirR) = @_; + + my $binDir = getBinDir($prefix); + + print("Installing programs...\n"); + + my $rc = system("$cpCommand $pkgdir/bin/* $binDir/"); + + if ($rc != 0) { + print("Copy of programs from $pkgdir/bin to $binDir failed.\n"); + print("cp return code is $rc\n"); + } else { + print("Done.\n"); + } + $$bindirR = $binDir; +} + + + +sub getLibDir($) { + + my ($prefix) = @_; + + print("Where do you want the shared library installed?\n"); + print("\n"); + + my $libDir; + + while (!$libDir) { + my $default = "$prefix/lib"; + + my $response = prompt("shared library directory", $default); + + if (-d($response)) { + $libDir = $response; + } else { + my $succeeded = mkdir($response, 0777); + + if (!$succeeded) { + print("Unable to create directory '$response'. " . + "Error=$ERRNO\n"); + } else { + $libDir = $response; + } + } + } + print("\n"); + + return $libDir; +} + + + +sub +execLdconfig() { +#----------------------------------------------------------------------------- +# Run Ldconfig. Try with the -X option first, and if that is an invalid +# option (which we have seen on an openBSD system), try it without -X. +# +# -X means "don't create any symlinks." Any symlinks required should be +# created as part of installing the library, so we don't need that function +# from Ldconfig. And we want to tread as lightly as possible on the +# system -- we don't want creating symlinks that have nothing to do with +# Netpbm to be a hidden side effect of installing Netpbm. +# +# Note that this Ldconfig works only if the user installed the Netpbm +# library in a standard directory that Ldconfig searches. Note that on +# OpenBSD, Ldconfig is hardcoded to search only /usr/lib ever. We could +# also do 'ldconfig DIR' to scan the particular directory in which we +# installed the Netpbm library. But 1) the effects of this would disappear +# the next time the user rebuilds the cache file; and 2) on OpenBSD, this +# causes the cache file to be rebuilt from ONLY that directory. On OpenBSD, +# you can add the -m option to cause it to ADD the contents of DIR to the +# existing cache file. +# +#----------------------------------------------------------------------------- +# Implementation note: We've seen varying completion codes and varying +# error messages from different versions of Ldconfig when it fails. + + my $ldconfigSucceeded; + + my $ldconfigXResp = `ldconfig -X 2>&1`; + + if (!defined($ldconfigXResp)) { + print("Unable to run Ldconfig.\n"); + $ldconfigSucceeded = $FALSE; + } elsif ($ldconfigXResp eq "") { + $ldconfigSucceeded = $TRUE; + } elsif ($ldconfigXResp =~ m{usage}i) { + print("Trying Ldconfig again without the -X option...\n"); + + my $rc = system("ldconfig"); + + $ldconfigSucceeded = ($rc == 0); + } else { + print($ldconfigXResp); + $ldconfigSucceeded = $FALSE; + } + + if ($ldconfigSucceeded) { + print("Ldconfig completed successfully.\n"); + } else { + print("Ldconfig failed. You will have to fix this later.\n"); + } +} + + + +sub +doLdconfig() { +#----------------------------------------------------------------------------- +# Run Ldconfig where appropriate. +#----------------------------------------------------------------------------- + if ($OSNAME eq "linux" || system("ldconfig -? 2>/dev/null") != 127) { + # This is a system where Ldconfig makes sense + + print("In order for the Netpbm shared library to be found when " . + "you invoke \n"); + print("A Netpbm program, you must either set an environment " . + "variable to \n"); + print("tell where to look for it, or you must put its location " . + "in the shared \n"); + print("library location cache. Do you want to run Ldconfig now " . + "to put the \n"); + print("Netpbm shared library in the cache? This works only if " . + "you have\n"); + print("installed the library in a standard location.\n"); + print("\n"); + + my $done; + + $done = $FALSE; + + while (!$done) { + my $response = prompt("Y(es) or N(o)", "Y"); + + if (uc($response) eq "Y") { + execLdconfig(); + $done = $TRUE; + } elsif (uc($response) eq "N") { + $done = $TRUE; + } else { + print("Invalid response. Enter 'Y' or 'N'\n"); + } + } + } +} + + + +sub installSharedLib($$$) { + + my ($pkgdir, $prefix, $libdirR) = @_; + + if (-d("$pkgdir/lib")) { + my $libDir = getLibDir($prefix); + + print("Installing shared libraries...\n"); + + my $rc = system("$cpCommand $pkgdir/lib/* $libDir/"); + + if ($rc != 0) { + print("Copy of libraries from $pkgdir/lib to $libDir failed.\n"); + print("cp return code is $rc\n"); + } else { + print("done.\n"); + print("\n"); + doLdconfig(); + } + $$libdirR = $libDir; + } else { + print("You did not build a shared library, so I will not " . + "install one.\n"); + } + print("\n"); +} + + + +sub getLinkDir($) { + + my ($prefix) = @_; + + print("Where do you want the static link library installed?\n"); + print("\n"); + + my $linkDir; + + while (!$linkDir) { + my $default = "$prefix/lib"; + + my $response = prompt("static library directory", $default); + + if (-d($response)) { + $linkDir = $response; + } else { + my $succeeded = mkdir($response, 0777); + + if (!$succeeded) { + print("Unable to create directory '$response'. " . + "Error=$ERRNO\n"); + } else { + $linkDir = $response; + } + } + } + print("\n"); + + return $linkDir; +} + + + +sub installStaticLib($$$) { + + my ($pkgdir, $prefix, $linkdirR) = @_; + + if (-d("$pkgdir/link")) { + my $linkDir = getLinkDir($prefix); + + print("Installing link libraries.\n"); + + my $rc = system("$cpCommand $pkgdir/link/* $linkDir/"); + + if ($rc != 0) { + print("Copy of files from $pkgdir/link to $linkDir failed.\n"); + print("cp return code is $rc\n"); + } else { + print("done.\n"); + } + $$linkdirR = $linkDir; + } else { + print("You did not build a static library, so I will not " . + "install one \n"); + } +} + + + +sub getDataDir($) { + + my ($prefix) = @_; + + print("Where do you want the data files installed?\n"); + print("\n"); + + my $dataDir; + + while (!$dataDir) { + my $default = "$prefix/lib"; + + my $response = prompt("data file directory", $default); + + if (-d($response)) { + $dataDir = $response; + } else { + my $succeeded = mkdir($response, 0777); + + if (!$succeeded) { + print("Unable to create directory '$response'. " . + "Error=$ERRNO\n"); + } else { + $dataDir = $response; + } + } + } + print("\n"); + + return $dataDir; +} + + + +sub getHdrDir($) { + + my ($prefix) = @_; + + print("Where do you want the library interface header files installed?\n"); + print("\n"); + + my $hdrDir; + + while (!$hdrDir) { + my $default = "$prefix/include"; + + my $response = prompt("header directory", $default); + + if (-d($response)) { + $hdrDir = $response; + } else { + my $succeeded = mkdir($response, 0777); + + if (!$succeeded) { + print("Unable to create directory '$response'. " . + "Error=$ERRNO\n"); + } else { + $hdrDir = $response; + } + } + } + print("\n"); + + return $hdrDir; +} + + + +sub installDataFile($$$) { + + my ($pkgdir, $prefix, $datadirR) = @_; + + my $dataDir = getDataDir($prefix); + + print("Installing data files...\n"); + + my $rc = system("$cpCommand $pkgdir/misc/* $dataDir/"); + + if ($rc != 0) { + print("copy of data files from $pkgdir/misc to $dataDir " . + "failed.\n"); + print("cp exit code is $rc\n"); + } else { + $$datadirR = $dataDir; + print("done.\n"); + } +} + + + +sub installHeader($$$) { + + my ($pkgdir, $prefix, $includedirR) = @_; + + my $hdrDir = getHdrDir($prefix); + + print("Installing interface header files...\n"); + + my $rc = system("$cpCommand $pkgdir/include/* $hdrDir/"); + + if ($rc != 0) { + print("copy of header files from $pkgdir/include to $hdrDir " . + "failed.\n"); + print("cp exit code is $rc\n"); + } else { + print("done.\n"); + } + $$includedirR = $hdrDir; +} + + + +sub getManDir($) { + + my ($prefix) = @_; + + print("Where do you want the man pages installed?\n"); + + print("\n"); + + my $manDir; + + while (!$manDir) { + my $default = "$prefix/man"; + + my $response = prompt("man page directory", $default); + + if (-d($response)) { + $manDir = $response; + } else { + my $succeeded = mkdir($response, 0777); + + if (!$succeeded) { + print("Unable to create directory '$response'. " . + "Error=$ERRNO\n"); + } else { + $manDir = $response; + } + } + } + print("\n"); + + return $manDir; +} + + + +sub removeObsoleteManPage($) { + + my ($mandir) = @_; + + unlink("$mandir/man1/pgmoil"); + unlink("$mandir/man1/pgmnorm"); + unlink("$mandir/man1/ppmtojpeg"); + unlink("$mandir/man1/bmptoppm"); + unlink("$mandir/man1/ppmtonorm"); + unlink("$mandir/man1/ppmtouil"); + unlink("$mandir/man1/pnmnoraw"); + unlink("$mandir/man1/gemtopbm"); + unlink("$mandir/man1/pnminterp"); +} + + + +sub tryToCreateManwebConf($) { + + my ($manweb_conf_filename) = $@; + + print("You don't have a /etc/manweb.conf, which is the " . + "configuration\n"); + print("file for the 'manweb' program, which is a quick way to " . + "get to Netpbm\n"); + print("documentation. Would you like to create one now?\n"); + + my $done; + + while (!$done) { + my $response = prompt("create /etc/manweb.conf", "Y"); + + if (uc($response) eq "Y") { + my $successful = open(MANWEB_CONF, ">/etc/manweb.conf"); + if (!$successful) { + print("Unable to create file /etc/manweb.conf. " . + "error = $ERRNO\n"); + } else { + print(MANWEB_CONF "#Configuration file for Manweb\n"); + print(MANWEB_CONF "webdir=/usr/man/web\n"); + close(MANWEB_CONF); + $done = $TRUE; + } + } else { + $done = $TRUE; + } + } +} + + + +sub getWebdir($) { + my ($manweb_conf_filename) = @_; +#----------------------------------------------------------------------------- +# Return the value of the Manweb "web directory," as indicated by the +# Manweb configuration file $manweb_conf_filename. +# +# If that file doesn't exist, or doesn't have a 'webdir' value, or +# the 'webdir' value is a chain of directories instead of just one, +# we return an undefined value. +#----------------------------------------------------------------------------- + my $webdir; + + my $success = open(MANWEB_CONF, "<$manweb_conf_filename"); + if (!$success) { + print("Unable to open file '$manweb_conf_filename' for reading. " . + "error is $ERRNO\n"); + } else { + while () { + chomp(); + if (/^\s*#/) { + #It's comment - ignore + } elsif (/^\s*$/) { + #It's a blank line - ignore + } elsif (/\s*(\S+)\s*=\s*(\S+)/) { + #It looks like "keyword=value" + my ($keyword, $value) = ($1, $2); + if ($keyword eq "webdir") { + # We can't handle a multi-directory path; we're looking + # only for a webdir statement naming a sole directory. + if ($value !~ m{:}) { + $webdir = $value; + } + } + } + } + close(MANWEB_CONF); + } + + return $webdir +} + + + +sub userWantsManwebSymlink($$) { + + my ($webdir, $netpbmWebdir) = @_; + + print("Your manweb.conf file says top level documentation " . + "is in $webdir, \n"); + print("but you installed netpbm.url in $netpbmWebdir.\n"); + print("Do you want to create a symlink in $webdir now?\n"); + + my $wants; + my $done; + + while (!$done) { + my $response = prompt("create symlink (Y/N)", "Y"); + + if (uc($response) eq "Y") { + $wants = $TRUE; + $done = $TRUE; + } elsif (uc($response) eq "N") { + $wants = $FALSE; + $done = $TRUE; + } + } + return $wants; +} + + + +sub makeInManwebPath($) { + + my ($netpbmWebdir) = @_; + + # Now we need /etc/manweb.conf to point to the directory in which we + # just installed netpbm.url. + + if (!-f("/etc/manweb.conf")) { + tryToCreateManwebConf("/etc/manweb.conf"); + } + if (-f("/etc/manweb.conf")) { + my $webdir = getWebdir("/etc/manweb.conf"); + if (defined($webdir)) { + if ($webdir ne $netpbmWebdir) { + if (userWantsManwebSymlink($webdir, $netpbmWebdir)) { + my $old = "$netpbmWebdir/netpbm.url"; + my $new = "$webdir/netpbm.url"; + mkdir($webdir, 0777); + my $success = symlink($old, $new); + if (!$success) { + print("Failed to create symbolic link from $new to " . + "$old. Error is $ERRNO\n"); + } + } + } + } + } +} + + + +sub installManPage($$$) { + + +# Note: This installs the pointer man pages and the netpbm.url file for Manweb. + + my ($pkgdir, $prefix, $mandirR) = @_; + + my $manDir = getManDir($prefix); + + print("Installing man pages...\n"); + + my $rc = system("$cpCommand $pkgdir/man/* $manDir/"); + + if ($rc != 0) { + print("copy of man pages from $pkgdir/man to $manDir failed.\n"); + print("cp exit code is $rc\n"); + } else { + print("done.\n"); + } + + print("\n"); + + removeObsoleteManPage($manDir); + + makeInManwebPath("$manDir/web"); + + $$mandirR = $manDir; +} + + + +sub +processTemplate($$$$$$$$$) { + my ($templateR, $version, $bindir, $libdir, $linkdir, $datadir, + $includedir, $mandir, $outputR) = @_; + + my @output; + + foreach (@{$templateR}) { + if (m{^@}) { + # Comment -- ignore it. + } else { + if (defined($version)) { + s/\@VERSION\@/$version/; + } + if (defined($bindir)) { + s/\@BINDIR@/$bindir/; + } + if (defined($libdir)) { + s/\@LIBDIR@/$libdir/; + } + if (defined($linkdir)) { + s/\@LINKDIR@/$linkdir/; + } + if (defined($datadir)) { + s/\@DATADIR@/$datadir/; + } + if (defined($includedir)) { + s/\@INCLUDEDIR@/$includedir/; + } + if (defined($mandir)) { + s/\@MANDIR@/$mandir/; + } + push(@output, $_); + } + } + $$outputR = \@output; +} + + + +sub +installConfig($$$$$$$) { + my ($pkgdir, + $bindir, $libdir, $linkdir, $datadir, $includedir, $mandir) = @_; + + my $error; + + my $configTemplateFilename = dirname($0) . "/config_template"; + + my $templateOpened = open(TEMPLATE, "<", $configTemplateFilename); + if (!$templateOpened) { + $error = "Can't open template file '$configTemplateFilename'.\n"; + } else { + my @template =